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:32:26 -0500
committerDan Williams <dan.j.williams@intel.com>2011-01-04 22:16:10 -0500
commit98838f90d92f6f0abf6d6a99880c0ff3127633b8 (patch)
tree011581a93e3ab32c3feaf2e8d93e9fbd3d23be1e /drivers/dma/amba-pl08x.c
parent9c0bb43bbd02fba0b235f8993d1f175734fa8735 (diff)
ARM: PL08x: fix deadlock in terminate_all
Trying to disable a tasklet while holding a spinlock which the tasklet will take is a recipe for deadlock - tasklet_disable() will wait for the tasklet to finish running, which it will never do. In any case, there is not a corresponding tasklet_enable(), so once the tasklet is disabled, it will never run again until reboot. It's safe to just remove the tasklet_disable() as we remove all current and pending descriptors before releasing this spinlock. This means that the tasklet will find no remaining work if it subsequently runs. The only remaining issue is that the callback for an already submitted txd may be in progress, or even called after terminate_all() returns. There's not much that can be done about that as waiting for the callback to complete before returning will also lead to deadlocks. 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.c2
1 files changed, 0 insertions, 2 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 9a8d44504c6a..4ca1eb122e07 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1560,8 +1560,6 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1560 pl08x_put_phy_channel(pl08x, plchan->phychan); 1560 pl08x_put_phy_channel(pl08x, plchan->phychan);
1561 plchan->phychan = NULL; 1561 plchan->phychan = NULL;
1562 } 1562 }
1563 /* Stop any pending tasklet */
1564 tasklet_disable(&plchan->tasklet);
1565 /* Dequeue jobs and free LLIs */ 1563 /* Dequeue jobs and free LLIs */
1566 if (plchan->at) { 1564 if (plchan->at) {
1567 pl08x_free_txd(pl08x, plchan->at); 1565 pl08x_free_txd(pl08x, plchan->at);