diff options
author | Johan Hovold <johan@kernel.org> | 2022-09-06 15:49:12 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-09-15 12:17:06 +0200 |
commit | a376e66e5d3d4da904390c84c3429f211b56c3eb (patch) | |
tree | 34da68baad2d6189ecbb911e27b6b009594f00b7 | |
parent | 5dac9b60b48ce8a3cd498c5680e8b5f0f4034461 (diff) | |
download | linux-stable-a376e66e5d3d4da904390c84c3429f211b56c3eb.tar.gz linux-stable-a376e66e5d3d4da904390c84c3429f211b56c3eb.tar.bz2 linux-stable-a376e66e5d3d4da904390c84c3429f211b56c3eb.zip |
usb: dwc3: fix PHY disable sequence
From: Johan Hovold <johan+linaro@kernel.org>
commit d2ac7bef95c9ead307801ccb6cb6dfbeb14247bf upstream.
Generic PHYs must be powered-off before they can be tore down.
Similarly, suspending legacy PHYs after having powered them off makes no
sense.
Fix the dwc3_core_exit() (e.g. called during suspend) and open-coded
dwc3_probe() error-path sequences that got this wrong.
Note that this makes dwc3_core_exit() match the dwc3_core_init() error
path with respect to powering off the PHYs.
Fixes: 03c1fd622f72 ("usb: dwc3: core: add phy cleanup for probe error handling")
Fixes: c499ff71ff2a ("usb: dwc3: core: re-factor init and exit paths")
Cc: stable@vger.kernel.org # 4.8
Reviewed-by: Andrew Halaney <ahalaney@redhat.com>
Reviewed-by: Matthias Kaehlcke <mka@chromium.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20220804151001.23612-2-johan+linaro@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ johan: adjust context to 4.19 ]
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/dwc3/core.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 984faecdd7ec..465aabb6e96c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -673,15 +673,16 @@ static void dwc3_core_exit(struct dwc3 *dwc) { dwc3_event_buffers_cleanup(dwc); + usb_phy_set_suspend(dwc->usb2_phy, 1); + usb_phy_set_suspend(dwc->usb3_phy, 1); + phy_power_off(dwc->usb2_generic_phy); + phy_power_off(dwc->usb3_generic_phy); + usb_phy_shutdown(dwc->usb2_phy); usb_phy_shutdown(dwc->usb3_phy); 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); - phy_power_off(dwc->usb2_generic_phy); - phy_power_off(dwc->usb3_generic_phy); clk_bulk_disable(dwc->num_clks, dwc->clks); clk_bulk_unprepare(dwc->num_clks, dwc->clks); reset_control_assert(dwc->reset); @@ -1509,16 +1510,16 @@ err5: dwc3_debugfs_exit(dwc); dwc3_event_buffers_cleanup(dwc); - usb_phy_shutdown(dwc->usb2_phy); - usb_phy_shutdown(dwc->usb3_phy); - 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); phy_power_off(dwc->usb2_generic_phy); phy_power_off(dwc->usb3_generic_phy); + usb_phy_shutdown(dwc->usb2_phy); + usb_phy_shutdown(dwc->usb3_phy); + phy_exit(dwc->usb2_generic_phy); + phy_exit(dwc->usb3_generic_phy); + dwc3_ulpi_exit(dwc); err4: |