Skip to contentSkip to conversation

Patch "dmaengine: omap-dma: Fix polled channel completion detection and handling" has been added to the 4.5-stable tree

PATCH [email protected] 1 participant 1 message Apr 28, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

dmaengine: omap-dma: Fix polled channel completion detection and handling

to the 4.5-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
dmaengine-omap-dma-fix-polled-channel-completion-detection-and-handling.patch
and it can be found in the queue-4.5 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 689d3c5ecc9e2eac714d32ca152b72988bc2a67b Mon Sep 17 00:00:00 2001

From: Peter Ujfalusi <[email protected]>
Date: Tue, 5 Apr 2016 15:20:20 +0300
Subject: dmaengine: omap-dma: Fix polled channel completion detection and handling

From: Peter Ujfalusi <[email protected]>

commit 689d3c5ecc9e2eac714d32ca152b72988bc2a67b upstream.

When based on the CCR_ENABLE bit the channel is stopped we should not call omap_dma_callback(), only change the return value to DMA_COMPLETE. Client drivers will do the right thing to clean up the channel after the transfer has been completed.
Check the CCR_ENABLE only if the channel is running and not paused since pause in sDMA means that the channel is stopped.
This will fix one hard to reproduce race condition when the channel is terminated during transfer (affecting cyclic operation).

Fixes 1a7cf7b26f25 ("dmaengine: omap-dma: Handle cases when the channel is polled for completion")
---
 drivers/dma/omap-dma.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/dma/omap-dma.c +16 -6
@@ -48,6 +48,7 @@ struct omap_chan {
 	unsigned dma_sig;
 	bool cyclic;
 	bool paused;
+	bool running;
 
 	int dma_ch;
 	struct omap_desc *desc;
@@ -294,6 +295,8 @@ static void omap_dma_start(struct omap_c
 
 	/* Enable channel */
 	omap_dma_chan_write(c, CCR, d->ccr | CCR_ENABLE);
+
+	c->running = true;
 }
 
 static void omap_dma_stop(struct omap_chan *c)
@@ -355,6 +358,8 @@ static void omap_dma_stop(struct omap_ch
 
 		omap_dma_chan_write(c, CLNK_CTRL, val);
 	}
+
+	c->running = false;
 }
 
 static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
@@ -673,15 +678,20 @@ static enum dma_status omap_dma_tx_statu
 	struct omap_chan *c = to_omap_dma_chan(chan);
 	struct virt_dma_desc *vd;
 	enum dma_status ret;
-	uint32_t ccr;
 	unsigned long flags;
 
-	ccr = omap_dma_chan_read(c, CCR);
-	/* The channel is no longer active, handle the completion right away */
-	if (!(ccr & CCR_ENABLE))
-		omap_dma_callback(c->dma_ch, 0, c);
-
 	ret = dma_cookie_status(chan, cookie, txstate);
+
+	if (!c->paused && c->running) {
+		uint32_t ccr = omap_dma_chan_read(c, CCR);
+		/*
+		 * The channel is no longer active, set the return value
+		 * accordingly
+		 */
+		if (!(ccr & CCR_ENABLE))
+			ret = DMA_COMPLETE;
+	}
+
 	if (ret == DMA_COMPLETE || !txstate)
 		return ret;
 

Patches currently in stable-queue which might be from [email protected] are

queue-4.5/arm-dts-am43xx-fix-edma-memcpy-channel-allocation.patch queue-4.5/dmaengine-edma-remove-dynamic-tptc-power-management-feature.patch queue-4.5/dmaengine-omap-dma-fix-polled-channel-completion-detection-and-handling.patch