summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>2012-02-17 18:44:44 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 10:59:33 +0200
commit0566cbcb27d06dde205d19029bc6bd3b465e489f (patch)
tree352cf0b57d8ba019a1935b9acce24cd2dfd9f759
parent4c732c546eb3001120f55a9fe8e4b4187de1d062 (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.c16
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);
}
/*