summaryrefslogtreecommitdiffstats
path: root/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
diff options
context:
space:
mode:
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.patch100
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 @@
1From 42a384af80e07534913d9002ec8d9caf5d4d305c Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Wed, 18 May 2011 01:48:23 -0500
4Subject: [PATCH 6/6] OMAP2+: cpufreq: fix freq_table leak
5
6Since we have two cpus the cpuinit call for cpu1 causes
7freq_table of cpu0 to be overwritten. instead, we maintain
8a counter to keep track of cpus who use the cpufreq table
9allocate it once(one freq table for all CPUs) and free them
10once the last user is done with it.
11
12Signed-off-by: Nishanth Menon <nm@ti.com>
13Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
14---
15 arch/arm/mach-omap2/omap2plus-cpufreq.c | 33 ++++++++++++++++++++++++------
16 1 files changed, 26 insertions(+), 7 deletions(-)
17
18diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
19index d0b4f97..fc3d0fb 100644
20--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
21+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
22@@ -42,6 +42,9 @@
23 #define VERY_HI_RATE 900000000
24
25 static struct cpufreq_frequency_table *freq_table;
26+static int freq_table_users;
27+static DEFINE_MUTEX(freq_table_lock);
28+
29 static struct clk *mpu_clk;
30
31 static int omap_verify_speed(struct cpufreq_policy *policy)
32@@ -172,6 +175,18 @@ skip_lpj:
33 return ret;
34 }
35
36+static void freq_table_free(void)
37+{
38+ if (!freq_table_users)
39+ return;
40+ freq_table_users--;
41+ if (freq_table_users)
42+ return;
43+ clk_exit_cpufreq_table(&freq_table);
44+ kfree(freq_table);
45+ freq_table = NULL;
46+}
47+
48 static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
49 {
50 int result = 0;
51@@ -199,14 +214,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
52 return -EINVAL;
53 }
54
55+ mutex_lock(&freq_table_lock);
56 /*
57 * if we dont get cpufreq table using opp, use traditional omap2 lookup
58 * as a fallback
59 */
60- if (opp_init_cpufreq_table(mpu_dev, &freq_table))
61- clk_init_cpufreq_table(&freq_table);
62+ if (!freq_table) {
63+ if (opp_init_cpufreq_table(mpu_dev, &freq_table))
64+ clk_init_cpufreq_table(&freq_table);
65+ }
66
67 if (freq_table) {
68+ freq_table_users++;
69 result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
70 if (!result) {
71 cpufreq_frequency_table_get_attr(freq_table,
72@@ -215,10 +234,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
73 clk_exit_cpufreq_table(&freq_table);
74 WARN(true, "%s: fallback to clk_round(freq_table=%d)\n",
75 __func__, result);
76- kfree(freq_table);
77- freq_table = NULL;
78+ freq_table_free();
79 }
80 }
81+ mutex_unlock(&freq_table_lock);
82
83 if (!freq_table) {
84 policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
85@@ -251,9 +270,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
86
87 static int omap_cpu_exit(struct cpufreq_policy *policy)
88 {
89- clk_exit_cpufreq_table(&freq_table);
90- kfree(freq_table);
91- freq_table = NULL;
92+ mutex_lock(&freq_table_lock);
93+ freq_table_free();
94+ mutex_unlock(&freq_table_lock);
95 clk_put(mpu_clk);
96 return 0;
97 }
98--
991.6.6.1
100