From 158769a5f805f326184b432aad7e4753d5f1eee4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 21 May 2015 09:34:09 +0900 Subject: dmaengine: pl330: Fix hang on dmaengine_terminate_all on certain boards commit 81cc6edc08705ac0146fe6ac14a0982a31ce6f3d upstream. The pl330 device could hang infinitely on certain boards when DMA channels are terminated. It was caused by lack of runtime resume when executing pl330_terminate_all() which calls the _stop() function. _stop() accesses device register and can loop infinitely while checking for device state. The hang was confirmed by Dinh Nguyen on Altera SOCFPGA Cyclone V board during boot. It can be also triggered with: $ echo 1 > /sys/module/dmatest/parameters/iterations $ echo dma1chan0 > /sys/module/dmatest/parameters/channel $ echo 1 > /sys/module/dmatest/parameters/run $ sleep 1 $ cat /sys/module/dmatest/parameters/run Reported-by: Dinh Nguyen Signed-off-by: Krzysztof Kozlowski Fixes: ae43b3289186 ("ARM: 8202/1: dmaengine: pl330: Add runtime Power Management support v12") Tested-by: Dinh Nguyen Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/pl330.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0e1f56772855..a2771a8d4377 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2127,6 +2127,7 @@ static int pl330_terminate_all(struct dma_chan *chan) struct pl330_dmac *pl330 = pch->dmac; LIST_HEAD(list); + pm_runtime_get_sync(pl330->ddma.dev); spin_lock_irqsave(&pch->lock, flags); spin_lock(&pl330->lock); _stop(pch->thread); @@ -2151,6 +2152,8 @@ static int pl330_terminate_all(struct dma_chan *chan) list_splice_tail_init(&pch->work_list, &pl330->desc_pool); list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); spin_unlock_irqrestore(&pch->lock, flags); + pm_runtime_mark_last_busy(pl330->ddma.dev); + pm_runtime_put_autosuspend(pl330->ddma.dev); return 0; } -- cgit v1.2.3