summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2020-02-14 11:14:41 +0200
committerVinod Koul <vkoul@kernel.org>2020-02-19 13:09:11 +0530
commit8390318c04bb24cc4d41ac03e009b0748882f99f (patch)
tree7c7bdc823d1099e22613973a917998b9281584b1 /drivers
parentc7450bb211f3ded7cb6e4d305855683ed7d04e60 (diff)
dmaengine: ti: k3-udma: Fix terminated transfer handling
When we receive back the descriptor of the terminated transfer the cookie must be marked as completed to make sure that the accounting is correct. In udma_tx_status() the status should be marked as completed if the channel is no longer running (it can only happen if the channel is not yet started for the first time, or after a channel termination). Fixes: 25dcb5dd7b7ce ("dmaengine: ti: New driver for K3 UDMA") Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Link: https://lore.kernel.org/r/20200214091441.27535-7-peter.ujfalusi@ti.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/ti/k3-udma.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 9b4e1e5fa849..0536866a58ce 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -1097,29 +1097,27 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data)
goto out;
}
- if (uc->cyclic) {
- /* push the descriptor back to the ring */
- if (d == uc->desc) {
+ if (d == uc->desc) {
+ /* active descriptor */
+ if (uc->cyclic) {
udma_cyclic_packet_elapsed(uc);
vchan_cyclic_callback(&d->vd);
- }
- } else {
- bool desc_done = false;
-
- if (d == uc->desc) {
- desc_done = udma_is_desc_really_done(uc, d);
-
- if (desc_done) {
+ } else {
+ if (udma_is_desc_really_done(uc, d)) {
uc->bcnt += d->residue;
udma_start(uc);
+ vchan_cookie_complete(&d->vd);
} else {
schedule_delayed_work(&uc->tx_drain.work,
0);
}
}
-
- if (desc_done)
- vchan_cookie_complete(&d->vd);
+ } else {
+ /*
+ * terminated descriptor, mark the descriptor as
+ * completed to update the channel's cookie marker
+ */
+ dma_cookie_complete(&d->vd.tx);
}
}
out:
@@ -2769,6 +2767,9 @@ static enum dma_status udma_tx_status(struct dma_chan *chan,
ret = dma_cookie_status(chan, cookie, txstate);
+ if (!udma_is_chan_running(uc))
+ ret = DMA_COMPLETE;
+
if (ret == DMA_IN_PROGRESS && udma_is_chan_paused(uc))
ret = DMA_PAUSED;