cpufreq: ondemand: Fix locking in store_powersave_bias

store_powersave_bias() assumes that dbs_info->cur_policy will
not change while it is executing. If it does, memory corruption
can potentially result. Fix this by acquiring the dbs_lock.

Most noticeably, this resolves timer-related list corruptions
encountered when queue_delayed_work_on() is called from within
store_powersave_bias() while a CPU is being hotplugged in and
out.

CRs-Fixed: 576272
Change-Id: I0fd5cbef6834545274cad9481e574ec50b37b871
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 2e4b262..69c1d4a 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -111,7 +111,7 @@
 static unsigned int dbs_enable;	/* number of CPUs using this policy */
 
 /*
- * dbs_mutex protects dbs_enable in governor start/stop.
+ * dbs_mutex protects dbs_enable and dbs_info during start/stop.
  */
 static DEFINE_MUTEX(dbs_mutex);
 
@@ -571,7 +571,10 @@
 				POWERSAVE_BIAS_MINLEVEL));
 
 	dbs_tuners_ins.powersave_bias = input;
+
+	mutex_lock(&dbs_mutex);
 	get_online_cpus();
+
 	if (!bypass) {
 		if (reenable_timer) {
 			/* reinstate dbs timer */
@@ -638,7 +641,9 @@
 			unlock_policy_rwsem_write(cpu);
 		}
 	}
+
 	put_online_cpus();
+	mutex_unlock(&dbs_mutex);
 
 	return count;
 }