summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2015-07-13 19:19:15 +0800
committerNitin Garg <nitin.garg@freescale.com>2015-09-17 09:24:05 -0500
commit9dc8dd91bafe1bb4f62e3ff7124932271b04aea3 (patch)
treee60fe0f93be8e5bdce6381d964dd4c44749ba341 /sound
parent8db5ce2826583b7c65d97cc0cc8d856e6156b3b9 (diff)
MLK-11248: dmaengine: imx-sdma: add new api for sync with dma and substream
There is occasion that dma callback come late after the substream is released. Then there will be kernel dump. [<805866b0>] (imx_pcm_dma_complete) from [<802fad9c>] (sdma_handle_channel_loop.isra.25+0x48/0x54) [<802fad9c>] (sdma_handle_channel_loop.isra.25) from [<802fae48>] (sdma_tasklet+0xa0/0x1d4) [<802fae48>] (sdma_tasklet) from [<800356e0>] (tasklet_action+0x64/0xf8) [<800356e0>] (tasklet_action) from [<80034ea0>] (__do_softirq+0x104/0x218) [<80034ea0>] (__do_softirq) from [<80035220>] (irq_exit+0xa8/0xec) [<80035220>] (irq_exit) from [<8000ed44>] (handle_IRQ+0x3c/0x90) [<8000ed44>] (handle_IRQ) from [<80008578>] (gic_handle_irq+0x28/0x5c) [<80008578>] (gic_handle_irq) from [<80012100>] (__irq_svc+0x40/0x70) The reason is the sdma tasklet is async with audio substream release. ALSA think when terminate dma, the dma should be stopped and no callback be called. This patch is to add new api dma_sync_wait_tasklet(), which is called in snd_dmaengine_pcm_close(). It will make sure the callback not be called after this funtion. Tasklet_kill is to wait scheduled tasklet end. Tasklet_kill can't be added to terminate dma function, because terminate dma function may be called in interrupt, but tasklet_kill can't be called in interrupt context. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_dmaengine.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
index 1b1683253b06..f01528fb892c 100644
--- a/sound/core/pcm_dmaengine.c
+++ b/sound/core/pcm_dmaengine.c
@@ -331,6 +331,8 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+ dma_sync_wait_tasklet(prtd->dma_chan);
+
kfree(prtd);
return 0;