dmaengine: imx-sdma: find desc first in sdma_tx_status
authorSascha Hauer <s.hauer@pengutronix.de>
Mon, 16 Dec 2019 10:53:27 +0000 (11:53 +0100)
committerVinod Koul <vkoul@kernel.org>
Thu, 26 Dec 2019 04:34:19 +0000 (10:04 +0530)
In sdma_tx_status() we must first find the current sdma_desc. In cyclic
mode we assume that this can always be found with vchan_find_desc().
This is true because do not remove the current descriptor from the
desc_issued list:

/*
 * Do not delete the node in desc_issued list in cyclic mode, otherwise
 * the desc allocated will never be freed in vchan_dma_desc_free_list
 */
if (!(sdmac->flags & IMX_DMA_SG_LOOP))
list_del(&vd->node);

We will change this in the next step, so check if the current descriptor is
the desired one also for the cyclic case.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Link: https://lore.kernel.org/r/20191216105328.15198-9-s.hauer@pengutronix.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/imx-sdma.c

index 527f8a81f50bc9a494a17542ce0ee2d8b41f4fde..99dbfd9039cf78ccad39d3062263fdd8a98073ae 100644 (file)
@@ -1648,7 +1648,7 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
                                      struct dma_tx_state *txstate)
 {
        struct sdma_channel *sdmac = to_sdma_chan(chan);
-       struct sdma_desc *desc;
+       struct sdma_desc *desc = NULL;
        u32 residue;
        struct virt_dma_desc *vd;
        enum dma_status ret;
@@ -1659,19 +1659,23 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
                return ret;
 
        spin_lock_irqsave(&sdmac->vc.lock, flags);
+
        vd = vchan_find_desc(&sdmac->vc, cookie);
-       if (vd) {
+       if (vd)
                desc = to_sdma_desc(&vd->tx);
+       else if (sdmac->desc && sdmac->desc->vd.tx.cookie == cookie)
+               desc = sdmac->desc;
+
+       if (desc) {
                if (sdmac->flags & IMX_DMA_SG_LOOP)
                        residue = (desc->num_bd - desc->buf_ptail) *
                                desc->period_len - desc->chn_real_count;
                else
                        residue = desc->chn_count - desc->chn_real_count;
-       } else if (sdmac->desc && sdmac->desc->vd.tx.cookie == cookie) {
-               residue = sdmac->desc->chn_count - sdmac->desc->chn_real_count;
        } else {
                residue = 0;
        }
+
        spin_unlock_irqrestore(&sdmac->vc.lock, flags);
 
        dma_set_tx_state(txstate, chan->completed_cookie, chan->cookie,