cpufreq: interactive: Fix freeing of cached tunabled during module_exit()

To avoid multiple frees of an allocated tunables struct during
module_exit(), the pointer to the allocated tunables should be stored in
only one of the per-CPU cached_tunables pointer.

So, in the case of per policy governor configuration, store the cached
values in the pointer of first CPU in a policy. In the case of one governor
across all policies, store it in the CPU0 pointer.

Change-Id: Id4334246491519ac91ab725a8758b2748f743bb0
Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 7989bd6..d904682 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -1153,19 +1153,27 @@
 {
 	int cpu;
 
-	if (have_governor_per_policy()) {
-		for_each_cpu(cpu, policy->related_cpus) {
-			WARN_ON(per_cpu(cached_tunables, cpu) &&
-				per_cpu(cached_tunables, cpu) != tunables);
-			per_cpu(cached_tunables, cpu) = tunables;
-		}
-	} else {
-		for_each_possible_cpu(cpu) {
-			WARN_ON(per_cpu(cached_tunables, cpu) &&
-				per_cpu(cached_tunables, cpu) != tunables);
-			per_cpu(cached_tunables, cpu) = tunables;
-		}
-	}
+	if (have_governor_per_policy())
+		cpu = cpumask_first(policy->related_cpus);
+	else
+		cpu = 0;
+
+	WARN_ON(per_cpu(cached_tunables, cpu) &&
+		per_cpu(cached_tunables, cpu) != tunables);
+	per_cpu(cached_tunables, cpu) = tunables;
+}
+
+static struct cpufreq_interactive_tunables *restore_tunables(
+						struct cpufreq_policy *policy)
+{
+	int cpu;
+
+	if (have_governor_per_policy())
+		cpu = cpumask_first(policy->related_cpus);
+	else
+		cpu = 0;
+
+	return per_cpu(cached_tunables, cpu);
 }
 
 static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
@@ -1195,7 +1203,7 @@
 			return 0;
 		}
 
-		tunables = per_cpu(cached_tunables, policy->cpu);
+		tunables = restore_tunables(policy);
 		if (!tunables) {
 			tunables = alloc_tunable(policy);
 			if (IS_ERR(tunables))