diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch new file mode 100644 index 00000000..0cb4c91f --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch @@ -0,0 +1,100 @@ +From 42a384af80e07534913d9002ec8d9caf5d4d305c Mon Sep 17 00:00:00 2001 +From: Nishanth Menon <nm@ti.com> +Date: Wed, 18 May 2011 01:48:23 -0500 +Subject: [PATCH 6/6] OMAP2+: cpufreq: fix freq_table leak + +Since we have two cpus the cpuinit call for cpu1 causes +freq_table of cpu0 to be overwritten. instead, we maintain +a counter to keep track of cpus who use the cpufreq table +allocate it once(one freq table for all CPUs) and free them +once the last user is done with it. + +Signed-off-by: Nishanth Menon <nm@ti.com> +Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> +--- + arch/arm/mach-omap2/omap2plus-cpufreq.c | 33 ++++++++++++++++++++++++------ + 1 files changed, 26 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c +index d0b4f97..fc3d0fb 100644 +--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c ++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c +@@ -42,6 +42,9 @@ + #define VERY_HI_RATE 900000000 + + static struct cpufreq_frequency_table *freq_table; ++static int freq_table_users; ++static DEFINE_MUTEX(freq_table_lock); ++ + static struct clk *mpu_clk; + + static int omap_verify_speed(struct cpufreq_policy *policy) +@@ -172,6 +175,18 @@ skip_lpj: + return ret; + } + ++static void freq_table_free(void) ++{ ++ if (!freq_table_users) ++ return; ++ freq_table_users--; ++ if (freq_table_users) ++ return; ++ clk_exit_cpufreq_table(&freq_table); ++ kfree(freq_table); ++ freq_table = NULL; ++} ++ + static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) + { + int result = 0; +@@ -199,14 +214,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) + return -EINVAL; + } + ++ mutex_lock(&freq_table_lock); + /* + * if we dont get cpufreq table using opp, use traditional omap2 lookup + * as a fallback + */ +- if (opp_init_cpufreq_table(mpu_dev, &freq_table)) +- clk_init_cpufreq_table(&freq_table); ++ if (!freq_table) { ++ if (opp_init_cpufreq_table(mpu_dev, &freq_table)) ++ clk_init_cpufreq_table(&freq_table); ++ } + + if (freq_table) { ++ freq_table_users++; + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); + if (!result) { + cpufreq_frequency_table_get_attr(freq_table, +@@ -215,10 +234,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) + clk_exit_cpufreq_table(&freq_table); + WARN(true, "%s: fallback to clk_round(freq_table=%d)\n", + __func__, result); +- kfree(freq_table); +- freq_table = NULL; ++ freq_table_free(); + } + } ++ mutex_unlock(&freq_table_lock); + + if (!freq_table) { + policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; +@@ -251,9 +270,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) + + static int omap_cpu_exit(struct cpufreq_policy *policy) + { +- clk_exit_cpufreq_table(&freq_table); +- kfree(freq_table); +- freq_table = NULL; ++ mutex_lock(&freq_table_lock); ++ freq_table_free(); ++ mutex_unlock(&freq_table_lock); + clk_put(mpu_clk); + return 0; + } +-- +1.6.6.1 + |