RE: [PATCH 2/2] MUSB DMA_INTR register may sometimes read zero when infact there

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Anand

>From: Anand Gadiyar <vikram.pandita@xxxxxx>
>
>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));

	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 majordomo@xxxxxxxxxxxxxxx
>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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux