| From daf079ee3d117735ba9df81464733c50a7c5429a Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 4 Nov 2025 08:25:02 +0800 |
| Subject: usb: dwc2: fix hang during shutdown if set as peripheral |
| |
| From: Jisheng Zhang <jszhang@kernel.org> |
| |
| [ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] |
| |
| dwc2 on most platforms needs phy controller, clock and power supply. |
| All of them must be enabled/activated to properly operate. If dwc2 |
| is configured as peripheral mode, then all the above three hardware |
| resources are disabled at the end of the probe: |
| |
| /* Gadget code manages lowlevel hw on its own */ |
| if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) |
| dwc2_lowlevel_hw_disable(hsotg); |
| |
| But dwc2_driver_shutdown() tries to disable the interrupts on HW IP |
| level. This would result in hang during shutdown if dwc2 is configured |
| as peripheral mode. |
| |
| Fix this hang by only disable and sync irq when lowlevel hw is enabled. |
| |
| Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") |
| Signed-off-by: Jisheng Zhang <jszhang@kernel.org> |
| Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/usb/dwc2/platform.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c |
| index 57ef6dcb489b8..175b4c0886284 100644 |
| --- a/drivers/usb/dwc2/platform.c |
| +++ b/drivers/usb/dwc2/platform.c |
| @@ -341,11 +341,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) |
| { |
| struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); |
| |
| - dwc2_disable_global_interrupts(hsotg); |
| - synchronize_irq(hsotg->irq); |
| - |
| - if (hsotg->ll_hw_enabled) |
| + if (hsotg->ll_hw_enabled) { |
| + dwc2_disable_global_interrupts(hsotg); |
| + synchronize_irq(hsotg->irq); |
| dwc2_lowlevel_hw_disable(hsotg); |
| + } |
| } |
| |
| /** |
| -- |
| 2.51.0 |
| |