From: Peter Ujfalusi Date: Fri, 14 Sep 2012 12:05:45 +0000 (+0300) Subject: dmaengine: omap: Add support for pause/resume in cyclic dma mode X-Git-Tag: firefly_0821_release~3680^2~1589^2~52^2~59 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2dcdf570936168d488acf90be9b04a3d32dafce7;p=firefly-linux-kernel-4.4.55.git dmaengine: omap: Add support for pause/resume in cyclic dma mode 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 Acked-by: Vinod Koul Tested-by: Janusz Krzysztofik Signed-off-by: Mark Brown --- diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index b77a40db2856..71d786973dfd 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,