diff options
author | Russell King - ARM Linux <linux@arm.linux.org.uk> | 2011-01-03 17:31:04 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-01-04 22:16:10 -0500 |
commit | 91aa5fadb831e7b6ea473a526a6b49c6dc4819ce (patch) | |
tree | 4f96e2649b8725b6f58bace588e90c9f38c3dc80 /drivers | |
parent | 4440aacf3a171a0ab498feda58d100a320c5d9ff (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.c | 18 |
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); |