summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorLi Jun <jun.li@nxp.com>2021-09-08 10:28:19 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-30 10:12:54 +0200
commit41d5aff380c0551abc741da2c6f2cf0b7b82e94c (patch)
treea5f6cd49ffa62b8654997c87019175f291a99170 /drivers/usb
parentc9f0252e45081b67fea5703cc3a9f3ce1d93dd33 (diff)
usb: dwc3: core: balance phy init and exit
commit 8cfac9a6744fcb143cb3e94ce002f09fd17fadbb upstream. After we start to do core soft reset while usb role switch, the phy init is invoked at every switch to device mode, but its counter part de-init is missing, this causes the actual phy init can not be done when we really want to re-init phy like system resume, because the counter maintained by phy core is not 0. considering phy init is actually redundant for role switch, so move out the phy init from core soft reset to dwc3 core init where is the only place required. Fixes: f88359e1588b ("usb: dwc3: core: Do core softreset when switch mode") Cc: <stable@vger.kernel.org> Tested-by: faqiang.zhu <faqiang.zhu@nxp.com> Tested-by: John Stultz <john.stultz@linaro.org> #HiKey960 Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Li Jun <jun.li@nxp.com> Link: https://lore.kernel.org/r/1631068099-13559-1-git-send-email-jun.li@nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/core.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ba74ad7f6995..2522d15c4244 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -264,19 +264,6 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
{
u32 reg;
int retries = 1000;
- int ret;
-
- usb_phy_init(dwc->usb2_phy);
- usb_phy_init(dwc->usb3_phy);
- ret = phy_init(dwc->usb2_generic_phy);
- if (ret < 0)
- return ret;
-
- ret = phy_init(dwc->usb3_generic_phy);
- if (ret < 0) {
- phy_exit(dwc->usb2_generic_phy);
- return ret;
- }
/*
* We're resetting only the device side because, if we're in host mode,
@@ -310,9 +297,6 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
udelay(1);
} while (--retries);
- phy_exit(dwc->usb3_generic_phy);
- phy_exit(dwc->usb2_generic_phy);
-
return -ETIMEDOUT;
done:
@@ -982,9 +966,21 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->phys_ready = true;
}
+ usb_phy_init(dwc->usb2_phy);
+ usb_phy_init(dwc->usb3_phy);
+ ret = phy_init(dwc->usb2_generic_phy);
+ if (ret < 0)
+ goto err0a;
+
+ ret = phy_init(dwc->usb3_generic_phy);
+ if (ret < 0) {
+ phy_exit(dwc->usb2_generic_phy);
+ goto err0a;
+ }
+
ret = dwc3_core_soft_reset(dwc);
if (ret)
- goto err0a;
+ goto err1;
if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) {