author | shihong.zheng <shihong.zheng@amlogic.com> | 2018-01-05 09:30:56 (GMT) |
---|---|---|
committer | Zhi Zhou <zhi.zhou@amlogic.com> | 2018-01-29 06:23:24 (GMT) |
commit | 6fa7657f7faef02a801fd5d611ea684953a41468 (patch) | |
tree | 5fee1953a449fec5616740455409ba394a28646f | |
parent | 3eddbd37868b0dc90ab2c10c9b68365de4a8689b (diff) | |
download | media_modules-6fa7657f7faef02a801fd5d611ea684953a41468.zip media_modules-6fa7657f7faef02a801fd5d611ea684953a41468.tar.gz media_modules-6fa7657f7faef02a801fd5d611ea684953a41468.tar.bz2 |
mpeg12: fix crash in timer when change clk
PD#155701
timer soft-irq cann't mutex_lock,add schedule work
to change source clk.
Change-Id: I199e3e480523ae546b91155113dc269b45e7beea
Signed-off-by: shihong.zheng <shihong.zheng@amlogic.com>
-rw-r--r-- | drivers/frame_provider/decoder/mpeg12/vmpeg12.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12.c index 1390bd3..eecb729 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12.c @@ -186,6 +186,7 @@ static u32 first_i_frame_ready; static struct work_struct userdata_push_work; static struct work_struct notify_work; static struct work_struct reset_work; +static struct work_struct set_clk_work; static bool is_reset; static inline int pool_index(struct vframe_s *vf) @@ -739,6 +740,18 @@ static void reset_do_work(struct work_struct *work) amvdec_start(); } +static void vmpeg12_set_clk(struct work_struct *work) +{ + if (frame_dur > 0 && saved_resolution != + frame_width * frame_height * (96000 / frame_dur)) { + int fps = 96000 / frame_dur; + + saved_resolution = frame_width * frame_height * fps; + vdec_source_changed(VFORMAT_MPEG12, + frame_width, frame_height, fps); + } +} + static void vmpeg_put_timer_func(unsigned long arg) { struct timer_list *timer = (struct timer_list *)arg; @@ -793,14 +806,7 @@ static void vmpeg_put_timer_func(unsigned long arg) } } - if (frame_dur > 0 && saved_resolution != - frame_width * frame_height * (96000 / frame_dur)) { - int fps = 96000 / frame_dur; - - saved_resolution = frame_width * frame_height * fps; - vdec_source_changed(VFORMAT_MPEG12, - frame_width, frame_height, fps); - } + schedule_work(&set_clk_work); timer->expires = jiffies + PUT_INTERVAL; @@ -1185,6 +1191,7 @@ static int amvdec_mpeg12_probe(struct platform_device *pdev) INIT_WORK(&userdata_push_work, userdata_push_do_work); INIT_WORK(¬ify_work, vmpeg12_notify_work); INIT_WORK(&reset_work, reset_do_work); + INIT_WORK(&set_clk_work, vmpeg12_set_clk); amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 probe end.\n"); @@ -1196,6 +1203,7 @@ static int amvdec_mpeg12_remove(struct platform_device *pdev) cancel_work_sync(&userdata_push_work); cancel_work_sync(¬ify_work); cancel_work_sync(&reset_work); + cancel_work_sync(&set_clk_work); if (stat & STAT_VDEC_RUN) { amvdec_stop(); |