diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2019-09-23 15:28:27 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-09-23 15:28:27 -0700 |
commit | c932d4ad3dbe9752029a282cef77455ccc240d0e (patch) | |
tree | 61d4f14956190a01dae0cbf74b803d18f52b4ca3 /drivers/usb/dwc3/dwc3-msm.c | |
parent | c518693e644df98a85a6d5bd7926ab9f316104f3 (diff) | |
parent | d418b9a1df7e92e22646f72fd2f3b7515b4316ea (diff) |
Merge "usb: dwc3-msm: Try core reset and reinit if PHY PLL lock fails"
Diffstat (limited to 'drivers/usb/dwc3/dwc3-msm.c')
-rw-r--r-- | drivers/usb/dwc3/dwc3-msm.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 4a5f3ec67785..b6b25c75b80c 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -276,6 +276,8 @@ struct dwc3_msm { struct mutex suspend_resume_mutex; enum usb_device_speed override_usb_speed; + + bool core_init_failed; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ @@ -1953,12 +1955,20 @@ static void dwc3_msm_power_collapse_por(struct dwc3_msm *mdwc) ret = dwc3_core_pre_init(dwc); if (ret) { dev_err(mdwc->dev, "dwc3_core_pre_init failed\n"); + mdwc->core_init_failed = true; return; } mdwc->init = true; } - dwc3_core_init(dwc); + ret = dwc3_core_init(dwc); + if (ret) { + dev_err(mdwc->dev, "dwc3_core_init failed\n"); + mdwc->core_init_failed = true; + return; + } + + mdwc->core_init_failed = false; /* Re-configure event buffers */ dwc3_event_buffers_setup(dwc); @@ -3602,6 +3612,12 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) dev_dbg(mdwc->dev, "%s: turn on host\n", __func__); pm_runtime_get_sync(mdwc->dev); + if (mdwc->core_init_failed) { + dev_err(mdwc->dev, "%s: Core init failed\n", __func__); + pm_runtime_put_sync_suspend(mdwc->dev); + return -EAGAIN; + } + mdwc->hs_phy->flags |= PHY_HOST_MODE; if (dwc->maximum_speed == USB_SPEED_SUPER) { mdwc->ss_phy->flags |= PHY_HOST_MODE; @@ -4075,6 +4091,10 @@ static void dwc3_otg_sm_work(struct work_struct *w) delay = VBUS_REG_CHECK_DELAY; work = 1; mdwc->vbus_retry_count++; + } else if (ret == -EAGAIN) { + mdwc->drd_state = DRD_STATE_HOST_IDLE; + dev_dbg(mdwc->dev, "Core init failed. Retrying...\n"); + work = 1; } else if (ret) { dev_err(mdwc->dev, "unable to start host\n"); mdwc->drd_state = DRD_STATE_HOST_IDLE; |