Anand
>From: Anand Gadiyar <[email protected]>
>
>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 <[email protected]>
>Cc: Ajay Kumar Gupta <[email protected]>
>Cc: Felipe Balbi <[email protected]>
>Cc: David Brownell <[email protected]>
>Cc: Sergei Shtylyov <[email protected]>
>---
>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));
csr is a misnomer. It should be called count.
Also I recommend to add a function:
musb_read_hsdma_count() in "musbhsdma.h" just like the write
counterpart and use here.
>+ if (csr == 0)
Should this not be if (csr != 0) only then you mark that dma channel as
generated the interrupt?
>+ 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 [email protected]
>More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html