The controller sets DSTS.DEVCTRLHLT only once every event in the event buffer has been acknowledged. Linux relies on its interrupt handler doing that while dwc3_gadget_run_stop() polls; barebox has no interrupts, and gadget_unbind_driver() unregisters the UDC poller before it disconnects. Any event left pending at that point keeps the controller running, and the poll ends in its 2 s timeout with -ETIMEDOUT.
On an i.MX8MP board with the gadget enumerated by a host, 1 to 15 events (GEVNTCOUNT 4 to 60) were pending on most boots, and each such boot lost 2.0 s between the start of shutdown_barebox() and the jump to Linux; with the events acknowledged, the controller halts within 1 ms. The gadget is being stopped, so acknowledge the events from the poll loop without processing them, keeping lpos in step with the hardware. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Johannes Schneider <[email protected]> --- drivers/usb/dwc3/gadget.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8b26a0c102..46a70231a7 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2322,6 +2322,19 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_DCFG, reg); } +static void dwc3_gadget_discard_events(struct dwc3 *dwc) +{ + struct dwc3_event_buffer *evt = dwc->ev_buf; + u32 count; + + count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)) & DWC3_GEVNTCOUNT_MASK; + if (!count) + return; + + evt->lpos = (evt->lpos + count) % evt->length; + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); +} + static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) { u32 reg; @@ -2356,6 +2369,9 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) do { udelay(1000); + /* the controller only halts once pending events are acked */ + if (!is_on) + dwc3_gadget_discard_events(dwc); reg = dwc3_readl(dwc->regs, DWC3_DSTS); reg &= DWC3_DSTS_DEVCTRLHLT; } while (--timeout && !(!is_on ^ !reg)); base-commit: 75819f9e196e2da048e96c8589898fdc38ef8e7a -- 2.53.0
