linux-omap 2.6.39: sync with meta-texasinstruments
[openembedded.git] / recipes / 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
blob0727ebcdeeb6659255ee05bbf9f3790496757874
1 From 9303bae0e4acf8a8b3b0c682d6655a656fc776bf Mon Sep 17 00:00:00 2001
2 From: Nishanth Menon <nm@ti.com>
3 Date: Wed, 18 May 2011 01:48:23 -0500
4 Subject: [PATCH 6/6] OMAP2+: cpufreq: fix freq_table leak
6 Since we have two cpus the cpuinit call for cpu1 causes
7 freq_table of cpu0 to be overwritten. instead, we maintain
8 a counter to keep track of cpus who use the cpufreq table
9 allocate it once(one freq table for all CPUs) and free them
10 once the last user is done with it.
12 Signed-off-by: Nishanth Menon <nm@ti.com>
13 Signed-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(-)
18 diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
19 index 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
25 static struct cpufreq_frequency_table *freq_table;
26 +static int freq_table_users;
27 +static DEFINE_MUTEX(freq_table_lock);
29 static struct clk *mpu_clk;
31 static int omap_verify_speed(struct cpufreq_policy *policy)
32 @@ -172,6 +175,18 @@ skip_lpj:
33 return ret;
36 +static void freq_table_free(void)
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;
48 static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
50 int result = 0;
51 @@ -199,14 +214,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
52 return -EINVAL;
55 + mutex_lock(&freq_table_lock);
57 * if we dont get cpufreq table using opp, use traditional omap2 lookup
58 * as a fallback
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 + }
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();
81 + mutex_unlock(&freq_table_lock);
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)
87 static int omap_cpu_exit(struct cpufreq_policy *policy)
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;
98 --
99 1.6.6.1