Commit ebc00869 authored by Akhil R's avatar Akhil R Committed by Vinod Koul
Browse files

dmaengine: tegra: Return correct DMA status when paused



Currently, the driver does not return the correct DMA status when a DMA
pause is issued by the client drivers. This causes GPCDMA users to
assume that DMA is still running, while in reality, the DMA is paused.

Return DMA_PAUSED for tx_status() if the channel is paused in the middle
of a transfer.

Fixes: ee170280 ("dmaengine: tegra: Add tegra gpcdma driver")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarAkhil R <akhilrajeev@nvidia.com>
Signed-off-by: default avatarKartik Rajput <kkartik@nvidia.com>
Link: https://lore.kernel.org/r/20241212124412.5650-1-kkartik@nvidia.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 362f1bf9
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -231,6 +231,7 @@ struct tegra_dma_channel {
	bool config_init;
	char name[30];
	enum dma_transfer_direction sid_dir;
	enum dma_status status;
	int id;
	int irq;
	int slave_id;
@@ -393,6 +394,8 @@ static int tegra_dma_pause(struct tegra_dma_channel *tdc)
		tegra_dma_dump_chan_regs(tdc);
	}

	tdc->status = DMA_PAUSED;

	return ret;
}

@@ -419,6 +422,8 @@ static void tegra_dma_resume(struct tegra_dma_channel *tdc)
	val = tdc_read(tdc, TEGRA_GPCDMA_CHAN_CSRE);
	val &= ~TEGRA_GPCDMA_CHAN_CSRE_PAUSE;
	tdc_write(tdc, TEGRA_GPCDMA_CHAN_CSRE, val);

	tdc->status = DMA_IN_PROGRESS;
}

static int tegra_dma_device_resume(struct dma_chan *dc)
@@ -544,6 +549,7 @@ static void tegra_dma_xfer_complete(struct tegra_dma_channel *tdc)

	tegra_dma_sid_free(tdc);
	tdc->dma_desc = NULL;
	tdc->status = DMA_COMPLETE;
}

static void tegra_dma_chan_decode_error(struct tegra_dma_channel *tdc,
@@ -716,6 +722,7 @@ static int tegra_dma_terminate_all(struct dma_chan *dc)
		tdc->dma_desc = NULL;
	}

	tdc->status = DMA_COMPLETE;
	tegra_dma_sid_free(tdc);
	vchan_get_all_descriptors(&tdc->vc, &head);
	spin_unlock_irqrestore(&tdc->vc.lock, flags);
@@ -769,6 +776,9 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
	if (ret == DMA_COMPLETE)
		return ret;

	if (tdc->status == DMA_PAUSED)
		ret = DMA_PAUSED;

	spin_lock_irqsave(&tdc->vc.lock, flags);
	vd = vchan_find_desc(&tdc->vc, cookie);
	if (vd) {