--- /dev/null
+From c47e6403fa099f200868d6b106701cb42d181d2b Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:49 +0300
+Subject: dmaengine: at_hdmac: Check return code of dma_async_device_register
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit c47e6403fa099f200868d6b106701cb42d181d2b upstream.
+
+dma_async_device_register() can fail, check the return code and display an
+error.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Cc: stable@vger.kernel.org
+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-16-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -1928,7 +1928,11 @@ static int __init at_dma_probe(struct pl
+ dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "",
+ plat_dat->nr_channels);
+
+- dma_async_device_register(&atdma->dma_common);
++ err = dma_async_device_register(&atdma->dma_common);
++ if (err) {
++ dev_err(&pdev->dev, "Unable to register: %d.\n", err);
++ goto err_dma_async_device_register;
++ }
+
+ /*
+ * Do not return an error if the dmac node is not present in order to
+@@ -1948,6 +1952,7 @@ static int __init at_dma_probe(struct pl
+
+ err_of_dma_controller_register:
+ dma_async_device_unregister(&atdma->dma_common);
++err_dma_async_device_register:
+ dma_pool_destroy(atdma->memset_pool);
+ err_memset_pool_create:
+ dma_pool_destroy(atdma->dma_desc_pool);
--- /dev/null
+From f645f85ae1104f8bd882f962ac0a69a1070076dd Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:39 +0300
+Subject: dmaengine: at_hdmac: Do not call the complete callback on device_terminate_all
+
+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.com
+Link: https://lore.kernel.org/r/20221025090306.297886-6-tudor.ambarus@microchip.com
+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
+@@ -1437,11 +1437,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__);
+
+ /*
+@@ -1460,15 +1457,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);
--- /dev/null
+From 580ee84405c27d6ed419abe4d2b3de1968abdafd Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:47 +0300
+Subject: dmaengine: at_hdmac: Don't allow CPU to reorder channel enable
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 580ee84405c27d6ed419abe4d2b3de1968abdafd upstream.
+
+at_hdmac uses __raw_writel for register writes. In the absence of a
+barrier, the CPU may reorder the register operations.
+Introduce a write memory barrier so that the CPU does not reorder the
+channel enable, thus the start of the transfer, without making sure that
+all the pre-required register fields are already written.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-14-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -256,6 +256,8 @@ static void atc_dostart(struct at_dma_ch
+ ATC_SPIP_BOUNDARY(first->boundary));
+ channel_writel(atchan, DPIP, ATC_DPIP_HOLE(first->dst_hole) |
+ ATC_DPIP_BOUNDARY(first->boundary));
++ /* Don't allow CPU to reorder channel enable. */
++ wmb();
+ dma_writel(atdma, CHER, atchan->mask);
+
+ vdbg_dump_regs(atchan);
--- /dev/null
+From 7176a6a8982d311e50a7c1168868d26e65bbba19 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:36 +0300
+Subject: dmaengine: at_hdmac: Don't start transactions at tx_submit level
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 7176a6a8982d311e50a7c1168868d26e65bbba19 upstream.
+
+tx_submit is supposed to push the current transaction descriptor to a
+pending queue, waiting for issue_pending() to be called. issue_pending()
+must start the transfer, not tx_submit(), thus remove atc_dostart() from
+atc_tx_submit(). Clients of at_xdmac that assume that tx_submit() starts
+the transfer must be updated and call dma_async_issue_pending() if they
+miss to call it.
+The vdbg print was moved to after the lock is released. It is desirable to
+do the prints without the lock held if possible, and because the if
+statement disappears there's no reason why to do the print while holding
+the lock.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-3-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -691,19 +691,11 @@ static dma_cookie_t atc_tx_submit(struct
+ spin_lock_irqsave(&atchan->lock, flags);
+ cookie = dma_cookie_assign(tx);
+
+- if (list_empty(&atchan->active_list)) {
+- dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
+- desc->txd.cookie);
+- atc_dostart(atchan, desc);
+- list_add_tail(&desc->desc_node, &atchan->active_list);
+- } else {
+- dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
+- desc->txd.cookie);
+- list_add_tail(&desc->desc_node, &atchan->queue);
+- }
+-
++ list_add_tail(&desc->desc_node, &atchan->queue);
+ spin_unlock_irqrestore(&atchan->lock, flags);
+
++ dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
++ desc->txd.cookie);
+ return cookie;
+ }
+
--- /dev/null
+From f1171bbdd2ba2a50ee64bb198a78c268a5baf5f1 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:35 +0300
+Subject: dmaengine: at_hdmac: Fix at_lli struct definition
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit f1171bbdd2ba2a50ee64bb198a78c268a5baf5f1 upstream.
+
+Those hardware registers are all of 32 bits, while dma_addr_t ca be of
+type u64 or u32 depending on CONFIG_ARCH_DMA_ADDR_T_64BIT. Force u32 to
+comply with what the hardware expects.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Cc: stable@vger.kernel.org
+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-2-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac_regs.h | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/dma/at_hdmac_regs.h
++++ b/drivers/dma/at_hdmac_regs.h
+@@ -186,13 +186,13 @@
+ /* LLI == Linked List Item; aka DMA buffer descriptor */
+ struct at_lli {
+ /* values that are not changed by hardware */
+- dma_addr_t saddr;
+- dma_addr_t daddr;
++ u32 saddr;
++ u32 daddr;
+ /* value that may get written back: */
+- u32 ctrla;
++ u32 ctrla;
+ /* more values that are not changed by hardware */
+- u32 ctrlb;
+- dma_addr_t dscr; /* chain to next lli */
++ u32 ctrlb;
++ u32 dscr; /* chain to next lli */
+ };
+
+ /**
--- /dev/null
+From ef2cb4f0ce479f77607b04c4b0414bf32f863ee8 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:46 +0300
+Subject: dmaengine: at_hdmac: Fix completion of unissued descriptor in case of errors
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit ef2cb4f0ce479f77607b04c4b0414bf32f863ee8 upstream.
+
+In case the controller detected an error, the code took the chance to move
+all the queued (submitted) descriptors to the active (issued) list. This
+was wrong as if there were any descriptors in the submitted list they were
+moved to the issued list without actually issuing them to the controller,
+thus a completion could be raised without even fireing the descriptor.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-13-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -539,10 +539,6 @@ static void atc_handle_error(struct at_d
+ bad_desc = atc_first_active(atchan);
+ list_del_init(&bad_desc->desc_node);
+
+- /* As we are stopped, take advantage to push queued descriptors
+- * in active_list */
+- list_splice_init(&atchan->queue, atchan->active_list.prev);
+-
+ /* Try to restart the controller */
+ if (!list_empty(&atchan->active_list)) {
+ desc = atc_first_queued(atchan);
--- /dev/null
+From 06988949df8c3007ad82036d3606d8ae72ed9000 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:42 +0300
+Subject: dmaengine: at_hdmac: Fix concurrency over descriptor
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 06988949df8c3007ad82036d3606d8ae72ed9000 upstream.
+
+The descriptor was added to the free_list before calling the callback,
+which could result in reissuing of the same descriptor and calling of a
+single callback for both. Move the decriptor to the free list after the
+callback is invoked.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-9-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -469,11 +469,8 @@ atc_chain_complete(struct at_dma_chan *a
+ desc->memset_buffer = false;
+ }
+
+- /* move children to free_list */
+- list_splice_init(&desc->tx_list, &atchan->free_list);
+- /* move myself to free_list */
+- list_move(&desc->desc_node, &atchan->free_list);
+-
++ /* Remove transfer node from the active list. */
++ list_del_init(&desc->desc_node);
+ spin_unlock_irqrestore(&atchan->lock, flags);
+
+ dma_descriptor_unmap(txd);
+@@ -483,6 +480,13 @@ atc_chain_complete(struct at_dma_chan *a
+ dmaengine_desc_get_callback_invoke(txd, NULL);
+
+ dma_run_dependencies(txd);
++
++ spin_lock_irqsave(&atchan->lock, flags);
++ /* move children to free_list */
++ list_splice_init(&desc->tx_list, &atchan->free_list);
++ /* add myself to free_list */
++ list_add(&desc->desc_node, &atchan->free_list);
++ spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+
+ /**
--- /dev/null
+From 03ed9ba357cc78116164b90b87f45eacab60b561 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:44 +0300
+Subject: dmaengine: at_hdmac: Fix concurrency over the active list
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 03ed9ba357cc78116164b90b87f45eacab60b561 upstream.
+
+The tasklet (atc_advance_work()) did not held the channel lock when
+retrieving the first active descriptor, causing concurrency problems if
+issue_pending() was called in between. If issue_pending() was called
+exactly after the lock was released in the tasklet (atc_advance_work()),
+atc_chain_complete() could complete a descriptor for which the controller
+has not yet raised an interrupt.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-11-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -462,8 +462,6 @@ atc_chain_complete(struct at_dma_chan *a
+ if (!atc_chan_is_cyclic(atchan))
+ dma_cookie_complete(txd);
+
+- /* Remove transfer node from the active list. */
+- list_del_init(&desc->desc_node);
+ spin_unlock_irqrestore(&atchan->lock, flags);
+
+ dma_descriptor_unmap(txd);
+@@ -495,6 +493,7 @@ atc_chain_complete(struct at_dma_chan *a
+ */
+ static void atc_advance_work(struct at_dma_chan *atchan)
+ {
++ struct at_desc *desc;
+ unsigned long flags;
+
+ dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
+@@ -502,9 +501,12 @@ static void atc_advance_work(struct at_d
+ spin_lock_irqsave(&atchan->lock, flags);
+ if (atc_chan_is_enabled(atchan) || list_empty(&atchan->active_list))
+ return spin_unlock_irqrestore(&atchan->lock, flags);
+- spin_unlock_irqrestore(&atchan->lock, flags);
+
+- atc_chain_complete(atchan, atc_first_active(atchan));
++ desc = atc_first_active(atchan);
++ /* Remove the transfer node from the active list. */
++ list_del_init(&desc->desc_node);
++ spin_unlock_irqrestore(&atchan->lock, flags);
++ atc_chain_complete(atchan, desc);
+
+ /* advance work */
+ spin_lock_irqsave(&atchan->lock, flags);
--- /dev/null
+From c6babed879fbe82796a601bf097649e07382db46 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:41 +0300
+Subject: dmaengine: at_hdmac: Fix concurrency problems by removing atc_complete_all()
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit c6babed879fbe82796a601bf097649e07382db46 upstream.
+
+atc_complete_all() had concurrency bugs, thus remove it:
+1/ atc_complete_all() in its entirety was buggy, as when the atchan->queue
+list (the one that contains descriptors that are not yet issued to the
+hardware) contained descriptors, it fired just the first from the
+atchan->queue, but moved all the desc from atchan->queue to
+atchan->active_list and considered them all as fired. This could result in
+calling the completion of a descriptor that was not yet issued to the
+hardware.
+2/ when in tasklet at atc_advance_work() time, atchan->active_list was
+queried without holding the lock of the chan. This can result in
+atchan->active_list concurrency problems between the tasklet and
+issue_pending().
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-8-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 49 ++++---------------------------------------------
+ 1 file changed, 4 insertions(+), 45 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -486,67 +486,26 @@ atc_chain_complete(struct at_dma_chan *a
+ }
+
+ /**
+- * atc_complete_all - finish work for all transactions
+- * @atchan: channel to complete transactions for
+- *
+- * Eventually submit queued descriptors if any
+- *
+- * Assume channel is idle while calling this function
+- * Called with atchan->lock held and bh disabled
+- */
+-static void atc_complete_all(struct at_dma_chan *atchan)
+-{
+- struct at_desc *desc, *_desc;
+- LIST_HEAD(list);
+- unsigned long flags;
+-
+- dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n");
+-
+- spin_lock_irqsave(&atchan->lock, flags);
+-
+- /*
+- * Submit queued descriptors ASAP, i.e. before we go through
+- * the completed ones.
+- */
+- if (!list_empty(&atchan->queue))
+- atc_dostart(atchan, atc_first_queued(atchan));
+- /* empty active_list now it is completed */
+- list_splice_init(&atchan->active_list, &list);
+- /* empty queue list by moving descriptors (if any) to active_list */
+- list_splice_init(&atchan->queue, &atchan->active_list);
+-
+- spin_unlock_irqrestore(&atchan->lock, flags);
+-
+- list_for_each_entry_safe(desc, _desc, &list, desc_node)
+- atc_chain_complete(atchan, desc);
+-}
+-
+-/**
+ * atc_advance_work - at the end of a transaction, move forward
+ * @atchan: channel where the transaction ended
+ */
+ static void atc_advance_work(struct at_dma_chan *atchan)
+ {
+ unsigned long flags;
+- int ret;
+
+ dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
+
+ spin_lock_irqsave(&atchan->lock, flags);
+- ret = atc_chan_is_enabled(atchan);
++ if (atc_chan_is_enabled(atchan) || list_empty(&atchan->active_list))
++ return spin_unlock_irqrestore(&atchan->lock, flags);
+ spin_unlock_irqrestore(&atchan->lock, flags);
+- if (ret)
+- return;
+-
+- if (list_empty(&atchan->active_list) ||
+- list_is_singular(&atchan->active_list))
+- return atc_complete_all(atchan);
+
+ atc_chain_complete(atchan, atc_first_active(atchan));
+
+ /* advance work */
+ spin_lock_irqsave(&atchan->lock, flags);
+- atc_dostart(atchan, atc_first_active(atchan));
++ if (!list_empty(&atchan->active_list))
++ atc_dostart(atchan, atc_first_active(atchan));
+ spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+
--- /dev/null
+From ba2423633ba646e1df20e30cb3cf35495c16f173 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:45 +0300
+Subject: dmaengine: at_hdmac: Fix descriptor handling when issuing it to hardware
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit ba2423633ba646e1df20e30cb3cf35495c16f173 upstream.
+
+As it was before, the descriptor was issued to the hardware without adding
+it to the active (issued) list. This could result in a completion of other
+descriptor, or/and in the descriptor never being completed.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-12-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -510,8 +510,11 @@ static void atc_advance_work(struct at_d
+
+ /* advance work */
+ spin_lock_irqsave(&atchan->lock, flags);
+- if (!list_empty(&atchan->active_list))
+- atc_dostart(atchan, atc_first_active(atchan));
++ if (!list_empty(&atchan->active_list)) {
++ desc = atc_first_queued(atchan);
++ list_move_tail(&desc->desc_node, &atchan->active_list);
++ atc_dostart(atchan, desc);
++ }
+ spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+
+@@ -523,6 +526,7 @@ static void atc_advance_work(struct at_d
+ static void atc_handle_error(struct at_dma_chan *atchan)
+ {
+ struct at_desc *bad_desc;
++ struct at_desc *desc;
+ struct at_desc *child;
+ unsigned long flags;
+
+@@ -540,8 +544,11 @@ static void atc_handle_error(struct at_d
+ list_splice_init(&atchan->queue, atchan->active_list.prev);
+
+ /* Try to restart the controller */
+- if (!list_empty(&atchan->active_list))
+- atc_dostart(atchan, atc_first_active(atchan));
++ if (!list_empty(&atchan->active_list)) {
++ desc = atc_first_queued(atchan);
++ list_move_tail(&desc->desc_node, &atchan->active_list);
++ atc_dostart(atchan, desc);
++ }
+
+ /*
+ * KERN_CRITICAL may seem harsh, but since this only happens
--- /dev/null
+From 28cbe5a0a46a6637adbda52337d7b2777fc04027 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:48 +0300
+Subject: dmaengine: at_hdmac: Fix impossible condition
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 28cbe5a0a46a6637adbda52337d7b2777fc04027 upstream.
+
+The iterator can not be greater than ATC_MAX_DSCR_TRIALS, as the for loop
+will stop when i == ATC_MAX_DSCR_TRIALS. While here, use the common "i"
+name for the iterator.
+
+Fixes: 93dce3a6434f ("dmaengine: at_hdmac: fix residue computation")
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Cc: stable@vger.kernel.org
+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-15-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -318,7 +318,8 @@ static int atc_get_bytes_left(struct dma
+ struct at_desc *desc_first = atc_first_active(atchan);
+ struct at_desc *desc;
+ int ret;
+- u32 ctrla, dscr, trials;
++ u32 ctrla, dscr;
++ unsigned int i;
+
+ /*
+ * If the cookie doesn't match to the currently running transfer then
+@@ -388,7 +389,7 @@ static int atc_get_bytes_left(struct dma
+ dscr = channel_readl(atchan, DSCR);
+ rmb(); /* ensure DSCR is read before CTRLA */
+ ctrla = channel_readl(atchan, CTRLA);
+- for (trials = 0; trials < ATC_MAX_DSCR_TRIALS; ++trials) {
++ for (i = 0; i < ATC_MAX_DSCR_TRIALS; ++i) {
+ u32 new_dscr;
+
+ rmb(); /* ensure DSCR is read after CTRLA */
+@@ -414,7 +415,7 @@ static int atc_get_bytes_left(struct dma
+ rmb(); /* ensure DSCR is read before CTRLA */
+ ctrla = channel_readl(atchan, CTRLA);
+ }
+- if (unlikely(trials >= ATC_MAX_DSCR_TRIALS))
++ if (unlikely(i == ATC_MAX_DSCR_TRIALS))
+ return -ETIMEDOUT;
+
+ /* for the first descriptor we can be more accurate */
--- /dev/null
+From fcd37565efdaffeac179d0f0ce980ac79bfdf569 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:38 +0300
+Subject: dmaengine: at_hdmac: Fix premature completion of desc in issue_pending
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit fcd37565efdaffeac179d0f0ce980ac79bfdf569 upstream.
+
+Multiple calls to atc_issue_pending() could result in a premature
+completion of a descriptor from the atchan->active list, as the method
+always completed the first active descriptor from the list. Instead,
+issue_pending() should just take the first transaction descriptor from the
+pending queue, move it to active_list and start the transfer.
+
+Fixes: dc78baa2b90b ("dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller")
+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-5-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -1527,16 +1527,26 @@ atc_tx_status(struct dma_chan *chan,
+ }
+
+ /**
+- * atc_issue_pending - try to finish work
++ * atc_issue_pending - takes the first transaction descriptor in the pending
++ * queue and starts the transfer.
+ * @chan: target DMA channel
+ */
+ static void atc_issue_pending(struct dma_chan *chan)
+ {
+- struct at_dma_chan *atchan = to_at_dma_chan(chan);
++ struct at_dma_chan *atchan = to_at_dma_chan(chan);
++ struct at_desc *desc;
++ unsigned long flags;
+
+ dev_vdbg(chan2dev(chan), "issue_pending\n");
+
+- atc_advance_work(atchan);
++ spin_lock_irqsave(&atchan->lock, flags);
++ if (atc_chan_is_enabled(atchan) || list_empty(&atchan->queue))
++ return spin_unlock_irqrestore(&atchan->lock, flags);
++
++ desc = atc_first_queued(atchan);
++ list_move_tail(&desc->desc_node, &atchan->active_list);
++ atc_dostart(atchan, desc);
++ spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+
+ /**
--- /dev/null
+From 6ba826cbb57d675f447b59323204d1473bbd5593 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:43 +0300
+Subject: dmaengine: at_hdmac: Free the memset buf without holding the chan lock
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 6ba826cbb57d675f447b59323204d1473bbd5593 upstream.
+
+There's no need to hold the channel lock when freeing the memset buf, as
+the operation has already completed. Free the memset buf without holding
+the channel lock.
+
+Fixes: 4d112426c344 ("dmaengine: hdmac: Add memset capabilities")
+Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Cc: stable@vger.kernel.org
+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-10-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -462,13 +462,6 @@ atc_chain_complete(struct at_dma_chan *a
+ if (!atc_chan_is_cyclic(atchan))
+ dma_cookie_complete(txd);
+
+- /* If the transfer was a memset, free our temporary buffer */
+- if (desc->memset_buffer) {
+- dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
+- desc->memset_paddr);
+- desc->memset_buffer = false;
+- }
+-
+ /* Remove transfer node from the active list. */
+ list_del_init(&desc->desc_node);
+ spin_unlock_irqrestore(&atchan->lock, flags);
+@@ -487,6 +480,13 @@ atc_chain_complete(struct at_dma_chan *a
+ /* add myself to free_list */
+ list_add(&desc->desc_node, &atchan->free_list);
+ spin_unlock_irqrestore(&atchan->lock, flags);
++
++ /* If the transfer was a memset, free our temporary buffer */
++ if (desc->memset_buffer) {
++ dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
++ desc->memset_paddr);
++ desc->memset_buffer = false;
++ }
+ }
+
+ /**
--- /dev/null
+From 6e5ad28d16f082efeae3d0bd2e31f24bed218019 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:40 +0300
+Subject: dmaengine: at_hdmac: Protect atchan->status with the channel lock
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 6e5ad28d16f082efeae3d0bd2e31f24bed218019 upstream.
+
+Now that the complete callback call was removed from
+device_terminate_all(), we can protect the atchan->status with the channel
+lock. The atomic bitops on atchan->status do not substitute proper locking
+on the status, as one could still modify the status after the lock was
+dropped in atc_terminate_all() but before the atomic bitops were executed.
+
+Fixes: 078a6506141a ("dmaengine: at_hdmac: Fix deadlocks")
+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-7-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -1460,12 +1460,12 @@ static int atc_terminate_all(struct dma_
+ 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);
+-
+ clear_bit(ATC_IS_PAUSED, &atchan->status);
+ /* if channel dedicated to cyclic operations, free it */
+ clear_bit(ATC_IS_CYCLIC, &atchan->status);
+
++ spin_unlock_irqrestore(&atchan->lock, flags);
++
+ return 0;
+ }
+
--- /dev/null
+From 8a47221fc28417ff8a32a4f92d4448a56c3cf7e1 Mon Sep 17 00:00:00 2001
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+Date: Tue, 25 Oct 2022 12:02:37 +0300
+Subject: dmaengine: at_hdmac: Start transfer for cyclic channels in issue_pending
+
+From: Tudor Ambarus <tudor.ambarus@microchip.com>
+
+commit 8a47221fc28417ff8a32a4f92d4448a56c3cf7e1 upstream.
+
+Cyclic channels must too call issue_pending in order to start a transfer.
+Start the transfer in issue_pending regardless of the type of channel.
+This wrongly worked before, because in the past the transfer was started
+at tx_submit level when only a desc in the transfer list.
+
+Fixes: 53830cc75974 ("dmaengine: at_hdmac: add cyclic DMA operation support")
+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-4-tudor.ambarus@microchip.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/dma/at_hdmac.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -1536,10 +1536,6 @@ static void atc_issue_pending(struct dma
+
+ dev_vdbg(chan2dev(chan), "issue_pending\n");
+
+- /* Not needed for cyclic transfers */
+- if (atc_chan_is_cyclic(atchan))
+- return;
+-
+ atc_advance_work(atchan);
+ }
+
kvm-svm-retrieve-vmcb-from-assembly.patch
kvm-svm-move-guest-vmsave-vmload-back-to-assembly.patch
can-dev-fix-skb-drop-check.patch
+dmaengine-at_hdmac-fix-at_lli-struct-definition.patch
+dmaengine-at_hdmac-don-t-start-transactions-at-tx_submit-level.patch
+dmaengine-at_hdmac-start-transfer-for-cyclic-channels-in-issue_pending.patch
+dmaengine-at_hdmac-fix-premature-completion-of-desc-in-issue_pending.patch
+dmaengine-at_hdmac-do-not-call-the-complete-callback-on-device_terminate_all.patch
+dmaengine-at_hdmac-protect-atchan-status-with-the-channel-lock.patch
+dmaengine-at_hdmac-fix-concurrency-problems-by-removing-atc_complete_all.patch
+dmaengine-at_hdmac-fix-concurrency-over-descriptor.patch
+dmaengine-at_hdmac-free-the-memset-buf-without-holding-the-chan-lock.patch
+dmaengine-at_hdmac-fix-concurrency-over-the-active-list.patch
+dmaengine-at_hdmac-fix-descriptor-handling-when-issuing-it-to-hardware.patch
+dmaengine-at_hdmac-fix-completion-of-unissued-descriptor-in-case-of-errors.patch
+dmaengine-at_hdmac-don-t-allow-cpu-to-reorder-channel-enable.patch
+dmaengine-at_hdmac-fix-impossible-condition.patch
+dmaengine-at_hdmac-check-return-code-of-dma_async_device_register.patch