From c4b671ec72f5470f82baac4e9600475145778a73 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=99=88=E6=81=92=E6=98=8E?= Date: Thu, 12 Apr 2012 18:16:16 +0800 Subject: [PATCH] rk30: vpu_service: fix dead lock in power on process and irq function --- arch/arm/plat-rk/vpu_service.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-rk/vpu_service.c b/arch/arm/plat-rk/vpu_service.c index d59e8819b05c..4b0c85ad4720 100644 --- a/arch/arm/plat-rk/vpu_service.c +++ b/arch/arm/plat-rk/vpu_service.c @@ -131,6 +131,7 @@ typedef struct vpu_device { typedef struct vpu_service_info { spinlock_t lock; + spinlock_t lock_power; struct timer_list timer; /* timer for power off */ struct list_head waiting; /* link to link_reg in struct vpu_reg */ struct list_head running; /* link to link_reg in struct vpu_reg */ @@ -264,8 +265,11 @@ static void vpu_service_power_off(void) { int total_running; - if (!service.enabled) + spin_lock_bh(&service.lock_power); + if (!service.enabled) { + spin_unlock_bh(&service.lock_power); return; + } service.enabled = false; total_running = atomic_read(&service.total_running); @@ -289,6 +293,7 @@ static void vpu_service_power_off(void) clk_disable(aclk_vepu); clk_disable(clk_vpu); printk("done\n"); + spin_unlock_bh(&service.lock_power); } static void vpu_service_power_off_work_func(unsigned long data) @@ -310,7 +315,7 @@ static void vpu_service_power_on(void) { clk_enable(clk_vpu); /* notify vpu on without lock. */ - spin_lock_bh(&service.lock); + spin_lock_bh(&service.lock_power); if (!service.enabled) { service.enabled = true; printk("vpu: power on\n"); @@ -331,9 +336,9 @@ static void vpu_service_power_on(void) service.timer.expires = jiffies + POWER_OFF_DELAY; service.timer.function = vpu_service_power_off_work_func; add_timer(&service.timer); - spin_unlock_bh(&service.lock); + spin_unlock_bh(&service.lock_power); } else { - spin_unlock_bh(&service.lock); + spin_unlock_bh(&service.lock_power); vpu_service_power_maintain(); } @@ -1137,6 +1142,7 @@ static int __init vpu_service_init(void) INIT_LIST_HEAD(&service.done); INIT_LIST_HEAD(&service.session); spin_lock_init(&service.lock); + spin_lock_init(&service.lock_power); service.reg_codec = NULL; service.reg_pproc = NULL; atomic_set(&service.total_running, 0); -- 2.34.1