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