* [PATCH v2] usb: dwc3: gadget: Fix spurious suspend event during HS link training [not found] <20260903110947.2761354-1-saranya.r@oss.qualcomm.com> @ 2026-09-07 10:12 ` Saranya R 2026-09-11 23:44 ` Thinh Nguyen 0 siblings, 1 reply; 2+ messages in thread From: Saranya R @ 2026-09-07 10:12 UTC (permalink / raw) To: Thinh.Nguyen; +Cc: gregkh, linux-usb, stable, Saranya R During HS link training, a spurious DWC3_DEVICE_EVENT_SUSPEND carrying link state U3 is fired before CONNECT_DONE completes enumeration. At this point gadget->speed is USB_SPEED_UNKNOWN since CONNECT_DONE has not yet run. Calling dwc3_gadget_suspend_interrupt() here triggers an unwanted composite_suspend, causing the charger framework to drop current to 2mA and then ramp back to 500mA on every USB connection. Fix this by skipping suspend event processing when gadget->speed is USB_SPEED_UNKNOWN. This precisely targets the pre-enumeration window without affecting genuine suspend events: a real suspend at ADDRESS state (required for BC1.2 compliance) only arrives after CONNECT_DONE sets gadget->speed to the negotiated speed, so gadget->speed is no longer UNKNOWN at that point. Signed-off-by: Saranya R <saranya.r@oss.qualcomm.com> --- v2: remove Fixes tag and add cc stable This issue observed on 6.12 kernel. --- drivers/usb/dwc3/gadget.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index fa944856f956..a3a59d9d92ef 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -4540,8 +4540,18 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, break; case DWC3_DEVICE_EVENT_SUSPEND: /* It changed to be suspend event for version 2.30a and above */ - if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) - dwc3_gadget_suspend_interrupt(dwc, event->event_info); + if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) { + /* + * A spurious U3 suspend event is fired during HS link + * training before CONNECT_DONE sets the gadget speed. + * Ignore it at that point to avoid triggering an unwanted + * composite_suspend. A genuine suspend at ADDRESS state + * (required for BC1.2 compliance) only arrives after + * CONNECT_DONE, so gadget->speed is no longer UNKNOWN then. + */ + if (dwc->gadget->speed != USB_SPEED_UNKNOWN) + dwc3_gadget_suspend_interrupt(dwc, event->event_info); + } break; case DWC3_DEVICE_EVENT_SOF: case DWC3_DEVICE_EVENT_ERRATIC_ERROR: -- 2.34.1 ^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v2] usb: dwc3: gadget: Fix spurious suspend event during HS link training 2026-09-07 10:12 ` [PATCH v2] usb: dwc3: gadget: Fix spurious suspend event during HS link training Saranya R @ 2026-09-11 23:44 ` Thinh Nguyen 0 siblings, 0 replies; 2+ messages in thread From: Thinh Nguyen @ 2026-09-11 23:44 UTC (permalink / raw) To: Saranya R Cc: Thinh Nguyen, gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, stable@vger.kernel.org On Mon, Sep 07, 2026, Saranya R wrote: > During HS link training, a spurious DWC3_DEVICE_EVENT_SUSPEND carrying > link state U3 is fired before CONNECT_DONE completes enumeration. At > this point gadget->speed is USB_SPEED_UNKNOWN since CONNECT_DONE has > not yet run. Calling dwc3_gadget_suspend_interrupt() here triggers an > unwanted composite_suspend, causing the charger framework to drop > current to 2mA and then ramp back to 500mA on every USB connection. > > Fix this by skipping suspend event processing when gadget->speed is > USB_SPEED_UNKNOWN. This precisely targets the pre-enumeration window > without affecting genuine suspend events: a real suspend at ADDRESS > state (required for BC1.2 compliance) only arrives after CONNECT_DONE > sets gadget->speed to the negotiated speed, so gadget->speed is no > longer UNKNOWN at that point. > > Signed-off-by: Saranya R <saranya.r@oss.qualcomm.com> > --- > > v2: remove Fixes tag and add cc stable > This issue observed on 6.12 kernel. > > --- > drivers/usb/dwc3/gadget.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index fa944856f956..a3a59d9d92ef 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -4540,8 +4540,18 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc, > break; > case DWC3_DEVICE_EVENT_SUSPEND: > /* It changed to be suspend event for version 2.30a and above */ > - if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) > - dwc3_gadget_suspend_interrupt(dwc, event->event_info); > + if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) { > + /* > + * A spurious U3 suspend event is fired during HS link > + * training before CONNECT_DONE sets the gadget speed. > + * Ignore it at that point to avoid triggering an unwanted > + * composite_suspend. A genuine suspend at ADDRESS state > + * (required for BC1.2 compliance) only arrives after > + * CONNECT_DONE, so gadget->speed is no longer UNKNOWN then. > + */ > + if (dwc->gadget->speed != USB_SPEED_UNKNOWN) > + dwc3_gadget_suspend_interrupt(dwc, event->event_info); > + } > break; > case DWC3_DEVICE_EVENT_SOF: > case DWC3_DEVICE_EVENT_ERRATIC_ERROR: > -- > 2.34.1 > Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Thanks, Thinh ^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-11 23:44 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260903110947.2761354-1-saranya.r@oss.qualcomm.com>
2026-09-07 10:12 ` [PATCH v2] usb: dwc3: gadget: Fix spurious suspend event during HS link training Saranya R
2026-09-11 23:44 ` Thinh Nguyen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox