From a2a97a039aec50399f02311d742fc3bf8ab7d449 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 4 Jul 2015 23:55:59 +0300 Subject: [PATCH] usb: musb: do multiple irq processing passes seems to reduce irq scheduling overhead (~5% or so) and improve responsiveness. Not 100% sure if this is safe (doing this in musb_gadget_queue() seems to lock up everything). --- drivers/usb/musb/musb_core.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 650a18bc2650..b7e37a5534fb 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1518,17 +1518,22 @@ static irqreturn_t generic_interrupt(int irq, void *__hci) unsigned long flags; irqreturn_t retval = IRQ_NONE; struct musb *musb = __hci; + int i; spin_lock_irqsave(&musb->lock, flags); - musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); - /* SOF is not enabled, but status is still often set */ - musb->int_usb &= ~MUSB_INTR_SOF; - musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); - musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + for (i = 0; i < 8; i++) { + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); + /* SOF is not enabled, but status is still often set */ + musb->int_usb &= ~MUSB_INTR_SOF; + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); - if (musb->int_usb || musb->int_tx || musb->int_rx) - retval = musb_interrupt(musb); + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval = musb_interrupt(musb); + else + break; + } spin_unlock_irqrestore(&musb->lock, flags); -- 2.47.2