aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRussell King - ARM Linux <linux@arm.linux.org.uk>2011-01-03 17:31:04 -0500
committerDan Williams <dan.j.williams@intel.com>2011-01-04 22:16:10 -0500
commit91aa5fadb831e7b6ea473a526a6b49c6dc4819ce (patch)
tree4f96e2649b8725b6f58bace588e90c9f38c3dc80 /drivers
parent4440aacf3a171a0ab498feda58d100a320c5d9ff (diff)
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')
-rw-r--r--drivers/dma/amba-pl08x.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 0809810f9e7a..5d9a15652dba 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -74,7 +74,6 @@
74#include <asm/hardware/pl080.h> 74#include <asm/hardware/pl080.h>
75#include <asm/dma.h> 75#include <asm/dma.h>
76#include <asm/mach/dma.h> 76#include <asm/mach/dma.h>
77#include <asm/atomic.h>
78#include <asm/processor.h> 77#include <asm/processor.h>
79#include <asm/cacheflush.h> 78#include <asm/cacheflush.h>
80 79
@@ -1082,8 +1081,10 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
1082{ 1081{
1083 struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan); 1082 struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan);
1084 1083
1085 atomic_inc(&plchan->last_issued); 1084 plchan->chan.cookie += 1;
1086 tx->cookie = atomic_read(&plchan->last_issued); 1085 if (plchan->chan.cookie < 0)
1086 plchan->chan.cookie = 1;
1087 tx->cookie = plchan->chan.cookie;
1087 /* This unlock follows the lock in the prep() function */ 1088 /* This unlock follows the lock in the prep() function */
1088 spin_unlock_irqrestore(&plchan->lock, plchan->lockflags); 1089 spin_unlock_irqrestore(&plchan->lock, plchan->lockflags);
1089 1090
@@ -1115,7 +1116,7 @@ pl08x_dma_tx_status(struct dma_chan *chan,
1115 enum dma_status ret; 1116 enum dma_status ret;
1116 u32 bytesleft = 0; 1117 u32 bytesleft = 0;
1117 1118
1118 last_used = atomic_read(&plchan->last_issued); 1119 last_used = plchan->chan.cookie;
1119 last_complete = plchan->lc; 1120 last_complete = plchan->lc;
1120 1121
1121 ret = dma_async_is_complete(cookie, last_complete, last_used); 1122 ret = dma_async_is_complete(cookie, last_complete, last_used);
@@ -1131,7 +1132,7 @@ pl08x_dma_tx_status(struct dma_chan *chan,
1131 /* 1132 /*
1132 * This cookie not complete yet 1133 * This cookie not complete yet
1133 */ 1134 */
1134 last_used = atomic_read(&plchan->last_issued); 1135 last_used = plchan->chan.cookie;
1135 last_complete = plchan->lc; 1136 last_complete = plchan->lc;
1136 1137
1137 /* Get number of bytes left in the active transactions and queue */ 1138 /* Get number of bytes left in the active transactions and queue */
@@ -1641,8 +1642,7 @@ static void pl08x_tasklet(unsigned long data)
1641 /* 1642 /*
1642 * Update last completed 1643 * Update last completed
1643 */ 1644 */
1644 plchan->lc = 1645 plchan->lc = plchan->at->tx.cookie;
1645 (plchan->at->tx.cookie);
1646 1646
1647 /* 1647 /*
1648 * Callback to signal completion 1648 * Callback to signal completion
@@ -1820,8 +1820,8 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1820 chan->name); 1820 chan->name);
1821 1821
1822 chan->chan.device = dmadev; 1822 chan->chan.device = dmadev;
1823 atomic_set(&chan->last_issued, 0); 1823 chan->chan.cookie = 0;
1824 chan->lc = atomic_read(&chan->last_issued); 1824 chan->lc = 0;
1825 1825
1826 spin_lock_init(&chan->lock); 1826 spin_lock_init(&chan->lock);
1827 INIT_LIST_HEAD(&chan->desc_list); 1827 INIT_LIST_HEAD(&chan->desc_list);