提交 1d0f11b3 编写于 作者: T Tony Lindgren 提交者: Greg Kroah-Hartman

usb: Fix tusb6010 for DMA API

Commit 18eabe23 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: NTony Lindgren <tony@atomide.com>
Acked-by: NFelipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 34e2beb2
...@@ -29,6 +29,19 @@ static void tusb_source_power(struct musb *musb, int is_on); ...@@ -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_MAJOR(reg_val) ((reg_val >> 4) & 0xf)
#define TUSB_REV_MINOR(reg_val) (reg_val & 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 * 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. * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
......
...@@ -39,7 +39,7 @@ struct tusb_omap_dma_ch { ...@@ -39,7 +39,7 @@ struct tusb_omap_dma_ch {
struct tusb_omap_dma *tusb_dma; struct tusb_omap_dma *tusb_dma;
void __iomem *dma_addr; dma_addr_t dma_addr;
u32 len; u32 len;
u16 packet_sz; u16 packet_sz;
...@@ -126,6 +126,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -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_ch *chdat = to_chdat(channel);
struct tusb_omap_dma *tusb_dma = chdat->tusb_dma; struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
struct musb *musb = chdat->musb; struct musb *musb = chdat->musb;
struct device *dev = musb->controller;
struct musb_hw_ep *hw_ep = chdat->hw_ep; struct musb_hw_ep *hw_ep = chdat->hw_ep;
void __iomem *ep_conf = hw_ep->conf; void __iomem *ep_conf = hw_ep->conf;
void __iomem *mbase = musb->mregs; void __iomem *mbase = musb->mregs;
...@@ -173,13 +174,15 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data) ...@@ -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); DBG(3, "Using PIO for remaining %lu bytes\n", pio);
buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len; buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
if (chdat->tx) { if (chdat->tx) {
dma_cache_maint(phys_to_virt((u32)chdat->dma_addr), dma_unmap_single(dev, chdat->dma_addr,
chdat->transfer_len, DMA_TO_DEVICE); chdat->transfer_len,
DMA_TO_DEVICE);
musb_write_fifo(hw_ep, pio, buf); musb_write_fifo(hw_ep, pio, buf);
} else { } else {
dma_unmap_single(dev, chdat->dma_addr,
chdat->transfer_len,
DMA_FROM_DEVICE);
musb_read_fifo(hw_ep, pio, buf); 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; channel->actual_len += pio;
} }
...@@ -224,6 +227,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -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_ch *chdat = to_chdat(channel);
struct tusb_omap_dma *tusb_dma = chdat->tusb_dma; struct tusb_omap_dma *tusb_dma = chdat->tusb_dma;
struct musb *musb = chdat->musb; struct musb *musb = chdat->musb;
struct device *dev = musb->controller;
struct musb_hw_ep *hw_ep = chdat->hw_ep; struct musb_hw_ep *hw_ep = chdat->hw_ep;
void __iomem *mbase = musb->mregs; void __iomem *mbase = musb->mregs;
void __iomem *ep_conf = hw_ep->conf; void __iomem *ep_conf = hw_ep->conf;
...@@ -299,14 +303,16 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz, ...@@ -299,14 +303,16 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
chdat->packet_sz = packet_sz; chdat->packet_sz = packet_sz;
chdat->len = len; chdat->len = len;
channel->actual_len = 0; channel->actual_len = 0;
chdat->dma_addr = (void __iomem *)dma_addr; chdat->dma_addr = dma_addr;
channel->status = MUSB_DMA_STATUS_BUSY; channel->status = MUSB_DMA_STATUS_BUSY;
/* Since we're recycling dma areas, we need to clean or invalidate */ /* Since we're recycling dma areas, we need to clean or invalidate */
if (chdat->tx) 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 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 */ /* Use 16-bit transfer if dma_addr is not 32-bit aligned */
if ((dma_addr & 0x3) == 0) { if ((dma_addr & 0x3) == 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册