Consider there is interrpt sequences as suspend (U3) -> wakeup (U0) -> suspend (U3), as there is no update to link state in wakeup interrupt, the second suspend interrupt will not report to upper layer.
Fix it by update link state in wakeup interrupt handler.
Cc: stable@vger.kernel.org Signed-off-by: Linyu Yuan quic_linyyuan@quicinc.com --- drivers/usb/dwc3/gadget.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 89dcfac..3533241 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -4066,7 +4066,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) */ }
-static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) +static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc, unsigned int evtinfo) { /* * TODO take core out of low power mode when that's @@ -4078,6 +4078,8 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) dwc->gadget_driver->resume(dwc->gadget); spin_lock(&dwc->lock); } + + dwc->link_state = evtinfo & DWC3_LINK_STATE_MASK; }
static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, @@ -4227,7 +4229,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, dwc3_gadget_conndone_interrupt(dwc); break; case DWC3_DEVICE_EVENT_WAKEUP: - dwc3_gadget_wakeup_interrupt(dwc); + dwc3_gadget_wakeup_interrupt(dwc, event->event_info); break; case DWC3_DEVICE_EVENT_HIBER_REQ: if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation,