usb: designware: cleanup irq handler

Change-Id: Ic1926a8277d32721e3c736472dfc41a57ba0d433
This commit is contained in:
mojyack 2026-01-23 10:31:00 +09:00
parent edecad823e
commit 64b1f09e06

View file

@ -1133,61 +1133,10 @@ static void usb_dw_handle_token_mismatch(void)
}
#endif /* USB_DW_SHARED_FIFO */
static void usb_dw_irq(void)
static void usb_dw_iepint(int ep)
{
int ep;
uint32_t daint;
#ifdef USB_DW_ARCH_SLAVE
/* Handle one packet at a time, the IRQ will re-trigger if there's
something left. */
if (DWC_GINTSTS & RXFLVL)
{
usb_dw_handle_rxfifo();
}
#endif
#ifdef USB_DW_SHARED_FIFO
if (DWC_GINTSTS & EPMIS)
{
usb_dw_handle_token_mismatch();
DWC_GINTSTS = EPMIS;
}
#ifdef USB_DW_ARCH_SLAVE
uint32_t gintsts = DWC_GINTSTS & DWC_GINTMSK;
if (gintsts & PTXFE)
{
/* First disable the IRQ, it will be re-enabled later if there
is anything left to be done. */
DWC_GINTMSK &= ~PTXFE;
/* Check all periodic endpoints for anything to be transmitted */
for (ep = 1; ep < USB_NUM_ENDPOINTS; ep++)
if (usb_endpoints & ep_periodic_msk & (1 << ep))
usb_dw_try_push(ep);
}
if (gintsts & NPTXFE)
{
/* First disable the IRQ, it will be re-enabled later if there
is anything left to be done. */
DWC_GINTMSK &= ~NPTXFE;
/* Check all non-periodic endpoints for anything to be transmitted */
for (ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
if (usb_endpoints & ~ep_periodic_msk & (1 << ep))
usb_dw_try_push(ep);
}
#endif /* USB_DW_ARCH_SLAVE */
#endif /* USB_DW_SHARED_FIFO */
daint = DWC_DAINT;
/* IN */
for (ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
{
if (daint & (1 << ep))
{
uint32_t epints = DWC_DIEPINT(ep);
DWC_DIEPINT(ep) = epints;
if (epints & TOC)
{
@ -1213,23 +1162,14 @@ static void usb_dw_irq(void)
}
#endif
/* Clear XFRC here, if this is a 'multi-transfer' request then
a new transfer is going to be launched, this ensures it will
not miss a single interrupt. */
DWC_DIEPINT(ep) = epints;
if (epints & XFRC)
{
usb_dw_handle_xfer_complete(ep, USB_DW_EPDIR_IN);
}
}
}
}
/* OUT */
for (ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
{
if (daint & (1 << (ep + 16)))
{
static void usb_dw_oepint(int ep)
{
uint32_t epints = DWC_DOEPINT(ep);
DWC_DOEPINT(ep) = epints;
@ -1269,10 +1209,77 @@ static void usb_dw_irq(void)
usb_dw_handle_xfer_complete(ep, USB_DW_EPDIR_OUT);
}
}
}
static void usb_dw_irq(void)
{
int ep;
uint32_t gintsts = DWC_GINTSTS & DWC_GINTMSK;
#ifdef USB_DW_ARCH_SLAVE
/* Handle one packet at a time, the IRQ will re-trigger if there's
something left. */
if (gintsts & RXFLVL)
{
usb_dw_handle_rxfifo();
}
#endif
#ifdef USB_DW_SHARED_FIFO
if (gintsts & EPMIS)
{
usb_dw_handle_token_mismatch();
DWC_GINTSTS = EPMIS;
}
#ifdef USB_DW_ARCH_SLAVE
if (gintsts & PTXFE)
{
/* First disable the IRQ, it will be re-enabled later if there
is anything left to be done. */
DWC_GINTMSK &= ~PTXFE;
/* Check all periodic endpoints for anything to be transmitted */
for (ep = 1; ep < USB_NUM_ENDPOINTS; ep++)
if (usb_endpoints & ep_periodic_msk & (1 << ep))
usb_dw_try_push(ep);
}
if (gintsts & NPTXFE)
{
/* First disable the IRQ, it will be re-enabled later if there
is anything left to be done. */
DWC_GINTMSK &= ~NPTXFE;
/* Check all non-periodic endpoints for anything to be transmitted */
for (ep = 0; ep < USB_NUM_ENDPOINTS; ep++)
if (usb_endpoints & ~ep_periodic_msk & (1 << ep))
usb_dw_try_push(ep);
}
#endif /* USB_DW_ARCH_SLAVE */
#endif /* USB_DW_SHARED_FIFO */
if (gintsts & (OEPINT | IEPINT))
{
uint32_t daint = DWC_DAINT & DWC_DAINTMSK;
uint32_t daint_out = daint >> 16;
uint32_t daint_in = daint & 0xffff;
for (ep = 0; ep < USB_NUM_ENDPOINTS && daint_in; ep++, daint_in >>= 1)
{
if (daint_in & 1)
{
usb_dw_iepint(ep);
}
}
if (DWC_GINTSTS & USBRST)
for (ep = 0; ep < USB_NUM_ENDPOINTS && daint_out; ep++, daint_out >>= 1)
{
if (daint_out & 1)
{
usb_dw_oepint(ep);
}
}
}
if (gintsts & USBRST)
{
DWC_GINTSTS = USBRST;
usb_dw_set_address(0);
@ -1280,7 +1287,7 @@ static void usb_dw_irq(void)
usb_core_bus_reset();
}
if (DWC_GINTSTS & ENUMDNE)
if (gintsts & ENUMDNE)
{
DWC_GINTSTS = ENUMDNE;
ep0.state = EP0_SETUP;