From b501278237bf5294a3146a1bf7dce222ea84e80c Mon Sep 17 00:00:00 2001 From: Johann Fischer Date: Wed, 8 May 2024 15:28:55 +0200 Subject: [PATCH] drivers: udc_dwc2: handle interrupt IEPINT before the RXFLVL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During a control read transfer host is able to start status stage as soon as it receives last data packet. The time between last data packet and status stage can be approximately 1 us at High-Speed and 8 us at Full-Speed (exact timing depends on host but it is mostly constrained by bus turnaround time). With sufficient interrupt latency it is therefore possible that both IEPINT (raised at end of Data Stage) and RXFLVL (raised at Status Stage) would be set when dwc2 interrupt handler reads GINTSTS register. When device is operating at High-Speed, the latency introduced by UART logger backend is enough to trigger this condition. If the RXFLVL is handled before IEPINT the stack will trigger "Cannot determine the next stage" error. Handle IEPINT before RXFLVL to make the handler immune to increased interrupt latencies. Co-authored-by: Tomasz Moń Signed-off-by: Johann Fischer --- drivers/usb/udc/udc_dwc2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/udc/udc_dwc2.c b/drivers/usb/udc/udc_dwc2.c index 0c1463e9798..8f5547d36c7 100644 --- a/drivers/usb/udc/udc_dwc2.c +++ b/drivers/usb/udc/udc_dwc2.c @@ -888,16 +888,16 @@ static void udc_dwc2_isr_handler(const struct device *dev) udc_submit_event(dev, UDC_EVT_RESUME, 0); } - if (int_status & USB_DWC2_GINTSTS_RXFLVL) { - /* Handle RxFIFO Non-Empty interrupt */ - dwc2_handle_rxflvl(dev); - } - if (int_status & USB_DWC2_GINTSTS_IEPINT) { /* Handle IN Endpoints interrupt */ dwc2_handle_iepint(dev); } + if (int_status & USB_DWC2_GINTSTS_RXFLVL) { + /* Handle RxFIFO Non-Empty interrupt */ + dwc2_handle_rxflvl(dev); + } + if (int_status & USB_DWC2_GINTSTS_OEPINT) { /* Handle OUT Endpoints interrupt */ dwc2_handle_oepint(dev);