For channels 16 through 31, the channel enable bits occupy bits 32 through 47 of the extended DMAC_CHEN register. dma_chan_terminate_all() only reads the low word and tests BIT(chan->id), so it can conclude that an upper-bank channel has stopped while its actual enable bit remains set. Descriptors can then be freed while hardware still owns them. Poll axi_chan_is_hw_enable(), which already handles both register banks and the smaller channel layouts, instead of constructing another mask. Fixes: 495e18b16e3d ("dmaengine: dw-axi-dmac: Add support DMAX_NUM_CHANNELS > 16") Cc: stable@vger.kernel.org Signed-off-by: James Hilliard --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index 6dae63024721..405ab9a78955 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "dw-axi-dmac.h" @@ -1179,17 +1180,17 @@ static irqreturn_t dw_axi_dma_interrupt(int irq, void *dev_id) static int dma_chan_terminate_all(struct dma_chan *dchan) { struct axi_dma_chan *chan = dchan_to_axi_dma_chan(dchan); - u32 chan_active = BIT(chan->id) << DMAC_CHAN_EN_SHIFT; unsigned long flags; - u32 val; + bool enabled; int ret; LIST_HEAD(head); axi_chan_disable(chan); - ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val, - !(val & chan_active), 1000, 50000); - if (ret == -ETIMEDOUT) + ret = readx_poll_timeout_atomic(axi_chan_is_hw_enable, chan, + enabled, !enabled, + 1 * USEC_PER_MSEC, 50 * USEC_PER_MSEC); + if (ret) dev_warn(dmaengine_chan_dev(dchan), "%s failed to stop\n", axi_chan_name(chan)); -- 2.53.0