diff options
author | Russell King - ARM Linux <linux@arm.linux.org.uk> | 2011-01-03 22:31:04 +0000 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-01-04 19:16:10 -0800 |
commit | 91aa5fadb831e7b6ea473a526a6b49c6dc4819ce (patch) | |
tree | 4f96e2649b8725b6f58bace588e90c9f38c3dc80 /drivers/dma/amba-pl08x.c | |
parent | 4440aacf3a171a0ab498feda58d100a320c5d9ff (diff) | |
download | op-kernel-dev-91aa5fadb831e7b6ea473a526a6b49c6dc4819ce.zip op-kernel-dev-91aa5fadb831e7b6ea473a526a6b49c6dc4819ce.tar.gz |
ARM: PL08x: fix atomic_t usage and tx_submit() return value range
The last_issued variable uses an atomic type, which is only
incremented inside a protected region, and then read. Everywhere else
only reads the value, so it isn't using atomic_t correctly, and it
doesn't even need to. Moreover, the DMA engine code provides us with
a variable for this already - chan.cookie. Use chan.cookie instead.
Also, avoid negative dma_cookie_t values - negative returns from
tx_submit() mean failure, yet in reality we always succeed. Restart
from cookie 1, just like other DMA engine drivers do.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r-- | drivers/dma/amba-pl08x.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 0809810..5d9a156 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -74,7 +74,6 @@ #include <asm/hardware/pl080.h> #include <asm/dma.h> #include <asm/mach/dma.h> -#include <asm/atomic.h> #include <asm/processor.h> #include <asm/cacheflush.h> @@ -1082,8 +1081,10 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx) { struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan); - atomic_inc(&plchan->last_issued); - tx->cookie = atomic_read(&plchan->last_issued); + plchan->chan.cookie += 1; + if (plchan->chan.cookie < 0) + plchan->chan.cookie = 1; + tx->cookie = plchan->chan.cookie; /* This unlock follows the lock in the prep() function */ spin_unlock_irqrestore(&plchan->lock, plchan->lockflags); @@ -1115,7 +1116,7 @@ pl08x_dma_tx_status(struct dma_chan *chan, enum dma_status ret; u32 bytesleft = 0; - last_used = atomic_read(&plchan->last_issued); + last_used = plchan->chan.cookie; last_complete = plchan->lc; ret = dma_async_is_complete(cookie, last_complete, last_used); @@ -1131,7 +1132,7 @@ pl08x_dma_tx_status(struct dma_chan *chan, /* * This cookie not complete yet */ - last_used = atomic_read(&plchan->last_issued); + last_used = plchan->chan.cookie; last_complete = plchan->lc; /* Get number of bytes left in the active transactions and queue */ @@ -1641,8 +1642,7 @@ static void pl08x_tasklet(unsigned long data) /* * Update last completed */ - plchan->lc = - (plchan->at->tx.cookie); + plchan->lc = plchan->at->tx.cookie; /* * Callback to signal completion @@ -1820,8 +1820,8 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, chan->name); chan->chan.device = dmadev; - atomic_set(&chan->last_issued, 0); - chan->lc = atomic_read(&chan->last_issued); + chan->chan.cookie = 0; + chan->lc = 0; spin_lock_init(&chan->lock); INIT_LIST_HEAD(&chan->desc_list); |