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

Reply via email to