aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/amba-pl08x.c
diff options
context:
space:
mode:
authorRussell King - ARM Linux <linux@arm.linux.org.uk>2011-01-03 17:31:24 -0500
committerDan Williams <dan.j.williams@intel.com>2011-01-04 22:16:10 -0500
commitbf072af461c166964fb110cfcafccd752fbb4c64 (patch)
treea30b526ad74c2885ae9f8d9f10f412f6d7ff0f59 /drivers/dma/amba-pl08x.c
parent91aa5fadb831e7b6ea473a526a6b49c6dc4819ce (diff)
ARM: PL08x: fix locking in tasklet
Tasklets are run from an interruptible context. The slave DMA functions can be called from within IRQ handlers. Taking the spinlock without disabling interrupts allows an interrupt handler to run, which may try to take the spinlock again, resulting in deadlock. Fix this by using the irqsave spinlocks. 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.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 5d9a15652dba..69cfb05e4d3c 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1627,11 +1627,12 @@ static void pl08x_tasklet(unsigned long data)
1627 struct pl08x_dma_chan *plchan = (struct pl08x_dma_chan *) data; 1627 struct pl08x_dma_chan *plchan = (struct pl08x_dma_chan *) data;
1628 struct pl08x_phy_chan *phychan = plchan->phychan; 1628 struct pl08x_phy_chan *phychan = plchan->phychan;
1629 struct pl08x_driver_data *pl08x = plchan->host; 1629 struct pl08x_driver_data *pl08x = plchan->host;
1630 unsigned long flags;
1630 1631
1631 if (!plchan) 1632 if (!plchan)
1632 BUG(); 1633 BUG();
1633 1634
1634 spin_lock(&plchan->lock); 1635 spin_lock_irqsave(&plchan->lock, flags);
1635 1636
1636 if (plchan->at) { 1637 if (plchan->at) {
1637 dma_async_tx_callback callback = 1638 dma_async_tx_callback callback =
@@ -1728,7 +1729,7 @@ static void pl08x_tasklet(unsigned long data)
1728 } 1729 }
1729 } 1730 }
1730 1731
1731 spin_unlock(&plchan->lock); 1732 spin_unlock_irqrestore(&plchan->lock, flags);
1732} 1733}
1733 1734
1734static irqreturn_t pl08x_irq(int irq, void *dev) 1735static irqreturn_t pl08x_irq(int irq, void *dev)