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>
This commit is contained in:
shihong.zheng
2018-01-05 17:30:56 +08:00
committed by Dongjin Kim
parent 5cd9351020
commit 3f36210b0b

View File

@@ -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(&notify_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(&notify_work);
cancel_work_sync(&reset_work);
cancel_work_sync(&set_clk_work);
if (stat & STAT_VDEC_RUN) {
amvdec_stop();