projects
/
firefly-linux-kernel-4.4.55.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
5eb1bc7
)
sound: rk29: pcm: fix bug on rockchip_pcm_enqueue
author
黄涛
<huangtao@rock-chips.com>
Thu, 24 Nov 2011 09:41:28 +0000
(17:41 +0800)
committer
黄涛
<huangtao@rock-chips.com>
Thu, 24 Nov 2011 09:42:23 +0000
(17:42 +0800)
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 : [<
c0713094
>] lr : [<
c071361c
>] 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
[<
c0713094
>] (rockchip_pcm_enqueue+0x2c/0xec) from [<
c071361c
>] (rk29_audio_buffdone+0x58/0x84)
[<
c071361c
>] (rk29_audio_buffdone+0x58/0x84) from [<
c0447a50
>] (rk29_pl330_rq+0x270/0x2d0)
[<
c0447a50
>] (rk29_pl330_rq+0x270/0x2d0) from [<
c04438f4
>] (pl330_update+0x374/0x438)
[<
c04438f4
>] (pl330_update+0x374/0x438) from [<
c0446d3c
>] (pl330_irq_handler+0xc/0x18)
[<
c0446d3c
>] (pl330_irq_handler+0xc/0x18) from [<
c04960e0
>] (handle_irq_event_percpu+0x30/0x174)
[<
c04960e0
>] (handle_irq_event_percpu+0x30/0x174) from [<
c049627c
>] (handle_irq_event+0x58/0x80)
[<
c049627c
>] (handle_irq_event+0x58/0x80) from [<
c0498358
>] (handle_fasteoi_irq+0xb4/0x108)
[<
c0498358
>] (handle_fasteoi_irq+0xb4/0x108) from [<
c0495d70
>] (generic_handle_irq+0x28/0x3c)
[<
c0495d70
>] (generic_handle_irq+0x28/0x3c) from [<
c0433060
>] (asm_do_IRQ+0x60/0x84)
[<
c0433060
>] (asm_do_IRQ+0x60/0x84) from [<
c04384c4
>] (__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
[<
c04384c4
>] (__irq_svc+0x44/0xa0) from [<
c046ef54
>] (__queue_work+0x334/0x370)
[<
c046ef54
>] (__queue_work+0x334/0x370) from [<
c046efdc
>] (queue_work_on+0x2c/0x34)
[<
c046efdc
>] (queue_work_on+0x2c/0x34) from [<
c046f024
>] (queue_work+0x2c/0x54)
[<
c046f024
>] (queue_work+0x2c/0x54) from [<
c047b214
>] (__async_schedule+0x194/0x1b4)
[<
c047b214
>] (__async_schedule+0x194/0x1b4) from [<
c070f118
>] (dapm_power_widgets+0x334/0x3a4)
[<
c070f118
>] (dapm_power_widgets+0x334/0x3a4) from [<
c070f234
>] (snd_soc_dapm_stream_event+0xac/0xbc)
[<
c070f234
>] (snd_soc_dapm_stream_event+0xac/0xbc) from [<
c070b3a0
>] (soc_codec_close+0x164/0x178)
[<
c070b3a0
>] (soc_codec_close+0x164/0x178) from [<
c07025a0
>] (snd_pcm_release_substream+0x54/0xa4)
[<
c07025a0
>] (snd_pcm_release_substream+0x54/0xa4) from [<
c0702618
>] (snd_pcm_release+0x28/0x6c)
[<
c0702618
>] (snd_pcm_release+0x28/0x6c) from [<
c04c8e50
>] (fput+0x104/0x1f8)
[<
c04c8e50
>] (fput+0x104/0x1f8) from [<
c04c5e60
>] (filp_close+0x6c/0x78)
[<
c04c5e60
>] (filp_close+0x6c/0x78) from [<
c04c5f30
>] (sys_close+0xc4/0x124)
[<
c04c5f30
>] (sys_close+0xc4/0x124) from [<
c0438940
>] (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
patch
|
blob
|
history
diff --git
a/sound/soc/rk29/rk29_pcm.c
b/sound/soc/rk29/rk29_pcm.c
index 689a9910f71e5f4009b9203b0cfe998570129864..a2cb3e96a8dc399daa563b92e9b225698054c1df 100755
(executable)
--- 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;