From: Tudor Ambarus tudor.ambarus@microchip.com
commit f645f85ae1104f8bd882f962ac0a69a1070076dd upstream.
The method was wrong because it violated the dmaengine API. For aborted transfers the complete callback should not be called. Fix the behavior and do not call the complete callback on device_terminate_all.
Fixes: 808347f6a317 ("dmaengine: at_hdmac: add DMA slave transfers") Reported-by: Peter Rosin peda@axentia.se Signed-off-by: Tudor Ambarus tudor.ambarus@microchip.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/lkml/13c6c9a2-6db5-c3bf-349b-4c127ad3496a@axentia.se... Acked-by: Nicolas Ferre nicolas.ferre@microchip.com Link: https://lore.kernel.org/r/20221025090306.297886-1-tudor.ambarus@microchip.co... Link: https://lore.kernel.org/r/20221025090306.297886-6-tudor.ambarus@microchip.co... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma/at_hdmac.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
--- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -1429,11 +1429,8 @@ static int atc_terminate_all(struct dma_ struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); int chan_id = atchan->chan_common.chan_id; - struct at_desc *desc, *_desc; unsigned long flags;
- LIST_HEAD(list); - dev_vdbg(chan2dev(chan), "%s\n", __func__);
/* @@ -1452,15 +1449,11 @@ static int atc_terminate_all(struct dma_ cpu_relax();
/* active_list entries will end up before queued entries */ - list_splice_init(&atchan->queue, &list); - list_splice_init(&atchan->active_list, &list); + list_splice_tail_init(&atchan->queue, &atchan->free_list); + list_splice_tail_init(&atchan->active_list, &atchan->free_list);
spin_unlock_irqrestore(&atchan->lock, flags);
- /* Flush all pending and queued descriptors */ - list_for_each_entry_safe(desc, _desc, &list, desc_node) - atc_chain_complete(atchan, desc); - clear_bit(ATC_IS_PAUSED, &atchan->status); /* if channel dedicated to cyclic operations, free it */ clear_bit(ATC_IS_CYCLIC, &atchan->status);