usb: Fix tusb6010 for DMA API
authorTony Lindgren <tony@atomide.com>
Sat, 24 Apr 2010 00:41:15 +0000 (17:41 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 30 Apr 2010 16:25:09 +0000 (09:25 -0700)
Commit 18eabe2347ae7a11b3db768695913724166dfb0e introduced
DMA buffer ownership. Fix tusb6010 accordingly. To compile,
also dummy musb_platform_save and restore functions need to
be added.

Also change the order of musb_read_fifo() to happen after
dma_cache_maint to have the DMA operations completed before
moving the remaining unaligned bytes with PIO. The DMA
access and PIO touch different areas of the FIFO, so this
change only makes the code a bit easier to follow.

Tested on n810 and g_ether with variable size ping test.
The test seems to fail for some ping sizes, but that seems to
be a different problem.

Signed-off-by: Tony Lindgren <tony@atomide.com>
Acked-by: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/musb/tusb6010.c
drivers/usb/musb/tusb6010_omap.c

index ab776a8d98cad99897a7c01f0a02cc78ba1b4dc2..60d3938cafcf3c08f74050923b9aa41ac1c76ebc 100644 (file)
@@ -29,6 +29,19 @@ static void tusb_source_power(struct musb *musb, int is_on);
 #define TUSB_REV_MAJOR(reg_val)                ((reg_val >> 4) & 0xf)
 #define TUSB_REV_MINOR(reg_val)                (reg_val & 0xf)
 
+#ifdef CONFIG_PM
+/* REVISIT: These should be only needed if somebody implements off idle */
+void musb_platform_save_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+}
+
+void musb_platform_restore_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+}
+#endif
+
 /*
  * Checks the revision. We need to use the DMA register as 3.0 does not
  * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
index 5afa070d7dc95aae24fdb0792c3e92e3b05a1b6c..c061a88f2b0f96199656f725382209ade44680f9 100644 (file)
@@ -39,7 +39,7 @@ struct tusb_omap_dma_ch {
 
        struct tusb_omap_dma    *tusb_dma;
 
-       void __iomem            *dma_addr;
+       dma_addr_t              dma_addr;
 
        u32                     len;
        u16                     packet_sz;
@@ -126,6 +126,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
        struct tusb_omap_dma_ch *chdat = to_chdat(channel);
        struct tusb_omap_dma    *tusb_dma = chdat->tusb_dma;
        struct musb             *musb = chdat->musb;
+       struct device           *dev = musb->controller;
        struct musb_hw_ep       *hw_ep = chdat->hw_ep;
        void __iomem            *ep_conf = hw_ep->conf;
        void __iomem            *mbase = musb->mregs;
@@ -173,13 +174,15 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
                DBG(3, "Using PIO for remaining %lu bytes\n", pio);
                buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
                if (chdat->tx) {
-                       dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-                                       chdat->transfer_len, DMA_TO_DEVICE);
+                       dma_unmap_single(dev, chdat->dma_addr,
+                                               chdat->transfer_len,
+                                               DMA_TO_DEVICE);
                        musb_write_fifo(hw_ep, pio, buf);
                } else {
+                       dma_unmap_single(dev, chdat->dma_addr,
+                                               chdat->transfer_len,
+                                               DMA_FROM_DEVICE);
                        musb_read_fifo(hw_ep, pio, buf);
-                       dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-                                       chdat->transfer_len, DMA_FROM_DEVICE);
                }
                channel->actual_len += pio;
        }
@@ -224,6 +227,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        struct tusb_omap_dma_ch         *chdat = to_chdat(channel);
        struct tusb_omap_dma            *tusb_dma = chdat->tusb_dma;
        struct musb                     *musb = chdat->musb;
+       struct device                   *dev = musb->controller;
        struct musb_hw_ep               *hw_ep = chdat->hw_ep;
        void __iomem                    *mbase = musb->mregs;
        void __iomem                    *ep_conf = hw_ep->conf;
@@ -299,14 +303,16 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        chdat->packet_sz = packet_sz;
        chdat->len = len;
        channel->actual_len = 0;
-       chdat->dma_addr = (void __iomem *)dma_addr;
+       chdat->dma_addr = dma_addr;
        channel->status = MUSB_DMA_STATUS_BUSY;
 
        /* Since we're recycling dma areas, we need to clean or invalidate */
        if (chdat->tx)
-               dma_cache_maint(phys_to_virt(dma_addr), len, DMA_TO_DEVICE);
+               dma_map_single(dev, phys_to_virt(dma_addr), len,
+                               DMA_TO_DEVICE);
        else
-               dma_cache_maint(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE);
+               dma_map_single(dev, phys_to_virt(dma_addr), len,
+                               DMA_FROM_DEVICE);
 
        /* Use 16-bit transfer if dma_addr is not 32-bit aligned */
        if ((dma_addr & 0x3) == 0) {