From c722a34ca9f1272954a4320d98fa1663a62d0caa Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 24 Nov 2011 17:41:28 +0800 Subject: [PATCH] sound: rk29: pcm: fix bug on rockchip_pcm_enqueue Fix this bug: Unable to handle kernel paging request at virtual address 6b6b6b77 pgd = d41ec000 [6b6b6b77] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT CPU: 0 Tainted: P (3.0.8+ #250) PC is at rockchip_pcm_enqueue+0x2c/0xec LR is at rk29_audio_buffdone+0x58/0x84 pc : [] lr : [] psr: 80000193 sp : d0bfdcf8 ip : 00000001 fp : d51f5c44 r10: d0a2e414 r9 : 6b6b6b6b r8 : 6b6b6b6b r7 : 00000001 r6 : d53abc80 r5 : 6b6b6b6b r4 : d0a983c0 r3 : 6b6b6b6b r2 : d6d6d6d6 r1 : 0000001d r0 : d53abc80 [] (rockchip_pcm_enqueue+0x2c/0xec) from [] (rk29_audio_buffdone+0x58/0x84) [] (rk29_audio_buffdone+0x58/0x84) from [] (rk29_pl330_rq+0x270/0x2d0) [] (rk29_pl330_rq+0x270/0x2d0) from [] (pl330_update+0x374/0x438) [] (pl330_update+0x374/0x438) from [] (pl330_irq_handler+0xc/0x18) [] (pl330_irq_handler+0xc/0x18) from [] (handle_irq_event_percpu+0x30/0x174) [] (handle_irq_event_percpu+0x30/0x174) from [] (handle_irq_event+0x58/0x80) [] (handle_irq_event+0x58/0x80) from [] (handle_fasteoi_irq+0xb4/0x108) [] (handle_fasteoi_irq+0xb4/0x108) from [] (generic_handle_irq+0x28/0x3c) [] (generic_handle_irq+0x28/0x3c) from [] (asm_do_IRQ+0x60/0x84) [] (asm_do_IRQ+0x60/0x84) from [] (__irq_svc+0x44/0xa0) Exception stack(0xd0bfde10 to 0xd0bfde58) de00: 00000001 00000108 00000002 00000000 de20: 00000013 d5028640 c0b0d32c d05e8808 d05e8800 d05e8808 c0b0d804 d0bfdeb8 de40: d4bd2400 d0bfde58 c0454ab4 c046ef54 40000013 ffffffff [] (__irq_svc+0x44/0xa0) from [] (__queue_work+0x334/0x370) [] (__queue_work+0x334/0x370) from [] (queue_work_on+0x2c/0x34) [] (queue_work_on+0x2c/0x34) from [] (queue_work+0x2c/0x54) [] (queue_work+0x2c/0x54) from [] (__async_schedule+0x194/0x1b4) [] (__async_schedule+0x194/0x1b4) from [] (dapm_power_widgets+0x334/0x3a4) [] (dapm_power_widgets+0x334/0x3a4) from [] (snd_soc_dapm_stream_event+0xac/0xbc) [] (snd_soc_dapm_stream_event+0xac/0xbc) from [] (soc_codec_close+0x164/0x178) [] (soc_codec_close+0x164/0x178) from [] (snd_pcm_release_substream+0x54/0xa4) [] (snd_pcm_release_substream+0x54/0xa4) from [] (snd_pcm_release+0x28/0x6c) [] (snd_pcm_release+0x28/0x6c) from [] (fput+0x104/0x1f8) [] (fput+0x104/0x1f8) from [] (filp_close+0x6c/0x78) [] (filp_close+0x6c/0x78) from [] (sys_close+0xc4/0x124) [] (sys_close+0xc4/0x124) from [] (ret_fast_syscall+0x0/0x30) rk29_audio_buffdone call rockchip_pcm_enqueue, which access rockchip_runtime_data *prtd, but prtd is freed on rockchip_pcm_close. --- sound/soc/rk29/rk29_pcm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/rk29/rk29_pcm.c b/sound/soc/rk29/rk29_pcm.c index 689a9910f71e..a2cb3e96a8dc 100755 --- a/sound/soc/rk29/rk29_pcm.c +++ b/sound/soc/rk29/rk29_pcm.c @@ -413,10 +413,14 @@ static int rockchip_pcm_close(struct snd_pcm_substream *substream) struct rockchip_dma_buf_set *sg_buf = NULL; DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - if (!prtd) + if (!prtd) { DBG("rockchip_pcm_close called with prtd == NULL\n"); - if (prtd) - sg_buf = prtd->curr; + return 0; + } + + if (prtd->params) + rk29_dma_set_buffdone_fn(prtd->params->channel, NULL); + sg_buf = prtd->curr; while (sg_buf != NULL) { prtd->curr = sg_buf->next; -- 2.34.1