diff options
Diffstat (limited to 'sound/core/pcm_dmaengine.c')
-rw-r--r-- | sound/core/pcm_dmaengine.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index 494ec0c207fa..b134a51b3fd5 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -349,6 +349,37 @@ int snd_dmaengine_pcm_open_request_chan(struct snd_pcm_substream *substream, } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan); +int snd_dmaengine_pcm_sync_stop(struct snd_pcm_substream *substream) +{ + struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); + struct dma_tx_state state; + enum dma_status status; + + status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state); + if (status != DMA_PAUSED) + dmaengine_synchronize(prtd->dma_chan); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_sync_stop); + +static void __snd_dmaengine_pcm_close(struct snd_pcm_substream *substream, + bool release_channel) +{ + struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); + struct dma_tx_state state; + enum dma_status status; + + status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state); + if (status == DMA_PAUSED) + dmaengine_terminate_async(prtd->dma_chan); + + dmaengine_synchronize(prtd->dma_chan); + if (release_channel) + dma_release_channel(prtd->dma_chan); + kfree(prtd); +} + /** * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream * @substream: PCM substream @@ -357,11 +388,7 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open_request_chan); */ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) { - struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - - dmaengine_synchronize(prtd->dma_chan); - kfree(prtd); - + __snd_dmaengine_pcm_close(substream, false); return 0; } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); @@ -377,12 +404,7 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); */ int snd_dmaengine_pcm_close_release_chan(struct snd_pcm_substream *substream) { - struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - - dmaengine_synchronize(prtd->dma_chan); - dma_release_channel(prtd->dma_chan); - kfree(prtd); - + __snd_dmaengine_pcm_close(substream, true); return 0; } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close_release_chan); @@ -470,4 +492,5 @@ int snd_dmaengine_pcm_refine_runtime_hwparams( } EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_refine_runtime_hwparams); +MODULE_DESCRIPTION("PCM dmaengine helper APIs"); MODULE_LICENSE("GPL"); |