diff options
author | Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | 2012-02-17 18:44:44 +0100 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 10:59:33 +0200 |
commit | 0566cbcb27d06dde205d19029bc6bd3b465e489f (patch) | |
tree | 352cf0b57d8ba019a1935b9acce24cd2dfd9f759 | |
parent | 4c732c546eb3001120f55a9fe8e4b4187de1d062 (diff) |
arm: ux500: pm: unlock mutex before canceling work
usecase_mutex is used by delayed_usecase_work(). Unlock it before calling
cancel_delayed_work_sync(). protect usecase_update_governor_state() with
its own mutex.
ST-Ericsson Linux next: -
ST-Ericsson ID: ER417298
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I373f34eaf87949ca8ccdbcd19e08ea638b76ac39
Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/49418
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/pm/usecase_gov.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/arch/arm/mach-ux500/pm/usecase_gov.c b/arch/arm/mach-ux500/pm/usecase_gov.c index ba4a1e050e9..1fd4fbb9830 100644 --- a/arch/arm/mach-ux500/pm/usecase_gov.c +++ b/arch/arm/mach-ux500/pm/usecase_gov.c @@ -71,6 +71,7 @@ static u32 exit_irq_per_s = 1000; static u64 old_num_irqs; static DEFINE_MUTEX(usecase_mutex); +static DEFINE_MUTEX(state_mutex); static bool user_config_updated; static enum ux500_uc current_uc = UX500_UC_MAX; static bool is_work_scheduled; @@ -411,6 +412,12 @@ void usecase_update_governor_state(void) { bool cancel_work = false; + /* + * usecase_mutex will have to be unlocked to ensure safe exit of + * delayed_usecase_work(). Protect this function with its own mutex + * from being executed by multiple threads at that point. + */ + mutex_lock(&state_mutex); mutex_lock(&usecase_mutex); if (uc_master_enable && (usecase_conf[UX500_UC_AUTO].enable || @@ -434,7 +441,14 @@ void usecase_update_governor_state(void) } if (cancel_work) { + /* + * usecase_mutex is used by delayed_usecase_work() so it must + * be unlocked before we call to cacnel the work. + */ + mutex_unlock(&usecase_mutex); cancel_delayed_work_sync(&work_usecase); + mutex_lock(&usecase_mutex); + is_work_scheduled = false; /* Set the default settings before exiting. */ @@ -442,7 +456,7 @@ void usecase_update_governor_state(void) } mutex_unlock(&usecase_mutex); - + mutex_unlock(&state_mutex); } /* |