dmaengine: at_hdmac: Do not call the complete callback on device_terminate_all
authorTudor Ambarus <tudor.ambarus@microchip.com>
Tue, 25 Oct 2022 09:02:39 +0000 (12:02 +0300)
committerVinod Koul <vkoul@kernel.org>
Tue, 8 Nov 2022 05:13:56 +0000 (10:43 +0530)
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.com
Link: https://lore.kernel.org/r/20221025090306.297886-6-tudor.ambarus@microchip.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/at_hdmac.c

index cb5522417db65a61740a4298eddc8040be2430b9..11816484843ee2163313e32f503cc42d929ad188 100644 (file)
@@ -1437,11 +1437,8 @@ static int atc_terminate_all(struct dma_chan *chan)
        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__);
 
        /*
@@ -1460,15 +1457,11 @@ static int atc_terminate_all(struct dma_chan *chan)
                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);