diff options
author | Russell King - ARM Linux <linux@arm.linux.org.uk> | 2011-01-03 17:32:05 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-01-04 22:16:10 -0500 |
commit | 9c0bb43bbd02fba0b235f8993d1f175734fa8735 (patch) | |
tree | b5b5673a0e44a0e5263f7c8a9ec800b53b1bfc12 /drivers/dma/amba-pl08x.c | |
parent | dafa73171be8dd31b485f5839e3376b1ca908e24 (diff) |
ARM: PL08x: fix missed spin-unlock in pl08x_issue_pending()
pl08x_issue_pending() returns with the spinlock locked and interrupts
disabled if the channel is waiting for a physical DMA to become free.
This is wrong - especially as pl08x_issue_pending() is an API function
as it leads to deadlocks. Fix it to always return with the spinlock
unlocked.
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 | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index b3b3180ce561..9a8d44504c6a 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c | |||
@@ -1294,15 +1294,11 @@ static void pl08x_issue_pending(struct dma_chan *chan) | |||
1294 | unsigned long flags; | 1294 | unsigned long flags; |
1295 | 1295 | ||
1296 | spin_lock_irqsave(&plchan->lock, flags); | 1296 | spin_lock_irqsave(&plchan->lock, flags); |
1297 | /* Something is already active */ | 1297 | /* Something is already active, or we're waiting for a channel... */ |
1298 | if (plchan->at) { | 1298 | if (plchan->at || plchan->state == PL08X_CHAN_WAITING) { |
1299 | spin_unlock_irqrestore(&plchan->lock, flags); | 1299 | spin_unlock_irqrestore(&plchan->lock, flags); |
1300 | return; | ||
1301 | } | ||
1302 | |||
1303 | /* Didn't get a physical channel so waiting for it ... */ | ||
1304 | if (plchan->state == PL08X_CHAN_WAITING) | ||
1305 | return; | 1300 | return; |
1301 | } | ||
1306 | 1302 | ||
1307 | /* Take the first element in the queue and execute it */ | 1303 | /* Take the first element in the queue and execute it */ |
1308 | if (!list_empty(&plchan->desc_list)) { | 1304 | if (!list_empty(&plchan->desc_list)) { |