[PATCH v2 2/5] usb: dwc2: fix a possible interrupt storm on stm32mp1

From: Fabrice Gasnier

Date: Tue Oct 13 2026 - 12:48:35 EST


On stm32mp1, upon resume from low power (stop) mode, in host mode, a
port interrupt storm may be seen before the hardware is accessible.

The core is able to generate interrupts during system resume in
platform.c when calling dwc2_resume()->__dwc2_lowlevel_hw_enable(). As
the PHY and clocks become available, a resume IRQ can be seen with a
Host Port Interrupt (PrtInt).

The wakeup interrupt handler make the controller to exit power down mode,
but the HCD handler returns IRQ_NONE, due to the HW accessible flag has
been cleared in _dwc2_hcd_suspend() earlier. It ends-up with the bad_irq
handler.

So set the HCD_FLAG_HW_ACCESSIBLE flag when the resume IRQ is handled to
exit from power down mode.

Fixes: ef5e0eec4764 ("usb: dwc2: Add clock gating exiting flow by system resume")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@xxxxxxxxxxx>
---
Changes in v2:
- Add check on hcd before setting HCD_FLAG_HW_ACCESSIBLE flag, to avoid a
NULL pointer dereference on hcd in peripheral-only mode as raised by
Sashiko.
- Add same handling in PPD mode as raised by Sashiko. Only handle clock
gating and partial power down mode (PPD) as pre-existing wakeup handler
manages these two modes. I don't have Hibernation capable hardware to
cross-check this mode.
---
drivers/usb/dwc2/core_intr.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 9565e6a52725..f6d5983d468a 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -453,18 +453,25 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
}
} else {
if (hsotg->lx_state == DWC2_L2) {
+ struct usb_hcd *hcd = hsotg->priv;
+
if (hsotg->in_ppd) {
ret = dwc2_exit_partial_power_down(hsotg, 1,
true);
if (ret)
dev_err(hsotg->dev,
"exit partial_power_down failed\n");
+ if (hcd)
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
}

if (hsotg->params.power_down ==
DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended &&
- !hsotg->params.no_clock_gating)
+ !hsotg->params.no_clock_gating) {
dwc2_host_exit_clock_gating(hsotg, 1);
+ if (hcd)
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ }

/*
* If we've got this quirk then the PHY is stuck upon

--
2.43.0