[PATCH V2 1/1] Fix a dead loop on dw shutdown

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We have a board it seems cannot shutdown on dw_shutdown(). It hard
to re-produce. It re-produce 2 times those days.

There is the log:
[   99.283522] system 00:09: shutdown start
[   99.287942] system 00:09: shutdown stop
[   99.292279] system 00:08: shutdown start
[   99.296700] system 00:08: shutdown stop
[   99.301023] pnp 00:07: shutdown start
[   99.305144] pnp 00:07: shutdown stop
[   99.309192] pnp 00:06: shutdown start
[   99.313323] pnp 00:06: shutdown stop
[   99.317357] pnp 00:05: shutdown start
[   99.321503] pnp 00:05: shutdown stop
[   99.325563] pnp 00:04: shutdown start
[   99.329761] pnp 00:04: shutdown stop
[   99.333815] pnp 00:03: shutdown start
[   99.337947] pnp 00:03: shutdown stop
[   99.342002] serial 00:02: shutdown start
[   99.346422] serial 00:02: shutdown stop
[   99.350742] system 00:01: shutdown start
[   99.355163] system 00:01: shutdown stop
[   99.359504] pnp 00:00: shutdown start
[   99.363632] pnp 00:00: shutdown stop
[   99.367700] intel_sst_acpi 808622A8:00: shutdown start
[   99.384530] intel_sst_acpi 808622A8:00: shutdown stop
[   99.390222] pxa2xx-spi 8086228E:02: shutdown start
[   99.395983] pxa2xx-spi 8086228E:02: shutdown stop
[   99.401376] pxa2xx-spi 8086228E:01: shutdown start
[   99.407197] pxa2xx-spi 8086228E:01: shutdown stop
[   99.412529] pxa2xx-spi 8086228E:00: shutdown start
[   99.418343] pxa2xx-spi 8086228E:00: shutdown stop
[   99.423652] HSU serial 8086228A:01: shutdown start
[   99.429078] HSU serial 8086228A:01: shutdown stop
[   99.434383] HSU serial 8086228A:00: shutdown start
[   99.439796] HSU serial 8086228A:00: shutdown stop
[   99.445110] dw_dmac 808622C0:00: shutdown start

There is potential risk of a dead loop on dmac shutdown, when the dmac
cannot wait the DW_CFG_DMA_EN bit on CFG register in a fault status.

This dead loop will let the shutdown un-finish, and the battery will drain.

Signed-off-by: Figo <tianfei.zhang@xxxxxxxxx>
---
 drivers/dma/dw/core.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index bedce03..9c5f3f5 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -1107,6 +1107,7 @@ static void dwc_issue_pending(struct dma_chan *chan)
 static void dw_dma_off(struct dw_dma *dw)
 {
 	int i;
+	int retry = 100;
 
 	dma_writel(dw, CFG, 0);
 
@@ -1115,8 +1116,11 @@ static void dw_dma_off(struct dw_dma *dw)
 	channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
 	channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
 
-	while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
-		cpu_relax();
+	while ((dma_readl(dw, CFG) & DW_CFG_DMA_EN) && --retry)
+		udelay(100);
+
+	if (retry == 0)
+		dev_err(&dw->dma.dev, "%s error :timeout\n", __func__);
 
 	for (i = 0; i < dw->dma.chancnt; i++)
 		dw->chan[i].initialized = false;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux