When a channel is released (fsl_dma_free_chan_resources) or the driver is unbound (fsl_dma_chan_remove), the descriptor pool and channel resources are freed without stopping the DMA hardware first. An active transfer could continue executing in the background, fetching descriptors or writing data to physical memory pages that have already been freed.
Fix by calling dma_halt() in both paths before cleaning up, matching the pattern already used in fsl_dma_device_terminate_all(). Assisted-by: opencode:big-pickle Signed-off-by: Rosen Penev <[email protected]> --- drivers/dma/fsldma.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 455d21d738de..1ba10d065278 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -748,6 +748,7 @@ static void fsl_dma_free_chan_resources(struct dma_chan *dchan) chan_dbg(chan, "free all channel resources\n"); spin_lock_bh(&chan->desc_lock); + dma_halt(chan); fsldma_cleanup_descriptors(chan); fsldma_free_desc_list(chan, &chan->ld_pending); fsldma_free_desc_list(chan, &chan->ld_running); @@ -1207,6 +1208,10 @@ static int fsl_dma_chan_probe(struct fsldma_device *fdev, static void fsl_dma_chan_remove(struct fsldma_chan *chan) { + spin_lock_bh(&chan->desc_lock); + dma_halt(chan); + spin_unlock_bh(&chan->desc_lock); + tasklet_kill(&chan->tasklet); irq_dispose_mapping(chan->irq); list_del(&chan->common.device_node); -- 2.54.0
