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 @@ | |||
1 | From 42a384af80e07534913d9002ec8d9caf5d4d305c 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 | ||
5 | |||
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. | ||
11 | |||
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(-) | ||
17 | |||
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 | ||
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 | -- | ||
99 | 1.6.6.1 | ||
100 | |||