diff options
author | Ingo Molnar <mingo@kernel.org> | 2016-05-05 09:57:27 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-05-05 09:57:27 +0200 |
commit | e8c8ce54807b19e90ac84e609b13f7d4e337eab1 (patch) | |
tree | ae7d65ae17d55aee197b605ce1a193fe594af614 /drivers/usb/dwc3/core.c | |
parent | lcoking/locktorture: Simplify the torture_runnable computation (diff) | |
parent | Linux 4.6-rc6 (diff) | |
download | linux-e8c8ce54807b19e90ac84e609b13f7d4e337eab1.tar.xz linux-e8c8ce54807b19e90ac84e609b13f7d4e337eab1.zip |
Merge tag 'v4.6-rc6' into locking/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r-- | drivers/usb/dwc3/core.c | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 17fd81447c9f..34277ced26bd 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode) static int dwc3_core_soft_reset(struct dwc3 *dwc) { u32 reg; + int retries = 1000; int ret; - /* Before Resetting PHY, put Core in Reset */ - reg = dwc3_readl(dwc->regs, DWC3_GCTL); - reg |= DWC3_GCTL_CORESOFTRESET; - dwc3_writel(dwc->regs, DWC3_GCTL, reg); - - /* Assert USB3 PHY reset */ - reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); - reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); - - /* Assert USB2 PHY reset */ - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); - reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); - usb_phy_init(dwc->usb2_phy); usb_phy_init(dwc->usb3_phy); ret = phy_init(dwc->usb2_generic_phy); @@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc) phy_exit(dwc->usb2_generic_phy); return ret; } - mdelay(100); - /* Clear USB3 PHY reset */ - reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); - reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); + /* + * We're resetting only the device side because, if we're in host mode, + * XHCI driver will reset the host block. If dwc3 was configured for + * host-only mode, then we can return early. + */ + if (dwc->dr_mode == USB_DR_MODE_HOST) + return 0; - /* Clear USB2 PHY reset */ - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); - reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg |= DWC3_DCTL_CSFTRST; + dwc3_writel(dwc->regs, DWC3_DCTL, reg); - mdelay(100); + do { + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + if (!(reg & DWC3_DCTL_CSFTRST)) + return 0; - /* After PHYs are stable we can take Core out of reset state */ - reg = dwc3_readl(dwc->regs, DWC3_GCTL); - reg &= ~DWC3_GCTL_CORESOFTRESET; - dwc3_writel(dwc->regs, DWC3_GCTL, reg); + udelay(1); + } while (--retries); - return 0; + return -ETIMEDOUT; } /** @@ -1162,6 +1150,11 @@ static int dwc3_suspend(struct device *dev) phy_exit(dwc->usb2_generic_phy); phy_exit(dwc->usb3_generic_phy); + usb_phy_set_suspend(dwc->usb2_phy, 1); + usb_phy_set_suspend(dwc->usb3_phy, 1); + WARN_ON(phy_power_off(dwc->usb2_generic_phy) < 0); + WARN_ON(phy_power_off(dwc->usb3_generic_phy) < 0); + pinctrl_pm_select_sleep_state(dev); return 0; @@ -1175,11 +1168,21 @@ static int dwc3_resume(struct device *dev) pinctrl_pm_select_default_state(dev); + usb_phy_set_suspend(dwc->usb2_phy, 0); + usb_phy_set_suspend(dwc->usb3_phy, 0); + ret = phy_power_on(dwc->usb2_generic_phy); + if (ret < 0) + return ret; + + ret = phy_power_on(dwc->usb3_generic_phy); + if (ret < 0) + goto err_usb2phy_power; + usb_phy_init(dwc->usb3_phy); usb_phy_init(dwc->usb2_phy); ret = phy_init(dwc->usb2_generic_phy); if (ret < 0) - return ret; + goto err_usb3phy_power; ret = phy_init(dwc->usb3_generic_phy); if (ret < 0) @@ -1212,6 +1215,12 @@ static int dwc3_resume(struct device *dev) err_usb2phy_init: phy_exit(dwc->usb2_generic_phy); +err_usb3phy_power: + phy_power_off(dwc->usb3_generic_phy); + +err_usb2phy_power: + phy_power_off(dwc->usb2_generic_phy); + return ret; } |