Commit a1ff6a07 authored by Sascha Hauer's avatar Sascha Hauer Committed by Vinod Koul
Browse files

dmaengine: imx-sdma: find desc first in sdma_tx_status



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: default avatarSascha Hauer <s.hauer@pengutronix.de>
Link: https://lore.kernel.org/r/20191216105328.15198-9-s.hauer@pengutronix.de


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent a80f2787
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -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,