From 8f05d443e4cf00632b27d91fd05bdae563586323 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Thu, 17 Dec 2020 17:40:27 -0800 Subject: [PATCH] usb: dwc3: dwc3-msm: Save dr_mode from DWC3 core node into mdwc To avoid dependencies for the DWC3 core device to be present during dwc3_msm_probe(), read out the dr_mode property from the DT node directly. Since this property can not dynamically change, it will be the same per compile time setting. Change-Id: I3b56bde13af141ea01f06ea5b81e44bc034bf7b1 Signed-off-by: Wesley Cheng --- drivers/usb/dwc3/dwc3-msm.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 83027a1fbfcf..97a6868c4e07 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -288,6 +288,13 @@ static const char *const state_names[] = { [DRD_STATE_HOST] = "host", }; +static const char *const usb_dr_modes[] = { + [USB_DR_MODE_UNKNOWN] = "", + [USB_DR_MODE_HOST] = "host", + [USB_DR_MODE_PERIPHERAL] = "peripheral", + [USB_DR_MODE_OTG] = "otg", +}; + static const char *dwc3_drd_state_string(enum dwc3_drd_state state) { if (state < 0 || state >= ARRAY_SIZE(state_names)) @@ -475,6 +482,7 @@ struct dwc3_msm { unsigned long inputs; unsigned int max_power; enum dwc3_drd_state drd_state; + enum usb_dr_mode dr_mode; enum bus_vote default_bus_vote; enum bus_vote override_bus_vote; struct icc_path *icc_paths[3]; @@ -2287,7 +2295,7 @@ static void dwc3_restart_usb_work(struct work_struct *w) dev_dbg(mdwc->dev, "%s\n", __func__); - if (atomic_read(&dwc->in_lpm) || dwc->dr_mode != USB_DR_MODE_OTG) { + if (atomic_read(&dwc->in_lpm) || mdwc->dr_mode != USB_DR_MODE_OTG) { dev_dbg(mdwc->dev, "%s failed!!!\n", __func__); return; } @@ -3241,7 +3249,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse, } } - if (!mdwc->vbus_active && dwc->dr_mode == USB_DR_MODE_OTG && + if (!mdwc->vbus_active && mdwc->dr_mode == USB_DR_MODE_OTG && mdwc->drd_state == DRD_STATE_PERIPHERAL) { /* * In some cases, the pm_runtime_suspend may be called by @@ -3264,7 +3272,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse, * then check controller state of L2 and break * LPM sequence. Check this for device bus suspend case. */ - if ((dwc->dr_mode == USB_DR_MODE_OTG && + if ((mdwc->dr_mode == USB_DR_MODE_OTG && mdwc->drd_state == DRD_STATE_PERIPHERAL_SUSPEND) && (dwc->gadget.state != USB_STATE_CONFIGURED)) { pr_err("%s(): Trying to go in LPM with state:%d\n", @@ -4133,7 +4141,7 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb, } mdwc->ext_idx = enb->idx; - if (dwc->dr_mode == USB_DR_MODE_OTG && !mdwc->in_restart) + if (mdwc->dr_mode == USB_DR_MODE_OTG && !mdwc->in_restart) queue_work(mdwc->dwc3_wq, &mdwc->resume_work); return NOTIFY_DONE; @@ -4332,10 +4340,9 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); - struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); if (sysfs_streq(buf, "peripheral")) { - if (dwc->dr_mode == USB_DR_MODE_HOST) { + if (mdwc->dr_mode == USB_DR_MODE_HOST) { dev_err(dev, "Core supports host mode only.\n"); return -EINVAL; } @@ -4711,6 +4718,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) struct dwc3_msm *mdwc; struct dwc3 *dwc; struct resource *res; + const char *prop_string; int ret = 0, size = 0, i; u32 val; @@ -4867,6 +4875,11 @@ static int dwc3_msm_probe(struct platform_device *pdev) goto err; } + ret = of_property_read_string(node, "dr_mode", &prop_string); + if (!ret) + ret = match_string(usb_dr_modes, ARRAY_SIZE(usb_dr_modes), prop_string); + mdwc->dr_mode = (ret < 0) ? USB_DR_MODE_UNKNOWN : ret; + ret = of_platform_populate(node, NULL, NULL, &pdev->dev); if (ret) { dev_err(&pdev->dev, @@ -5031,7 +5044,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) mdwc->pm_qos_latency = 0; } - if (mdwc->dual_port && dwc->dr_mode != USB_DR_MODE_HOST) { + if (mdwc->dual_port && mdwc->dr_mode != USB_DR_MODE_HOST) { dev_err(&pdev->dev, "Dual port not allowed for DRD core\n"); goto put_dwc3; } @@ -5096,7 +5109,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) } if (!mdwc->role_switch && !mdwc->extcon) { - switch (dwc->dr_mode) { + switch (mdwc->dr_mode) { case USB_DR_MODE_OTG: if (of_property_read_bool(node, "qcom,default-mode-host")) {