On 12-10-15, 05:27, Figo wrote: > 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; Acked-by: Viresh Kumar <viresh.kumar@xxxxxxxxxx> -- viresh -- 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