]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - 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
linux-omap 2.6.39: update to latest beagle patchset
[glsdk/meta-ti-glsdk.git] / 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
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
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