diff mbox

[v3,02/15] dmaengine: omap: Add support for pause/resume in cyclic dma mode

Message ID 1347624358-25582-3-git-send-email-peter.ujfalusi@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Ujfalusi Sept. 14, 2012, 12:05 p.m. UTC
The audio stack used omap_stop_dma/omap_start_dma to pause/resume the DMA.
This method has been used for years on OMAP based products.
We only allow pause/resume when the DMA has been configured in cyclic mode
which is used by the audio stack.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
CC: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/dma/omap-dma.c | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

Comments

Vinod Koul Sept. 17, 2012, 3:13 a.m. UTC | #1
On Fri, 2012-09-14 at 15:05 +0300, Peter Ujfalusi wrote:
> -       /* FIXME: not supported by platform private API */
> -       return -EINVAL;
> +       /* Pause/Resume only allowed with cyclic mode */
> +       if (!c->cyclic)
> +               return -EINVAL; 
This is not a dma restriction right?
Peter Ujfalusi Sept. 17, 2012, 8:41 a.m. UTC | #2
Hi Vinod,

On 09/17/2012 06:13 AM, Vinod Koul wrote:
> On Fri, 2012-09-14 at 15:05 +0300, Peter Ujfalusi wrote:
>> -       /* FIXME: not supported by platform private API */
>> -       return -EINVAL;
>> +       /* Pause/Resume only allowed with cyclic mode */
>> +       if (!c->cyclic)
>> +               return -EINVAL; 
> This is not a dma restriction right?

The pause/resume operation has been only used by audio. This might work with
non cyclic modes as well but it has never been used/tested so to be safe I
have added this restriction.
Vinod Koul Sept. 17, 2012, 9:55 a.m. UTC | #3
On Fri, 2012-09-14 at 15:05 +0300, Peter Ujfalusi wrote:
> The audio stack used omap_stop_dma/omap_start_dma to pause/resume the
> DMA.
> This method has been used for years on OMAP based products.
> We only allow pause/resume when the DMA has been configured in cyclic
> mode
> which is used by the audio stack.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> CC: Russell King <rmk+kernel@arm.linux.org.uk>
> --- 
Acked-by: Vinod Koul <vinod.koul@linux.intel.com>
Russell King - ARM Linux Sept. 18, 2012, 8:28 a.m. UTC | #4
On Mon, Sep 17, 2012 at 08:43:57AM +0530, Vinod Koul wrote:
> On Fri, 2012-09-14 at 15:05 +0300, Peter Ujfalusi wrote:
> > -       /* FIXME: not supported by platform private API */
> > -       return -EINVAL;
> > +       /* Pause/Resume only allowed with cyclic mode */
> > +       if (!c->cyclic)
> > +               return -EINVAL; 
> This is not a dma restriction right?

This is needed because this is not a real "pause" - it is a stop, which
causes the contents of the DMA engine's FIFOs to be discarded - which
means a subsequent resume will loose data.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index b77a40d..71d7869 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -34,6 +34,7 @@  struct omap_chan {
 	struct dma_slave_config	cfg;
 	unsigned dma_sig;
 	bool cyclic;
+	bool paused;
 
 	int dma_ch;
 	struct omap_desc *desc;
@@ -470,11 +471,14 @@  static int omap_dma_terminate_all(struct omap_chan *c)
 	 */
 	if (c->desc) {
 		c->desc = NULL;
-		omap_stop_dma(c->dma_ch);
+		/* Avoid stopping the dma twice */
+		if (!c->paused)
+			omap_stop_dma(c->dma_ch);
 	}
 
 	if (c->cyclic) {
 		c->cyclic = false;
+		c->paused = false;
 		omap_dma_unlink_lch(c->dma_ch, c->dma_ch);
 	}
 
@@ -487,14 +491,30 @@  static int omap_dma_terminate_all(struct omap_chan *c)
 
 static int omap_dma_pause(struct omap_chan *c)
 {
-	/* FIXME: not supported by platform private API */
-	return -EINVAL;
+	/* Pause/Resume only allowed with cyclic mode */
+	if (!c->cyclic)
+		return -EINVAL;
+
+	if (!c->paused) {
+		omap_stop_dma(c->dma_ch);
+		c->paused = true;
+	}
+
+	return 0;
 }
 
 static int omap_dma_resume(struct omap_chan *c)
 {
-	/* FIXME: not supported by platform private API */
-	return -EINVAL;
+	/* Pause/Resume only allowed with cyclic mode */
+	if (!c->cyclic)
+		return -EINVAL;
+
+	if (c->paused) {
+		omap_start_dma(c->dma_ch);
+		c->paused = false;
+	}
+
+	return 0;
 }
 
 static int omap_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,