forked from luck/tmp_suning_uos_patched
usb: musb: workaround MUSB DMA_INTR sometimes reads zero
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. Additionally, the absence of a debug print meant we would never catch a spurious DMA interrupt in MUSB. So this patch adds a debug print in the IRQ handler. Signed-off-by: Anand Gadiyar <gadiyar@ti.com> Cc: Ajay Kumar Gupta <ajay.gupta@ti.com> Cc: David Brownell <dbrownell@users.sourceforge.net> Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com> Cc: Vikram Pandita <vikram.pandita@ti.com> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
452f039437
commit
f933a0c0fe
@ -250,20 +250,39 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
|
||||
u8 bchannel;
|
||||
u8 int_hsdma;
|
||||
|
||||
u32 addr;
|
||||
u32 addr, count;
|
||||
u16 csr;
|
||||
|
||||
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) {
|
||||
count = musb_read_hsdma_count(mbase, bchannel);
|
||||
|
||||
if (count == 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 *)
|
||||
|
Loading…
Reference in New Issue
Block a user