]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
musb_hdrc: DMA RX workaround for tusb6010
authorTony Lindgren <tony@atomide.com>
Mon, 30 Apr 2007 19:04:26 +0000 (19:04 +0000)
committerTony Lindgren <tony@atomide.com>
Fri, 4 May 2007 17:06:25 +0000 (10:06 -0700)
Async RX DMA on tusb6010 will eventually corrupt the XFR_SIZE
register. This patch blocks DMA transfers for async RX DMA.

Signed-off-by: Tony Lindgren <tony@atomide.com>
drivers/usb/musb/tusb6010_omap.c

index 1d9d80f374c81ef33d456873dbadff7f44ed908e..1ca6a3a1fa281ff1c108199a316788f7250daa40 100644 (file)
@@ -169,6 +169,13 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
                remaining = musb_readl(ep_conf, TUSB_EP_RX_OFFSET);
 
        remaining = TUSB_EP_CONFIG_XFR_SIZE(remaining);
+
+       /* HW issue #10: XFR_SIZE may get corrupt on async DMA */
+       if (unlikely(remaining > chdat->transfer_len)) {
+               WARN("Corrupt XFR_SIZE with async DMA: %lu\n", remaining);
+               remaining = 0;
+       }
+
        channel->dwActualLength = chdat->transfer_len - remaining;
        pio = chdat->len - channel->dwActualLength;
 
@@ -246,6 +253,15 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
                return FALSE;
 
+       /*
+        * HW issue #10: Async dma will eventually corrupt the XFR_SIZE
+        * register which will cause missed DMA interrupt. We could try to
+        * use a timer for the callback, but it is unsafe as the XFR_SIZE
+        * register is corrupt, and we won't know if the DMA worked.
+        */
+       if (dma_addr & 0x2)
+               return FALSE;
+
        chdat->transfer_len = len & ~0x1f;
 
        if (len < packet_sz)