Skip to content

Commit

Permalink
usb: Fix tusb6010 for DMA API
Browse files Browse the repository at this point in the history
Commit 18eabe2 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>
  • Loading branch information
Tony Lindgren authored and Greg Kroah-Hartman committed Apr 30, 2010
1 parent 34e2beb commit 1d0f11b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
13 changes: 13 additions & 0 deletions drivers/usb/musb/tusb6010.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
22 changes: 14 additions & 8 deletions drivers/usb/musb/tusb6010_omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 1d0f11b

Please sign in to comment.