dmaengine: dw-axi-dmac: Handle xfer start while non-idle
authorSamin Guo <samin.guo@starfivetech.com>
Wed, 17 Nov 2021 06:50:45 +0000 (14:50 +0800)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Thu, 9 Feb 2023 19:07:44 +0000 (20:07 +0100)
Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
drivers/dma/dw-axi-dmac/dw-axi-dmac.h

index bf85aa0..17d4de3 100644 (file)
@@ -377,11 +377,13 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
        u32 irq_mask;
        u8 lms = 0; /* Select AXI0 master for LLI fetching */
 
+       chan->is_err = false;
        if (unlikely(axi_chan_is_hw_enable(chan))) {
                dev_err(chan2dev(chan), "%s is non-idle!\n",
                        axi_chan_name(chan));
 
-               return;
+               axi_chan_disable(chan);
+               chan->is_err = true;
        }
 
        axi_dma_enable(chan->chip);
@@ -1023,6 +1025,15 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
                        axi_chan_name(chan));
                goto out;
        }
+
+       if (chan->is_err) {
+               struct axi_dma_desc *desc = vd_to_axi_desc(vd);
+
+               axi_chan_block_xfer_start(chan, desc);
+               chan->is_err = false;
+               goto out;
+       }
+
        /* Remove the completed descriptor from issued list */
        list_del(&vd->node);
 
index e9d5eb0..4019a9a 100644 (file)
@@ -49,6 +49,7 @@ struct axi_dma_chan {
        struct dma_slave_config         config;
        enum dma_transfer_direction     direction;
        bool                            cyclic;
+       bool                            is_err;
        /* these other elements are all protected by vc.lock */
        bool                            is_paused;
 };