MUSB DMA_INTR register may sometimes read zero when infact there was a pending interrupt. Workaround this by reading the DMA_COUNT values for all enabled channels when this condition occurs. Flag these channels as the ones needing to be serviced. Signed-off-by: Anand Gadiyar <gadiyar@xxxxxx> Cc: Ajay Kumar Gupta <ajay.gupta@xxxxxx> Cc: Felipe Balbi <felipe.balbi@xxxxxxxxx> Cc: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx> Cc: Sergei Shtylyov <sshtylyov@xxxxxxxxxxxxx> --- This issue exists on versions of the controller newer than 1.8. The first version of this patch checked for this version before acting. However to keep the code clean, I felt that it is acceptable to do this unconditionally on all versions. Also, the absence of the debug print meant that we would never catch a spurious DMA interrupt on the older versions, so adding the prints helps there. drivers/usb/musb/musbhsdma.c | 24 ++++++++++++++++++++++-- 1 files changed, 22 insertions(+), 2 deletions(-) Index: linux-omap-2.6/drivers/usb/musb/musbhsdma.c =================================================================== --- linux-omap-2.6.orig/drivers/usb/musb/musbhsdma.c +++ linux-omap-2.6/drivers/usb/musb/musbhsdma.c @@ -256,14 +256,34 @@ static irqreturn_t dma_controller_irq(in spin_lock_irqsave(&musb->lock, flags); int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR); - if (!int_hsdma) - goto done; #ifdef CONFIG_BLACKFIN /* Clear DMA interrupt flags */ musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma); #endif + if (!int_hsdma) { + DBG(2, "spurious DMA irq\n"); + + for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { + musb_channel = (struct musb_dma_channel *) + &(controller->channel[bchannel]); + channel = &musb_channel->channel; + if (channel->status == MUSB_DMA_STATUS_BUSY) { + csr = musb_readw(mbase, + MUSB_HSDMA_CHANNEL_OFFSET(bchannel, + MUSB_HSDMA_COUNT)); + if (csr == 0) + int_hsdma |= (1 << bchannel); + } + } + + DBG(2, "int_hsdma = 0x%x\n", int_hsdma); + + if (!int_hsdma) + goto done; + } + for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { if (int_hsdma & (1 << bchannel)) { musb_channel = (struct musb_dma_channel *) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html