diff options
author | Koen Kooi <koen@dominion.thruhere.net> | 2011-07-20 14:41:45 +0200 |
---|---|---|
committer | Koen Kooi <koen@dominion.thruhere.net> | 2011-07-20 14:41:45 +0200 |
commit | e125e989fafda1faf6d3f5dc33e949cd7d4b5a97 (patch) | |
tree | 5359f8bbfa60493160ef883083f863fce5ea2fb4 /recipes-kernel/linux/linux-3.0/pm-wip | |
parent | 7018fe0a81fa33c6d73d6296d25517b5d427d0a7 (diff) | |
download | meta-ti-e125e989fafda1faf6d3f5dc33e949cd7d4b5a97.tar.gz |
linux 3.0: initial recipe that will track 3.0rc till 3.0 final
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
Diffstat (limited to 'recipes-kernel/linux/linux-3.0/pm-wip')
19 files changed, 2072 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0001-PM-OPP-introduce-function-to-free-cpufreq-table.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0001-PM-OPP-introduce-function-to-free-cpufreq-table.patch new file mode 100644 index 00000000..f92c4abc --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0001-PM-OPP-introduce-function-to-free-cpufreq-table.patch | |||
@@ -0,0 +1,84 @@ | |||
1 | From e029940bc6c0ff4ad3c8e2b4f31d0a3de78eff32 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nishanth Menon <nm@ti.com> | ||
3 | Date: Wed, 25 May 2011 00:43:26 -0700 | ||
4 | Subject: [PATCH 01/19] PM: OPP: introduce function to free cpufreq table | ||
5 | |||
6 | cpufreq table allocated by opp_init_cpufreq_table is better | ||
7 | freed by OPP layer itself. This allows future modifications to | ||
8 | the table handling to be transparent to the users. | ||
9 | |||
10 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
11 | Acked-by: Kevin Hilman <khilman@ti.com> | ||
12 | --- | ||
13 | Documentation/power/opp.txt | 2 ++ | ||
14 | drivers/base/power/opp.c | 17 +++++++++++++++++ | ||
15 | include/linux/opp.h | 8 ++++++++ | ||
16 | 3 files changed, 27 insertions(+), 0 deletions(-) | ||
17 | |||
18 | diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt | ||
19 | index 5ae70a1..3035d00 100644 | ||
20 | --- a/Documentation/power/opp.txt | ||
21 | +++ b/Documentation/power/opp.txt | ||
22 | @@ -321,6 +321,8 @@ opp_init_cpufreq_table - cpufreq framework typically is initialized with | ||
23 | addition to CONFIG_PM as power management feature is required to | ||
24 | dynamically scale voltage and frequency in a system. | ||
25 | |||
26 | +opp_free_cpufreq_table - Free up the table allocated by opp_init_cpufreq_table | ||
27 | + | ||
28 | 7. Data Structures | ||
29 | ================== | ||
30 | Typically an SoC contains multiple voltage domains which are variable. Each | ||
31 | diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c | ||
32 | index 56a6899..5cc1232 100644 | ||
33 | --- a/drivers/base/power/opp.c | ||
34 | +++ b/drivers/base/power/opp.c | ||
35 | @@ -625,4 +625,21 @@ int opp_init_cpufreq_table(struct device *dev, | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | + | ||
40 | +/** | ||
41 | + * opp_free_cpufreq_table() - free the cpufreq table | ||
42 | + * @dev: device for which we do this operation | ||
43 | + * @table: table to free | ||
44 | + * | ||
45 | + * Free up the table allocated by opp_init_cpufreq_table | ||
46 | + */ | ||
47 | +void opp_free_cpufreq_table(struct device *dev, | ||
48 | + struct cpufreq_frequency_table **table) | ||
49 | +{ | ||
50 | + if (!table) | ||
51 | + return; | ||
52 | + | ||
53 | + kfree(*table); | ||
54 | + *table = NULL; | ||
55 | +} | ||
56 | #endif /* CONFIG_CPU_FREQ */ | ||
57 | diff --git a/include/linux/opp.h b/include/linux/opp.h | ||
58 | index 5449945..7020e97 100644 | ||
59 | --- a/include/linux/opp.h | ||
60 | +++ b/include/linux/opp.h | ||
61 | @@ -94,12 +94,20 @@ static inline int opp_disable(struct device *dev, unsigned long freq) | ||
62 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_PM_OPP) | ||
63 | int opp_init_cpufreq_table(struct device *dev, | ||
64 | struct cpufreq_frequency_table **table); | ||
65 | +void opp_free_cpufreq_table(struct device *dev, | ||
66 | + struct cpufreq_frequency_table **table); | ||
67 | #else | ||
68 | static inline int opp_init_cpufreq_table(struct device *dev, | ||
69 | struct cpufreq_frequency_table **table) | ||
70 | { | ||
71 | return -EINVAL; | ||
72 | } | ||
73 | + | ||
74 | +static inline | ||
75 | +void opp_free_cpufreq_table(struct device *dev, | ||
76 | + struct cpufreq_frequency_table **table) | ||
77 | +{ | ||
78 | +} | ||
79 | #endif /* CONFIG_CPU_FREQ */ | ||
80 | |||
81 | #endif /* __LINUX_OPP_H__ */ | ||
82 | -- | ||
83 | 1.6.6.1 | ||
84 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0002-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0002-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch new file mode 100644 index 00000000..5201c81b --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0002-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch | |||
@@ -0,0 +1,28 @@ | |||
1 | From 895fc8961297666b46b4cd3f8c01010051d2164e Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com> | ||
3 | Date: Wed, 11 Aug 2010 17:02:43 -0700 | ||
4 | Subject: [PATCH 02/19] OMAP: CPUfreq: ensure driver initializes after cpufreq framework and governors | ||
5 | |||
6 | Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com> | ||
7 | Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
8 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
9 | --- | ||
10 | arch/arm/plat-omap/cpu-omap.c | 2 +- | ||
11 | 1 files changed, 1 insertions(+), 1 deletions(-) | ||
12 | |||
13 | diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c | ||
14 | index da4f68d..cd09d4b 100644 | ||
15 | --- a/arch/arm/plat-omap/cpu-omap.c | ||
16 | +++ b/arch/arm/plat-omap/cpu-omap.c | ||
17 | @@ -160,7 +160,7 @@ static int __init omap_cpufreq_init(void) | ||
18 | return cpufreq_register_driver(&omap_driver); | ||
19 | } | ||
20 | |||
21 | -arch_initcall(omap_cpufreq_init); | ||
22 | +late_initcall(omap_cpufreq_init); | ||
23 | |||
24 | /* | ||
25 | * if ever we want to remove this, upon cleanup call: | ||
26 | -- | ||
27 | 1.6.6.1 | ||
28 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0003-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0003-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch new file mode 100644 index 00000000..5447646a --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0003-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch | |||
@@ -0,0 +1,32 @@ | |||
1 | From 62bd1b0f18ee6c6bad1573c2f06e74b0abc418a3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Kevin Hilman <khilman@deeprootsystems.com> | ||
3 | Date: Wed, 11 Aug 2010 17:05:38 -0700 | ||
4 | Subject: [PATCH 03/19] OMAP: CPUfreq: ensure policy is fully initialized | ||
5 | |||
6 | Ensure policy min/max/cur values are initialized when OMAP | ||
7 | CPUfreq driver starts. | ||
8 | |||
9 | Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
10 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
11 | --- | ||
12 | arch/arm/plat-omap/cpu-omap.c | 4 ++++ | ||
13 | 1 files changed, 4 insertions(+), 0 deletions(-) | ||
14 | |||
15 | diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c | ||
16 | index cd09d4b..1b36664 100644 | ||
17 | --- a/arch/arm/plat-omap/cpu-omap.c | ||
18 | +++ b/arch/arm/plat-omap/cpu-omap.c | ||
19 | @@ -126,6 +126,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
20 | VERY_HI_RATE) / 1000; | ||
21 | } | ||
22 | |||
23 | + policy->min = policy->cpuinfo.min_freq; | ||
24 | + policy->max = policy->cpuinfo.max_freq; | ||
25 | + policy->cur = omap_getspeed(0); | ||
26 | + | ||
27 | /* FIXME: what's the actual transition time? */ | ||
28 | policy->cpuinfo.transition_latency = 300 * 1000; | ||
29 | |||
30 | -- | ||
31 | 1.6.6.1 | ||
32 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0004-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0004-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch new file mode 100644 index 00000000..c490a1de --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0004-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch | |||
@@ -0,0 +1,264 @@ | |||
1 | From afa9b062a33a9d9d2d9077cc519e1375b8338e39 Mon Sep 17 00:00:00 2001 | ||
2 | From: Rajendra Nayak <rnayak@ti.com> | ||
3 | Date: Mon, 10 Nov 2008 17:00:25 +0530 | ||
4 | Subject: [PATCH 04/19] OMAP3 PM: CPUFreq driver for OMAP3 | ||
5 | |||
6 | CPUFreq driver for OMAP3 | ||
7 | |||
8 | With additional fixes and cleanups from Tero Kristo: | ||
9 | - Fix rate calculation bug in omap3_select_table_rate | ||
10 | - Refreshed DVFS VDD1 control against latest clock fw | ||
11 | |||
12 | Signed-off-by: Tero Kristo <tero.kristo@nokia.com> | ||
13 | Signed-off-by: Rajendra Nayak <rnayak@ti.com> | ||
14 | |||
15 | OMAP3: PM: CPUFreq: Fix omap_getspeed. | ||
16 | |||
17 | Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com> | ||
18 | |||
19 | Make sure omap cpufreq driver initializes after cpufreq framework and governors | ||
20 | |||
21 | Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com> | ||
22 | |||
23 | merge: CPUFreq: remove obsolete funcs | ||
24 | |||
25 | OMAP3 clock: Update cpufreq driver | ||
26 | |||
27 | This patch removes all refrences to virtual clock | ||
28 | nodes in CPUFreq driver. | ||
29 | |||
30 | Signed-off-by: Rajendra Nayak <rnayak@ti.com> | ||
31 | Signed-off-by: Tero Kristo <tero.kristo@nokia.com> | ||
32 | Signed-off-by: Jean Pihet <jpihet@mvista.com> | ||
33 | |||
34 | PM: Prevent direct cpufreq scaling during initialization | ||
35 | |||
36 | It is seen that the OMAP specific cpufreq initialization code tries to | ||
37 | scale the MPU frequency to the highest possible without taking care of | ||
38 | the voltage level. On power on reset the power IC does not provide the | ||
39 | necessary voltage for the highest available MPU frequency (that would | ||
40 | satisfy all Si families). This potentially is an window of opportunity | ||
41 | for things to go wrong. | ||
42 | |||
43 | Signed-off-by: Romit Dasgupta <romit@ti.com> | ||
44 | Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
45 | |||
46 | OMAP3: PM: enable 600MHz (overdrive) OPP | ||
47 | |||
48 | Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
49 | |||
50 | omap3: introduce cpufreq | ||
51 | |||
52 | OMAP OPP layer functions now have dependencies of CONFIG_CPU_FREQ only. | ||
53 | |||
54 | With this patch, omap opp layer now has its compilation flags | ||
55 | bound to CONFIG_CPU_FREQ. Also its code has been removed from pm34xx.c. | ||
56 | |||
57 | A new file has been created to contain cpu freq code related to | ||
58 | OMAP3: cpufreq34xx.c | ||
59 | |||
60 | OMAP34xx and OMAP36xx family OPPs are made available | ||
61 | |||
62 | Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com> | ||
63 | Signed-off-by: Paul Walmsley <paul@pwsan.com> | ||
64 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
65 | Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com> | ||
66 | Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
67 | Signed-off-by: Romit Dasgupta <romit@ti.com> | ||
68 | Signed-off-by: Rajendra Nayak <rnayak@ti.com> | ||
69 | |||
70 | omap3: cpufreq: allow default opp table init | ||
71 | |||
72 | For board files which choose to override the defaults, the existing | ||
73 | mechanism will work, for boards that would like to work with defaults, | ||
74 | allow init_common_hw to call init_opp_table to initialize if not | ||
75 | already initialized. this will allow all omap boards which have opp | ||
76 | tables predefined for a silicon to use the same. | ||
77 | |||
78 | Originally reported for overo: | ||
79 | http://marc.info/?t=127265269400004&r=1&w=2 | ||
80 | |||
81 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
82 | Reported-by: Peter Tseng <tsenpet09@gmail.com> | ||
83 | Cc: Cliff Brake <cliff.brake@gmail.com> | ||
84 | Cc: Kevin Hilman <khilman@deeprootsystems.com> | ||
85 | |||
86 | OMAP2: update OPP data to be device based | ||
87 | |||
88 | Cc: Nishanth Menon <nm@ti.com> | ||
89 | Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
90 | |||
91 | OMAP3: CPUfreq: update to device-based OPP API | ||
92 | |||
93 | Update usage of OPP API to use new device-based API. This requires | ||
94 | getting the 'struct device' for the MPU and using that with the OPP | ||
95 | API. | ||
96 | |||
97 | Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> | ||
98 | |||
99 | omap3: opp: make independent of cpufreq | ||
100 | |||
101 | Make opp3xx data which is registered with the opp layer | ||
102 | dependent purely on CONFIG_PM as opp layer and pm.c users | ||
103 | are CONFIG_PM dependent not cpufreq dependent. | ||
104 | so we rename the data definition to opp3xxx_data.c (inline with what | ||
105 | we have for omap2), also move the build definition to be under | ||
106 | the existing CONFIG_PM build instead of CPUFREQ. | ||
107 | |||
108 | Cc: Eduardo Valentin <eduardo.valentin@nokia.com> | ||
109 | Cc: Kevin Hilman <khilman@deeprootsystems.com> | ||
110 | Cc: Paul Walmsley <paul@pwsan.com> | ||
111 | Cc: Rajendra Nayak <rnayak@ti.com> | ||
112 | Cc: Sanjeev Premi <premi@ti.com> | ||
113 | Cc: Thara Gopinath <thara@ti.com> | ||
114 | Cc: Tony Lindgren <tony@atomide.com> | ||
115 | |||
116 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
117 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
118 | --- | ||
119 | arch/arm/mach-omap2/clock.h | 14 +++++++++++++- | ||
120 | arch/arm/mach-omap2/clock34xx.c | 2 ++ | ||
121 | arch/arm/plat-omap/cpu-omap.c | 34 +++++++++++++++++++++++++++++++--- | ||
122 | 3 files changed, 46 insertions(+), 4 deletions(-) | ||
123 | |||
124 | diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h | ||
125 | index e10ff2b..0a07e50 100644 | ||
126 | --- a/arch/arm/mach-omap2/clock.h | ||
127 | +++ b/arch/arm/mach-omap2/clock.h | ||
128 | @@ -141,7 +141,9 @@ extern const struct clksel_rate gpt_sys_rates[]; | ||
129 | extern const struct clksel_rate gfx_l3_rates[]; | ||
130 | extern const struct clksel_rate dsp_ick_rates[]; | ||
131 | |||
132 | -#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) | ||
133 | +#ifdef CONFIG_CPU_FREQ | ||
134 | + | ||
135 | +#ifdef CONFIG_ARCH_OMAP2 | ||
136 | extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); | ||
137 | extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); | ||
138 | #else | ||
139 | @@ -149,6 +151,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) | ||
140 | #define omap2_clk_exit_cpufreq_table 0 | ||
141 | #endif | ||
142 | |||
143 | +#ifdef CONFIG_ARCH_OMAP3 | ||
144 | +extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); | ||
145 | +extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); | ||
146 | +#else | ||
147 | +#define omap3_clk_init_cpufreq_table 0 | ||
148 | +#define omap3_clk_exit_cpufreq_table 0 | ||
149 | +#endif | ||
150 | + | ||
151 | +#endif /* CONFIG_CPU_FREQ */ | ||
152 | + | ||
153 | extern const struct clkops clkops_omap2_iclk_dflt_wait; | ||
154 | extern const struct clkops clkops_omap2_iclk_dflt; | ||
155 | extern const struct clkops clkops_omap2_iclk_idle_only; | ||
156 | diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c | ||
157 | index 1fc96b9..119e135 100644 | ||
158 | --- a/arch/arm/mach-omap2/clock34xx.c | ||
159 | +++ b/arch/arm/mach-omap2/clock34xx.c | ||
160 | @@ -20,6 +20,8 @@ | ||
161 | #include <linux/kernel.h> | ||
162 | #include <linux/clk.h> | ||
163 | #include <linux/io.h> | ||
164 | +#include <linux/err.h> | ||
165 | +#include <linux/cpufreq.h> | ||
166 | |||
167 | #include <plat/clock.h> | ||
168 | |||
169 | diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c | ||
170 | index 1b36664..f0f9430 100644 | ||
171 | --- a/arch/arm/plat-omap/cpu-omap.c | ||
172 | +++ b/arch/arm/plat-omap/cpu-omap.c | ||
173 | @@ -8,6 +8,10 @@ | ||
174 | * | ||
175 | * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King | ||
176 | * | ||
177 | + * Copyright (C) 2007-2008 Texas Instruments, Inc. | ||
178 | + * Updated to support OMAP3 | ||
179 | + * Rajendra Nayak <rnayak@ti.com> | ||
180 | + * | ||
181 | * This program is free software; you can redistribute it and/or modify | ||
182 | * it under the terms of the GNU General Public License version 2 as | ||
183 | * published by the Free Software Foundation. | ||
184 | @@ -26,12 +30,19 @@ | ||
185 | #include <plat/clock.h> | ||
186 | #include <asm/system.h> | ||
187 | |||
188 | +#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) | ||
189 | +#include <plat/omap-pm.h> | ||
190 | +#include <plat/opp.h> | ||
191 | +#endif | ||
192 | + | ||
193 | #define VERY_HI_RATE 900000000 | ||
194 | |||
195 | static struct cpufreq_frequency_table *freq_table; | ||
196 | |||
197 | #ifdef CONFIG_ARCH_OMAP1 | ||
198 | #define MPU_CLK "mpu" | ||
199 | +#elif CONFIG_ARCH_OMAP3 | ||
200 | +#define MPU_CLK "arm_fck" | ||
201 | #else | ||
202 | #define MPU_CLK "virt_prcm_set" | ||
203 | #endif | ||
204 | @@ -73,7 +84,13 @@ static int omap_target(struct cpufreq_policy *policy, | ||
205 | unsigned int target_freq, | ||
206 | unsigned int relation) | ||
207 | { | ||
208 | +#ifdef CONFIG_ARCH_OMAP1 | ||
209 | struct cpufreq_freqs freqs; | ||
210 | +#endif | ||
211 | +#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) | ||
212 | + unsigned long freq; | ||
213 | + struct device *mpu_dev = omap2_get_mpuss_device(); | ||
214 | +#endif | ||
215 | int ret = 0; | ||
216 | |||
217 | /* Ensure desired rate is within allowed range. Some govenors | ||
218 | @@ -83,13 +100,13 @@ static int omap_target(struct cpufreq_policy *policy, | ||
219 | if (target_freq > policy->max) | ||
220 | target_freq = policy->max; | ||
221 | |||
222 | +#ifdef CONFIG_ARCH_OMAP1 | ||
223 | freqs.old = omap_getspeed(0); | ||
224 | freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | ||
225 | freqs.cpu = 0; | ||
226 | |||
227 | if (freqs.old == freqs.new) | ||
228 | return ret; | ||
229 | - | ||
230 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
231 | #ifdef CONFIG_CPU_FREQ_DEBUG | ||
232 | printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n", | ||
233 | @@ -97,7 +114,11 @@ static int omap_target(struct cpufreq_policy *policy, | ||
234 | #endif | ||
235 | ret = clk_set_rate(mpu_clk, freqs.new * 1000); | ||
236 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
237 | - | ||
238 | +#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) | ||
239 | + freq = target_freq * 1000; | ||
240 | + if (opp_find_freq_ceil(mpu_dev, &freq)) | ||
241 | + omap_pm_cpu_set_freq(freq); | ||
242 | +#endif | ||
243 | return ret; | ||
244 | } | ||
245 | |||
246 | @@ -114,7 +135,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
247 | |||
248 | policy->cur = policy->min = policy->max = omap_getspeed(0); | ||
249 | |||
250 | - clk_init_cpufreq_table(&freq_table); | ||
251 | + if (!cpu_is_omap34xx()) { | ||
252 | + clk_init_cpufreq_table(&freq_table); | ||
253 | + } else { | ||
254 | + struct device *mpu_dev = omap2_get_mpuss_device(); | ||
255 | + | ||
256 | + opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
257 | + } | ||
258 | + | ||
259 | if (freq_table) { | ||
260 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
261 | if (!result) | ||
262 | -- | ||
263 | 1.6.6.1 | ||
264 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0005-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0005-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch new file mode 100644 index 00000000..1801c46c --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0005-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch | |||
@@ -0,0 +1,33 @@ | |||
1 | From c93327d36f0dc4ea6693fcae54c561eb8bafdd1e Mon Sep 17 00:00:00 2001 | ||
2 | From: Silesh C V <silesh@ti.com> | ||
3 | Date: Wed, 29 Sep 2010 14:52:54 +0530 | ||
4 | Subject: [PATCH 05/19] OMAP: PM: CPUFREQ: Fix conditional compilation | ||
5 | |||
6 | Fix conditional compilation. A conditional expresiion | ||
7 | should follow "#elif", in this case #elif clause should | ||
8 | check whether CONFIG_ARCH_OMAP3 is defined or not | ||
9 | (ie. defined(CONFIG_ARCH_OMAP3)) rather than checking for | ||
10 | the value of the macro. | ||
11 | |||
12 | Signed-off-by: Silesh C V <silesh@ti.com> | ||
13 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
14 | --- | ||
15 | arch/arm/plat-omap/cpu-omap.c | 2 +- | ||
16 | 1 files changed, 1 insertions(+), 1 deletions(-) | ||
17 | |||
18 | diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c | ||
19 | index f0f9430..c3ac065 100644 | ||
20 | --- a/arch/arm/plat-omap/cpu-omap.c | ||
21 | +++ b/arch/arm/plat-omap/cpu-omap.c | ||
22 | @@ -41,7 +41,7 @@ static struct cpufreq_frequency_table *freq_table; | ||
23 | |||
24 | #ifdef CONFIG_ARCH_OMAP1 | ||
25 | #define MPU_CLK "mpu" | ||
26 | -#elif CONFIG_ARCH_OMAP3 | ||
27 | +#elif defined(CONFIG_ARCH_OMAP3) | ||
28 | #define MPU_CLK "arm_fck" | ||
29 | #else | ||
30 | #define MPU_CLK "virt_prcm_set" | ||
31 | -- | ||
32 | 1.6.6.1 | ||
33 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0006-cpufreq-fixup-after-new-OPP-layer-merged.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0006-cpufreq-fixup-after-new-OPP-layer-merged.patch new file mode 100644 index 00000000..9c035fab --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0006-cpufreq-fixup-after-new-OPP-layer-merged.patch | |||
@@ -0,0 +1,34 @@ | |||
1 | From b8246b5d5edc98155628ba88510bc7e67baf7acf Mon Sep 17 00:00:00 2001 | ||
2 | From: Kevin Hilman <khilman@deeprootsystems.com> | ||
3 | Date: Tue, 16 Nov 2010 11:48:41 -0800 | ||
4 | Subject: [PATCH 06/19] cpufreq: fixup after new OPP layer merged | ||
5 | |||
6 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
7 | --- | ||
8 | arch/arm/plat-omap/cpu-omap.c | 3 ++- | ||
9 | 1 files changed, 2 insertions(+), 1 deletions(-) | ||
10 | |||
11 | diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c | ||
12 | index c3ac065..9cd2709 100644 | ||
13 | --- a/arch/arm/plat-omap/cpu-omap.c | ||
14 | +++ b/arch/arm/plat-omap/cpu-omap.c | ||
15 | @@ -25,6 +25,7 @@ | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/io.h> | ||
19 | +#include <linux/opp.h> | ||
20 | |||
21 | #include <mach/hardware.h> | ||
22 | #include <plat/clock.h> | ||
23 | @@ -32,7 +33,7 @@ | ||
24 | |||
25 | #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) | ||
26 | #include <plat/omap-pm.h> | ||
27 | -#include <plat/opp.h> | ||
28 | +#include <plat/common.h> | ||
29 | #endif | ||
30 | |||
31 | #define VERY_HI_RATE 900000000 | ||
32 | -- | ||
33 | 1.6.6.1 | ||
34 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch new file mode 100644 index 00000000..3eafe76c --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch | |||
@@ -0,0 +1,673 @@ | |||
1 | From 9f9061d3e98aa6db7d5c3feabd5a2d93eb3cb737 Mon Sep 17 00:00:00 2001 | ||
2 | From: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
3 | Date: Mon, 14 Mar 2011 17:08:48 +0530 | ||
4 | Subject: [PATCH 07/19] OMAP: cpufreq: Split OMAP1 and OMAP2PLUS CPUfreq drivers. | ||
5 | |||
6 | This patch is an attempt to cleanup the #ifdeferry in the | ||
7 | omap CPUfreq drivers. | ||
8 | |||
9 | The split betwenn OMAP1 and OMAP2PLUS is logical because | ||
10 | - OMAP1 doesn't support opp layer. | ||
11 | - OMAP1 build is seperate from omap2plus. | ||
12 | |||
13 | Includes minor header/copyright updates reported by Todd Poynor. | ||
14 | |||
15 | Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
16 | Cc: Kevin Hilman <khilman@ti.com> | ||
17 | Cc: Vishwanath BS <vishwanath.bs@ti.com> | ||
18 | Cc: Todd Poynor <toddpoynor@google.com> | ||
19 | Cc: Nishanth Menon <nm@ti.com> | ||
20 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
21 | --- | ||
22 | arch/arm/mach-omap1/Makefile | 3 + | ||
23 | arch/arm/mach-omap1/omap1-cpufreq.c | 175 ++++++++++++++++++++++++++ | ||
24 | arch/arm/mach-omap2/Makefile | 3 + | ||
25 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 201 ++++++++++++++++++++++++++++++ | ||
26 | arch/arm/plat-omap/Makefile | 1 - | ||
27 | arch/arm/plat-omap/cpu-omap.c | 204 ------------------------------- | ||
28 | 6 files changed, 382 insertions(+), 205 deletions(-) | ||
29 | create mode 100644 arch/arm/mach-omap1/omap1-cpufreq.c | ||
30 | create mode 100644 arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
31 | delete mode 100644 arch/arm/plat-omap/cpu-omap.c | ||
32 | |||
33 | diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile | ||
34 | index 5b114d1..9600410 100644 | ||
35 | --- a/arch/arm/mach-omap1/Makefile | ||
36 | +++ b/arch/arm/mach-omap1/Makefile | ||
37 | @@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o | ||
38 | |||
39 | obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o | ||
40 | |||
41 | +# CPUFREQ driver | ||
42 | +obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o | ||
43 | + | ||
44 | # Power Management | ||
45 | obj-$(CONFIG_PM) += pm.o sleep.o | ||
46 | |||
47 | diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c | ||
48 | new file mode 100644 | ||
49 | index 0000000..7c5216e | ||
50 | --- /dev/null | ||
51 | +++ b/arch/arm/mach-omap1/omap1-cpufreq.c | ||
52 | @@ -0,0 +1,175 @@ | ||
53 | +/* | ||
54 | + * OMAP1 cpufreq driver | ||
55 | + * | ||
56 | + * CPU frequency scaling for OMAP | ||
57 | + * | ||
58 | + * Copyright (C) 2005 Nokia Corporation | ||
59 | + * Written by Tony Lindgren <tony@atomide.com> | ||
60 | + * | ||
61 | + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King | ||
62 | + * | ||
63 | + * Copyright (C) 2007-2008 Texas Instruments, Inc. | ||
64 | + * Rajendra Nayak <rnayak@ti.com> | ||
65 | + * | ||
66 | + * This program is free software; you can redistribute it and/or modify | ||
67 | + * it under the terms of the GNU General Public License version 2 as | ||
68 | + * published by the Free Software Foundation. | ||
69 | + */ | ||
70 | +#include <linux/types.h> | ||
71 | +#include <linux/kernel.h> | ||
72 | +#include <linux/sched.h> | ||
73 | +#include <linux/cpufreq.h> | ||
74 | +#include <linux/delay.h> | ||
75 | +#include <linux/init.h> | ||
76 | +#include <linux/err.h> | ||
77 | +#include <linux/clk.h> | ||
78 | +#include <linux/io.h> | ||
79 | +#include <linux/opp.h> | ||
80 | + | ||
81 | +#include <asm/system.h> | ||
82 | + | ||
83 | +#include <plat/clock.h> | ||
84 | +#include <plat/omap-pm.h> | ||
85 | + | ||
86 | +#include <mach/hardware.h> | ||
87 | + | ||
88 | +#define VERY_HI_RATE 900000000 | ||
89 | + | ||
90 | +static struct cpufreq_frequency_table *freq_table; | ||
91 | +static struct clk *mpu_clk; | ||
92 | + | ||
93 | +static int omap_verify_speed(struct cpufreq_policy *policy) | ||
94 | +{ | ||
95 | + if (freq_table) | ||
96 | + return cpufreq_frequency_table_verify(policy, freq_table); | ||
97 | + | ||
98 | + if (policy->cpu) | ||
99 | + return -EINVAL; | ||
100 | + | ||
101 | + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
102 | + policy->cpuinfo.max_freq); | ||
103 | + | ||
104 | + policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; | ||
105 | + policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; | ||
106 | + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
107 | + policy->cpuinfo.max_freq); | ||
108 | + return 0; | ||
109 | +} | ||
110 | + | ||
111 | +static unsigned int omap_getspeed(unsigned int cpu) | ||
112 | +{ | ||
113 | + unsigned long rate; | ||
114 | + | ||
115 | + if (cpu) | ||
116 | + return 0; | ||
117 | + | ||
118 | + rate = clk_get_rate(mpu_clk) / 1000; | ||
119 | + return rate; | ||
120 | +} | ||
121 | + | ||
122 | +static int omap_target(struct cpufreq_policy *policy, | ||
123 | + unsigned int target_freq, | ||
124 | + unsigned int relation) | ||
125 | +{ | ||
126 | + struct cpufreq_freqs freqs; | ||
127 | + int ret = 0; | ||
128 | + | ||
129 | + /* Ensure desired rate is within allowed range. Some govenors | ||
130 | + * (ondemand) will just pass target_freq=0 to get the minimum. */ | ||
131 | + if (target_freq < policy->min) | ||
132 | + target_freq = policy->min; | ||
133 | + if (target_freq > policy->max) | ||
134 | + target_freq = policy->max; | ||
135 | + | ||
136 | + freqs.old = omap_getspeed(0); | ||
137 | + freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | ||
138 | + freqs.cpu = 0; | ||
139 | + | ||
140 | + if (freqs.old == freqs.new) | ||
141 | + return ret; | ||
142 | + | ||
143 | + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
144 | + | ||
145 | +#ifdef CONFIG_CPU_FREQ_DEBUG | ||
146 | + pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); | ||
147 | +#endif | ||
148 | + ret = clk_set_rate(mpu_clk, freqs.new * 1000); | ||
149 | + | ||
150 | + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
151 | + | ||
152 | + return ret; | ||
153 | +} | ||
154 | + | ||
155 | +static int __init omap_cpu_init(struct cpufreq_policy *policy) | ||
156 | +{ | ||
157 | + int result = 0; | ||
158 | + | ||
159 | + mpu_clk = clk_get(NULL, "mpu"); | ||
160 | + if (IS_ERR(mpu_clk)) | ||
161 | + return PTR_ERR(mpu_clk); | ||
162 | + | ||
163 | + if (policy->cpu != 0) | ||
164 | + return -EINVAL; | ||
165 | + | ||
166 | + policy->cur = policy->min = policy->max = omap_getspeed(0); | ||
167 | + | ||
168 | + clk_init_cpufreq_table(&freq_table); | ||
169 | + | ||
170 | + if (freq_table) { | ||
171 | + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
172 | + if (!result) | ||
173 | + cpufreq_frequency_table_get_attr(freq_table, | ||
174 | + policy->cpu); | ||
175 | + } else { | ||
176 | + policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; | ||
177 | + policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, | ||
178 | + VERY_HI_RATE) / 1000; | ||
179 | + } | ||
180 | + | ||
181 | + policy->min = policy->cpuinfo.min_freq; | ||
182 | + policy->max = policy->cpuinfo.max_freq; | ||
183 | + policy->cur = omap_getspeed(0); | ||
184 | + | ||
185 | + /* FIXME: what's the actual transition time? */ | ||
186 | + policy->cpuinfo.transition_latency = 300 * 1000; | ||
187 | + | ||
188 | + return 0; | ||
189 | +} | ||
190 | + | ||
191 | +static int omap_cpu_exit(struct cpufreq_policy *policy) | ||
192 | +{ | ||
193 | + clk_exit_cpufreq_table(&freq_table); | ||
194 | + clk_put(mpu_clk); | ||
195 | + return 0; | ||
196 | +} | ||
197 | + | ||
198 | +static struct freq_attr *omap_cpufreq_attr[] = { | ||
199 | + &cpufreq_freq_attr_scaling_available_freqs, | ||
200 | + NULL, | ||
201 | +}; | ||
202 | + | ||
203 | +static struct cpufreq_driver omap_driver = { | ||
204 | + .flags = CPUFREQ_STICKY, | ||
205 | + .verify = omap_verify_speed, | ||
206 | + .target = omap_target, | ||
207 | + .get = omap_getspeed, | ||
208 | + .init = omap_cpu_init, | ||
209 | + .exit = omap_cpu_exit, | ||
210 | + .name = "omap1", | ||
211 | + .attr = omap_cpufreq_attr, | ||
212 | +}; | ||
213 | + | ||
214 | +static int __init omap_cpufreq_init(void) | ||
215 | +{ | ||
216 | + return cpufreq_register_driver(&omap_driver); | ||
217 | +} | ||
218 | + | ||
219 | +static void __exit omap_cpufreq_exit(void) | ||
220 | +{ | ||
221 | + cpufreq_unregister_driver(&omap_driver); | ||
222 | +} | ||
223 | + | ||
224 | +MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs"); | ||
225 | +MODULE_LICENSE("GPL"); | ||
226 | +module_init(omap_cpufreq_init); | ||
227 | +module_exit(omap_cpufreq_exit); | ||
228 | diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile | ||
229 | index b148077..5024064 100644 | ||
230 | --- a/arch/arm/mach-omap2/Makefile | ||
231 | +++ b/arch/arm/mach-omap2/Makefile | ||
232 | @@ -56,6 +56,9 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o | ||
233 | obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o | ||
234 | endif | ||
235 | |||
236 | +# CPUFREQ driver | ||
237 | +obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o | ||
238 | + | ||
239 | # Power Management | ||
240 | ifeq ($(CONFIG_PM),y) | ||
241 | obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o | ||
242 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
243 | new file mode 100644 | ||
244 | index 0000000..27f641b | ||
245 | --- /dev/null | ||
246 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
247 | @@ -0,0 +1,201 @@ | ||
248 | +/* | ||
249 | + * OMAP2PLUS cpufreq driver | ||
250 | + * | ||
251 | + * CPU frequency scaling for OMAP | ||
252 | + * | ||
253 | + * Copyright (C) 2005 Nokia Corporation | ||
254 | + * Written by Tony Lindgren <tony@atomide.com> | ||
255 | + * | ||
256 | + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King | ||
257 | + * | ||
258 | + * Copyright (C) 2007-2011 Texas Instruments, Inc. | ||
259 | + * Updated to support OMAP3 | ||
260 | + * Rajendra Nayak <rnayak@ti.com> | ||
261 | + * | ||
262 | + * This program is free software; you can redistribute it and/or modify | ||
263 | + * it under the terms of the GNU General Public License version 2 as | ||
264 | + * published by the Free Software Foundation. | ||
265 | + */ | ||
266 | +#include <linux/types.h> | ||
267 | +#include <linux/kernel.h> | ||
268 | +#include <linux/sched.h> | ||
269 | +#include <linux/cpufreq.h> | ||
270 | +#include <linux/delay.h> | ||
271 | +#include <linux/init.h> | ||
272 | +#include <linux/err.h> | ||
273 | +#include <linux/clk.h> | ||
274 | +#include <linux/io.h> | ||
275 | +#include <linux/opp.h> | ||
276 | + | ||
277 | +#include <asm/system.h> | ||
278 | +#include <asm/smp_plat.h> | ||
279 | + | ||
280 | +#include <plat/clock.h> | ||
281 | +#include <plat/omap-pm.h> | ||
282 | +#include <plat/common.h> | ||
283 | + | ||
284 | +#include <mach/hardware.h> | ||
285 | + | ||
286 | +#define VERY_HI_RATE 900000000 | ||
287 | + | ||
288 | +static struct cpufreq_frequency_table *freq_table; | ||
289 | +static struct clk *mpu_clk; | ||
290 | + | ||
291 | +static int omap_verify_speed(struct cpufreq_policy *policy) | ||
292 | +{ | ||
293 | + if (freq_table) | ||
294 | + return cpufreq_frequency_table_verify(policy, freq_table); | ||
295 | + | ||
296 | + if (policy->cpu) | ||
297 | + return -EINVAL; | ||
298 | + | ||
299 | + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
300 | + policy->cpuinfo.max_freq); | ||
301 | + | ||
302 | + policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; | ||
303 | + policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; | ||
304 | + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
305 | + policy->cpuinfo.max_freq); | ||
306 | + return 0; | ||
307 | +} | ||
308 | + | ||
309 | +static unsigned int omap_getspeed(unsigned int cpu) | ||
310 | +{ | ||
311 | + unsigned long rate; | ||
312 | + | ||
313 | + if (cpu) | ||
314 | + return 0; | ||
315 | + | ||
316 | + rate = clk_get_rate(mpu_clk) / 1000; | ||
317 | + return rate; | ||
318 | +} | ||
319 | + | ||
320 | +static int omap_target(struct cpufreq_policy *policy, | ||
321 | + unsigned int target_freq, | ||
322 | + unsigned int relation) | ||
323 | +{ | ||
324 | + int ret = 0; | ||
325 | + struct cpufreq_freqs freqs; | ||
326 | + | ||
327 | + /* Ensure desired rate is within allowed range. Some govenors | ||
328 | + * (ondemand) will just pass target_freq=0 to get the minimum. */ | ||
329 | + if (target_freq < policy->min) | ||
330 | + target_freq = policy->min; | ||
331 | + if (target_freq > policy->max) | ||
332 | + target_freq = policy->max; | ||
333 | + | ||
334 | + freqs.old = omap_getspeed(0); | ||
335 | + freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | ||
336 | + freqs.cpu = 0; | ||
337 | + | ||
338 | + if (freqs.old == freqs.new) | ||
339 | + return ret; | ||
340 | + | ||
341 | + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
342 | + | ||
343 | +#ifdef CONFIG_CPU_FREQ_DEBUG | ||
344 | + pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); | ||
345 | +#endif | ||
346 | + | ||
347 | + ret = clk_set_rate(mpu_clk, freqs.new * 1000); | ||
348 | + | ||
349 | + /* | ||
350 | + * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies | ||
351 | + * won't get updated when UP machine cpufreq build with | ||
352 | + * CONFIG_SMP enabled. Below code is added only to manage that | ||
353 | + * scenario | ||
354 | + */ | ||
355 | + if (!is_smp()) | ||
356 | + loops_per_jiffy = | ||
357 | + cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new); | ||
358 | + | ||
359 | + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
360 | + | ||
361 | + return ret; | ||
362 | +} | ||
363 | + | ||
364 | +static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
365 | +{ | ||
366 | + int result = 0; | ||
367 | + struct device *mpu_dev; | ||
368 | + | ||
369 | + if (cpu_is_omap24xx()) | ||
370 | + mpu_clk = clk_get(NULL, "virt_prcm_set"); | ||
371 | + else if (cpu_is_omap34xx()) | ||
372 | + mpu_clk = clk_get(NULL, "dpll1_ck"); | ||
373 | + else if (cpu_is_omap34xx()) | ||
374 | + mpu_clk = clk_get(NULL, "dpll_mpu_ck"); | ||
375 | + | ||
376 | + if (IS_ERR(mpu_clk)) | ||
377 | + return PTR_ERR(mpu_clk); | ||
378 | + | ||
379 | + if (policy->cpu != 0) | ||
380 | + return -EINVAL; | ||
381 | + | ||
382 | + policy->cur = policy->min = policy->max = omap_getspeed(0); | ||
383 | + | ||
384 | + mpu_dev = omap2_get_mpuss_device(); | ||
385 | + if (!mpu_dev) { | ||
386 | + pr_warning("%s: unable to get the mpu device\n", __func__); | ||
387 | + return -EINVAL; | ||
388 | + } | ||
389 | + opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
390 | + | ||
391 | + if (freq_table) { | ||
392 | + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
393 | + if (!result) | ||
394 | + cpufreq_frequency_table_get_attr(freq_table, | ||
395 | + policy->cpu); | ||
396 | + } else { | ||
397 | + policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; | ||
398 | + policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, | ||
399 | + VERY_HI_RATE) / 1000; | ||
400 | + } | ||
401 | + | ||
402 | + policy->min = policy->cpuinfo.min_freq; | ||
403 | + policy->max = policy->cpuinfo.max_freq; | ||
404 | + policy->cur = omap_getspeed(0); | ||
405 | + | ||
406 | + /* FIXME: what's the actual transition time? */ | ||
407 | + policy->cpuinfo.transition_latency = 300 * 1000; | ||
408 | + | ||
409 | + return 0; | ||
410 | +} | ||
411 | + | ||
412 | +static int omap_cpu_exit(struct cpufreq_policy *policy) | ||
413 | +{ | ||
414 | + clk_exit_cpufreq_table(&freq_table); | ||
415 | + clk_put(mpu_clk); | ||
416 | + return 0; | ||
417 | +} | ||
418 | + | ||
419 | +static struct freq_attr *omap_cpufreq_attr[] = { | ||
420 | + &cpufreq_freq_attr_scaling_available_freqs, | ||
421 | + NULL, | ||
422 | +}; | ||
423 | + | ||
424 | +static struct cpufreq_driver omap_driver = { | ||
425 | + .flags = CPUFREQ_STICKY, | ||
426 | + .verify = omap_verify_speed, | ||
427 | + .target = omap_target, | ||
428 | + .get = omap_getspeed, | ||
429 | + .init = omap_cpu_init, | ||
430 | + .exit = omap_cpu_exit, | ||
431 | + .name = "omap2plus", | ||
432 | + .attr = omap_cpufreq_attr, | ||
433 | +}; | ||
434 | + | ||
435 | +static int __init omap_cpufreq_init(void) | ||
436 | +{ | ||
437 | + return cpufreq_register_driver(&omap_driver); | ||
438 | +} | ||
439 | + | ||
440 | +static void __exit omap_cpufreq_exit(void) | ||
441 | +{ | ||
442 | + cpufreq_unregister_driver(&omap_driver); | ||
443 | +} | ||
444 | + | ||
445 | +MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs"); | ||
446 | +MODULE_LICENSE("GPL"); | ||
447 | +module_init(omap_cpufreq_init); | ||
448 | +module_exit(omap_cpufreq_exit); | ||
449 | diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile | ||
450 | index f0233e6..4ef7493 100644 | ||
451 | --- a/arch/arm/plat-omap/Makefile | ||
452 | +++ b/arch/arm/plat-omap/Makefile | ||
453 | @@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o | ||
454 | obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o | ||
455 | obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o | ||
456 | |||
457 | -obj-$(CONFIG_CPU_FREQ) += cpu-omap.o | ||
458 | obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o | ||
459 | obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o | ||
460 | obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o | ||
461 | diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c | ||
462 | deleted file mode 100644 | ||
463 | index 9cd2709..0000000 | ||
464 | --- a/arch/arm/plat-omap/cpu-omap.c | ||
465 | +++ /dev/null | ||
466 | @@ -1,204 +0,0 @@ | ||
467 | -/* | ||
468 | - * linux/arch/arm/plat-omap/cpu-omap.c | ||
469 | - * | ||
470 | - * CPU frequency scaling for OMAP | ||
471 | - * | ||
472 | - * Copyright (C) 2005 Nokia Corporation | ||
473 | - * Written by Tony Lindgren <tony@atomide.com> | ||
474 | - * | ||
475 | - * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King | ||
476 | - * | ||
477 | - * Copyright (C) 2007-2008 Texas Instruments, Inc. | ||
478 | - * Updated to support OMAP3 | ||
479 | - * Rajendra Nayak <rnayak@ti.com> | ||
480 | - * | ||
481 | - * This program is free software; you can redistribute it and/or modify | ||
482 | - * it under the terms of the GNU General Public License version 2 as | ||
483 | - * published by the Free Software Foundation. | ||
484 | - */ | ||
485 | -#include <linux/types.h> | ||
486 | -#include <linux/kernel.h> | ||
487 | -#include <linux/sched.h> | ||
488 | -#include <linux/cpufreq.h> | ||
489 | -#include <linux/delay.h> | ||
490 | -#include <linux/init.h> | ||
491 | -#include <linux/err.h> | ||
492 | -#include <linux/clk.h> | ||
493 | -#include <linux/io.h> | ||
494 | -#include <linux/opp.h> | ||
495 | - | ||
496 | -#include <mach/hardware.h> | ||
497 | -#include <plat/clock.h> | ||
498 | -#include <asm/system.h> | ||
499 | - | ||
500 | -#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) | ||
501 | -#include <plat/omap-pm.h> | ||
502 | -#include <plat/common.h> | ||
503 | -#endif | ||
504 | - | ||
505 | -#define VERY_HI_RATE 900000000 | ||
506 | - | ||
507 | -static struct cpufreq_frequency_table *freq_table; | ||
508 | - | ||
509 | -#ifdef CONFIG_ARCH_OMAP1 | ||
510 | -#define MPU_CLK "mpu" | ||
511 | -#elif defined(CONFIG_ARCH_OMAP3) | ||
512 | -#define MPU_CLK "arm_fck" | ||
513 | -#else | ||
514 | -#define MPU_CLK "virt_prcm_set" | ||
515 | -#endif | ||
516 | - | ||
517 | -static struct clk *mpu_clk; | ||
518 | - | ||
519 | -/* TODO: Add support for SDRAM timing changes */ | ||
520 | - | ||
521 | -static int omap_verify_speed(struct cpufreq_policy *policy) | ||
522 | -{ | ||
523 | - if (freq_table) | ||
524 | - return cpufreq_frequency_table_verify(policy, freq_table); | ||
525 | - | ||
526 | - if (policy->cpu) | ||
527 | - return -EINVAL; | ||
528 | - | ||
529 | - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
530 | - policy->cpuinfo.max_freq); | ||
531 | - | ||
532 | - policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; | ||
533 | - policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; | ||
534 | - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
535 | - policy->cpuinfo.max_freq); | ||
536 | - return 0; | ||
537 | -} | ||
538 | - | ||
539 | -static unsigned int omap_getspeed(unsigned int cpu) | ||
540 | -{ | ||
541 | - unsigned long rate; | ||
542 | - | ||
543 | - if (cpu) | ||
544 | - return 0; | ||
545 | - | ||
546 | - rate = clk_get_rate(mpu_clk) / 1000; | ||
547 | - return rate; | ||
548 | -} | ||
549 | - | ||
550 | -static int omap_target(struct cpufreq_policy *policy, | ||
551 | - unsigned int target_freq, | ||
552 | - unsigned int relation) | ||
553 | -{ | ||
554 | -#ifdef CONFIG_ARCH_OMAP1 | ||
555 | - struct cpufreq_freqs freqs; | ||
556 | -#endif | ||
557 | -#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) | ||
558 | - unsigned long freq; | ||
559 | - struct device *mpu_dev = omap2_get_mpuss_device(); | ||
560 | -#endif | ||
561 | - int ret = 0; | ||
562 | - | ||
563 | - /* Ensure desired rate is within allowed range. Some govenors | ||
564 | - * (ondemand) will just pass target_freq=0 to get the minimum. */ | ||
565 | - if (target_freq < policy->min) | ||
566 | - target_freq = policy->min; | ||
567 | - if (target_freq > policy->max) | ||
568 | - target_freq = policy->max; | ||
569 | - | ||
570 | -#ifdef CONFIG_ARCH_OMAP1 | ||
571 | - freqs.old = omap_getspeed(0); | ||
572 | - freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | ||
573 | - freqs.cpu = 0; | ||
574 | - | ||
575 | - if (freqs.old == freqs.new) | ||
576 | - return ret; | ||
577 | - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
578 | -#ifdef CONFIG_CPU_FREQ_DEBUG | ||
579 | - printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n", | ||
580 | - freqs.old, freqs.new); | ||
581 | -#endif | ||
582 | - ret = clk_set_rate(mpu_clk, freqs.new * 1000); | ||
583 | - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
584 | -#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) | ||
585 | - freq = target_freq * 1000; | ||
586 | - if (opp_find_freq_ceil(mpu_dev, &freq)) | ||
587 | - omap_pm_cpu_set_freq(freq); | ||
588 | -#endif | ||
589 | - return ret; | ||
590 | -} | ||
591 | - | ||
592 | -static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
593 | -{ | ||
594 | - int result = 0; | ||
595 | - | ||
596 | - mpu_clk = clk_get(NULL, MPU_CLK); | ||
597 | - if (IS_ERR(mpu_clk)) | ||
598 | - return PTR_ERR(mpu_clk); | ||
599 | - | ||
600 | - if (policy->cpu != 0) | ||
601 | - return -EINVAL; | ||
602 | - | ||
603 | - policy->cur = policy->min = policy->max = omap_getspeed(0); | ||
604 | - | ||
605 | - if (!cpu_is_omap34xx()) { | ||
606 | - clk_init_cpufreq_table(&freq_table); | ||
607 | - } else { | ||
608 | - struct device *mpu_dev = omap2_get_mpuss_device(); | ||
609 | - | ||
610 | - opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
611 | - } | ||
612 | - | ||
613 | - if (freq_table) { | ||
614 | - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
615 | - if (!result) | ||
616 | - cpufreq_frequency_table_get_attr(freq_table, | ||
617 | - policy->cpu); | ||
618 | - } else { | ||
619 | - policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; | ||
620 | - policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, | ||
621 | - VERY_HI_RATE) / 1000; | ||
622 | - } | ||
623 | - | ||
624 | - policy->min = policy->cpuinfo.min_freq; | ||
625 | - policy->max = policy->cpuinfo.max_freq; | ||
626 | - policy->cur = omap_getspeed(0); | ||
627 | - | ||
628 | - /* FIXME: what's the actual transition time? */ | ||
629 | - policy->cpuinfo.transition_latency = 300 * 1000; | ||
630 | - | ||
631 | - return 0; | ||
632 | -} | ||
633 | - | ||
634 | -static int omap_cpu_exit(struct cpufreq_policy *policy) | ||
635 | -{ | ||
636 | - clk_exit_cpufreq_table(&freq_table); | ||
637 | - clk_put(mpu_clk); | ||
638 | - return 0; | ||
639 | -} | ||
640 | - | ||
641 | -static struct freq_attr *omap_cpufreq_attr[] = { | ||
642 | - &cpufreq_freq_attr_scaling_available_freqs, | ||
643 | - NULL, | ||
644 | -}; | ||
645 | - | ||
646 | -static struct cpufreq_driver omap_driver = { | ||
647 | - .flags = CPUFREQ_STICKY, | ||
648 | - .verify = omap_verify_speed, | ||
649 | - .target = omap_target, | ||
650 | - .get = omap_getspeed, | ||
651 | - .init = omap_cpu_init, | ||
652 | - .exit = omap_cpu_exit, | ||
653 | - .name = "omap", | ||
654 | - .attr = omap_cpufreq_attr, | ||
655 | -}; | ||
656 | - | ||
657 | -static int __init omap_cpufreq_init(void) | ||
658 | -{ | ||
659 | - return cpufreq_register_driver(&omap_driver); | ||
660 | -} | ||
661 | - | ||
662 | -late_initcall(omap_cpufreq_init); | ||
663 | - | ||
664 | -/* | ||
665 | - * if ever we want to remove this, upon cleanup call: | ||
666 | - * | ||
667 | - * cpufreq_unregister_driver() | ||
668 | - * cpufreq_frequency_table_put_attr() | ||
669 | - */ | ||
670 | - | ||
671 | -- | ||
672 | 1.6.6.1 | ||
673 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0008-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0008-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch new file mode 100644 index 00000000..b47934f2 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0008-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch | |||
@@ -0,0 +1,171 @@ | |||
1 | From f5dc16c8178d0c0bcad795f8ebc71934c4028472 Mon Sep 17 00:00:00 2001 | ||
2 | From: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
3 | Date: Mon, 14 Mar 2011 17:08:49 +0530 | ||
4 | Subject: [PATCH 08/19] OMAP2PLUS: cpufreq: Add SMP support to cater OMAP4430 | ||
5 | |||
6 | On OMAP SMP configuartion, both processors share the voltage | ||
7 | and clock. So both CPUs needs to be scaled together and hence | ||
8 | needs software co-ordination. | ||
9 | |||
10 | Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
11 | Cc: Kevin Hilman <khilman@ti.com> | ||
12 | cc: Vishwanath BS <vishwanath.bs@ti.com> | ||
13 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
14 | --- | ||
15 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 73 ++++++++++++++++++++++++++----- | ||
16 | 1 files changed, 62 insertions(+), 11 deletions(-) | ||
17 | |||
18 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
19 | index 27f641b..3730f96 100644 | ||
20 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
21 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
22 | @@ -26,9 +26,11 @@ | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/opp.h> | ||
26 | +#include <linux/cpu.h> | ||
27 | |||
28 | #include <asm/system.h> | ||
29 | #include <asm/smp_plat.h> | ||
30 | +#include <asm/cpu.h> | ||
31 | |||
32 | #include <plat/clock.h> | ||
33 | #include <plat/omap-pm.h> | ||
34 | @@ -63,7 +65,7 @@ static unsigned int omap_getspeed(unsigned int cpu) | ||
35 | { | ||
36 | unsigned long rate; | ||
37 | |||
38 | - if (cpu) | ||
39 | + if (cpu >= NR_CPUS) | ||
40 | return 0; | ||
41 | |||
42 | rate = clk_get_rate(mpu_clk) / 1000; | ||
43 | @@ -74,9 +76,13 @@ static int omap_target(struct cpufreq_policy *policy, | ||
44 | unsigned int target_freq, | ||
45 | unsigned int relation) | ||
46 | { | ||
47 | - int ret = 0; | ||
48 | + int i, ret = 0; | ||
49 | struct cpufreq_freqs freqs; | ||
50 | |||
51 | + /* Changes not allowed until all CPUs are online */ | ||
52 | + if (is_smp() && (num_online_cpus() < NR_CPUS)) | ||
53 | + return ret; | ||
54 | + | ||
55 | /* Ensure desired rate is within allowed range. Some govenors | ||
56 | * (ondemand) will just pass target_freq=0 to get the minimum. */ | ||
57 | if (target_freq < policy->min) | ||
58 | @@ -84,15 +90,25 @@ static int omap_target(struct cpufreq_policy *policy, | ||
59 | if (target_freq > policy->max) | ||
60 | target_freq = policy->max; | ||
61 | |||
62 | - freqs.old = omap_getspeed(0); | ||
63 | + freqs.old = omap_getspeed(policy->cpu); | ||
64 | freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | ||
65 | - freqs.cpu = 0; | ||
66 | + freqs.cpu = policy->cpu; | ||
67 | |||
68 | if (freqs.old == freqs.new) | ||
69 | return ret; | ||
70 | |||
71 | - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
72 | + if (!is_smp()) { | ||
73 | + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
74 | + goto set_freq; | ||
75 | + } | ||
76 | + | ||
77 | + /* notifiers */ | ||
78 | + for_each_cpu(i, policy->cpus) { | ||
79 | + freqs.cpu = i; | ||
80 | + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
81 | + } | ||
82 | |||
83 | +set_freq: | ||
84 | #ifdef CONFIG_CPU_FREQ_DEBUG | ||
85 | pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); | ||
86 | #endif | ||
87 | @@ -105,12 +121,33 @@ static int omap_target(struct cpufreq_policy *policy, | ||
88 | * CONFIG_SMP enabled. Below code is added only to manage that | ||
89 | * scenario | ||
90 | */ | ||
91 | - if (!is_smp()) | ||
92 | + freqs.new = omap_getspeed(policy->cpu); | ||
93 | + if (!is_smp()) { | ||
94 | loops_per_jiffy = | ||
95 | cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new); | ||
96 | + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
97 | + goto skip_lpj; | ||
98 | + } | ||
99 | |||
100 | - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
101 | +#ifdef CONFIG_SMP | ||
102 | + /* | ||
103 | + * Note that loops_per_jiffy is not updated on SMP systems in | ||
104 | + * cpufreq driver. So, update the per-CPU loops_per_jiffy value | ||
105 | + * on frequency transition. We need to update all dependent CPUs. | ||
106 | + */ | ||
107 | + for_each_cpu(i, policy->cpus) | ||
108 | + per_cpu(cpu_data, i).loops_per_jiffy = | ||
109 | + cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy, | ||
110 | + freqs.old, freqs.new); | ||
111 | +#endif | ||
112 | |||
113 | + /* notifiers */ | ||
114 | + for_each_cpu(i, policy->cpus) { | ||
115 | + freqs.cpu = i; | ||
116 | + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
117 | + } | ||
118 | + | ||
119 | +skip_lpj: | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | @@ -118,6 +155,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
124 | { | ||
125 | int result = 0; | ||
126 | struct device *mpu_dev; | ||
127 | + static cpumask_var_t cpumask; | ||
128 | |||
129 | if (cpu_is_omap24xx()) | ||
130 | mpu_clk = clk_get(NULL, "virt_prcm_set"); | ||
131 | @@ -129,12 +167,12 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
132 | if (IS_ERR(mpu_clk)) | ||
133 | return PTR_ERR(mpu_clk); | ||
134 | |||
135 | - if (policy->cpu != 0) | ||
136 | + if (policy->cpu >= NR_CPUS) | ||
137 | return -EINVAL; | ||
138 | |||
139 | - policy->cur = policy->min = policy->max = omap_getspeed(0); | ||
140 | - | ||
141 | + policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); | ||
142 | mpu_dev = omap2_get_mpuss_device(); | ||
143 | + | ||
144 | if (!mpu_dev) { | ||
145 | pr_warning("%s: unable to get the mpu device\n", __func__); | ||
146 | return -EINVAL; | ||
147 | @@ -154,7 +192,20 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
148 | |||
149 | policy->min = policy->cpuinfo.min_freq; | ||
150 | policy->max = policy->cpuinfo.max_freq; | ||
151 | - policy->cur = omap_getspeed(0); | ||
152 | + policy->cur = omap_getspeed(policy->cpu); | ||
153 | + | ||
154 | + /* | ||
155 | + * On OMAP SMP configuartion, both processors share the voltage | ||
156 | + * and clock. So both CPUs needs to be scaled together and hence | ||
157 | + * needs software co-ordination. Use cpufreq affected_cpus | ||
158 | + * interface to handle this scenario. Additional is_smp() check | ||
159 | + * is to keep SMP_ON_UP build working. | ||
160 | + */ | ||
161 | + if (is_smp()) { | ||
162 | + policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; | ||
163 | + cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask); | ||
164 | + cpumask_copy(policy->cpus, cpumask); | ||
165 | + } | ||
166 | |||
167 | /* FIXME: what's the actual transition time? */ | ||
168 | policy->cpuinfo.transition_latency = 300 * 1000; | ||
169 | -- | ||
170 | 1.6.6.1 | ||
171 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0009-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0009-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch new file mode 100644 index 00000000..b7ea956d --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0009-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch | |||
@@ -0,0 +1,30 @@ | |||
1 | From 07367b4c3afd8e881c4cf50ef35d081c4ac252b8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Jarkko Nikula <jhnikula@gmail.com> | ||
3 | Date: Thu, 14 Apr 2011 16:21:58 +0300 | ||
4 | Subject: [PATCH 09/19] OMAP2PLUS: cpufreq: Fix typo when attempting to set mpu_clk for OMAP4 | ||
5 | |||
6 | Fix this typo as there is no dpll_mpu_ck for OMAP3 and code flow is clearly | ||
7 | trying to set mpu_clk for OMAP4 for which this dpll_mpu_ck is available. | ||
8 | |||
9 | Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> | ||
10 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
11 | --- | ||
12 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 2 +- | ||
13 | 1 files changed, 1 insertions(+), 1 deletions(-) | ||
14 | |||
15 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
16 | index 3730f96..a725d90 100644 | ||
17 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
18 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
19 | @@ -161,7 +161,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
20 | mpu_clk = clk_get(NULL, "virt_prcm_set"); | ||
21 | else if (cpu_is_omap34xx()) | ||
22 | mpu_clk = clk_get(NULL, "dpll1_ck"); | ||
23 | - else if (cpu_is_omap34xx()) | ||
24 | + else if (cpu_is_omap44xx()) | ||
25 | mpu_clk = clk_get(NULL, "dpll_mpu_ck"); | ||
26 | |||
27 | if (IS_ERR(mpu_clk)) | ||
28 | -- | ||
29 | 1.6.6.1 | ||
30 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0010-OMAP2-cpufreq-move-clk-name-decision-to-init.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0010-OMAP2-cpufreq-move-clk-name-decision-to-init.patch new file mode 100644 index 00000000..fe892e37 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0010-OMAP2-cpufreq-move-clk-name-decision-to-init.patch | |||
@@ -0,0 +1,64 @@ | |||
1 | From 4d3e024c2f7f0334874bbb2a168b62e91cb2517a Mon Sep 17 00:00:00 2001 | ||
2 | From: Nishanth Menon <nm@ti.com> | ||
3 | Date: Wed, 25 May 2011 16:38:46 -0700 | ||
4 | Subject: [PATCH 10/19] OMAP2+: cpufreq: move clk name decision to init | ||
5 | |||
6 | Clk name does'nt need to dynamically detected during clk init. | ||
7 | move them off to driver initialization, if we dont have a clk name, | ||
8 | there is no point in registering the driver anyways. The actual clk | ||
9 | get and put is left at cpu_init and exit functions. | ||
10 | |||
11 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
12 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
13 | --- | ||
14 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 20 +++++++++++++------- | ||
15 | 1 files changed, 13 insertions(+), 7 deletions(-) | ||
16 | |||
17 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
18 | index a725d90..c46d0cd 100644 | ||
19 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
20 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
21 | @@ -42,6 +42,7 @@ | ||
22 | |||
23 | static struct cpufreq_frequency_table *freq_table; | ||
24 | static struct clk *mpu_clk; | ||
25 | +static char *mpu_clk_name; | ||
26 | |||
27 | static int omap_verify_speed(struct cpufreq_policy *policy) | ||
28 | { | ||
29 | @@ -157,13 +158,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
30 | struct device *mpu_dev; | ||
31 | static cpumask_var_t cpumask; | ||
32 | |||
33 | - if (cpu_is_omap24xx()) | ||
34 | - mpu_clk = clk_get(NULL, "virt_prcm_set"); | ||
35 | - else if (cpu_is_omap34xx()) | ||
36 | - mpu_clk = clk_get(NULL, "dpll1_ck"); | ||
37 | - else if (cpu_is_omap44xx()) | ||
38 | - mpu_clk = clk_get(NULL, "dpll_mpu_ck"); | ||
39 | - | ||
40 | + mpu_clk = clk_get(NULL, mpu_clk_name); | ||
41 | if (IS_ERR(mpu_clk)) | ||
42 | return PTR_ERR(mpu_clk); | ||
43 | |||
44 | @@ -238,6 +233,17 @@ static struct cpufreq_driver omap_driver = { | ||
45 | |||
46 | static int __init omap_cpufreq_init(void) | ||
47 | { | ||
48 | + if (cpu_is_omap24xx()) | ||
49 | + mpu_clk_name = "virt_prcm_set"; | ||
50 | + else if (cpu_is_omap34xx()) | ||
51 | + mpu_clk_name = "dpll1_ck"; | ||
52 | + else if (cpu_is_omap44xx()) | ||
53 | + mpu_clk_name = "dpll_mpu_ck"; | ||
54 | + | ||
55 | + if (!mpu_clk_name) { | ||
56 | + pr_err("%s: unsupported Silicon?\n", __func__); | ||
57 | + return -EINVAL; | ||
58 | + } | ||
59 | return cpufreq_register_driver(&omap_driver); | ||
60 | } | ||
61 | |||
62 | -- | ||
63 | 1.6.6.1 | ||
64 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0011-OMAP2-cpufreq-deny-initialization-if-no-mpudev.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0011-OMAP2-cpufreq-deny-initialization-if-no-mpudev.patch new file mode 100644 index 00000000..4138e3fe --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0011-OMAP2-cpufreq-deny-initialization-if-no-mpudev.patch | |||
@@ -0,0 +1,64 @@ | |||
1 | From 85afa12ad2a6e7a23ddf4b25e78e0ce5b9f18a64 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nishanth Menon <nm@ti.com> | ||
3 | Date: Wed, 25 May 2011 16:38:47 -0700 | ||
4 | Subject: [PATCH 11/19] OMAP2+: cpufreq: deny initialization if no mpudev | ||
5 | |||
6 | if we do not have mpu_dev we normally fail in cpu_init. It is better | ||
7 | to fail driver registration if the devices are not available. | ||
8 | |||
9 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
10 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
11 | --- | ||
12 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 15 ++++++++------- | ||
13 | 1 files changed, 8 insertions(+), 7 deletions(-) | ||
14 | |||
15 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
16 | index c46d0cd..33a91ec 100644 | ||
17 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
18 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
19 | @@ -43,6 +43,7 @@ | ||
20 | static struct cpufreq_frequency_table *freq_table; | ||
21 | static struct clk *mpu_clk; | ||
22 | static char *mpu_clk_name; | ||
23 | +static struct device *mpu_dev; | ||
24 | |||
25 | static int omap_verify_speed(struct cpufreq_policy *policy) | ||
26 | { | ||
27 | @@ -155,7 +156,6 @@ skip_lpj: | ||
28 | static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
29 | { | ||
30 | int result = 0; | ||
31 | - struct device *mpu_dev; | ||
32 | static cpumask_var_t cpumask; | ||
33 | |||
34 | mpu_clk = clk_get(NULL, mpu_clk_name); | ||
35 | @@ -166,12 +166,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
36 | return -EINVAL; | ||
37 | |||
38 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); | ||
39 | - mpu_dev = omap2_get_mpuss_device(); | ||
40 | - | ||
41 | - if (!mpu_dev) { | ||
42 | - pr_warning("%s: unable to get the mpu device\n", __func__); | ||
43 | - return -EINVAL; | ||
44 | - } | ||
45 | opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
46 | |||
47 | if (freq_table) { | ||
48 | @@ -244,6 +238,13 @@ static int __init omap_cpufreq_init(void) | ||
49 | pr_err("%s: unsupported Silicon?\n", __func__); | ||
50 | return -EINVAL; | ||
51 | } | ||
52 | + | ||
53 | + mpu_dev = omap2_get_mpuss_device(); | ||
54 | + if (!mpu_dev) { | ||
55 | + pr_warning("%s: unable to get the mpu device\n", __func__); | ||
56 | + return -EINVAL; | ||
57 | + } | ||
58 | + | ||
59 | return cpufreq_register_driver(&omap_driver); | ||
60 | } | ||
61 | |||
62 | -- | ||
63 | 1.6.6.1 | ||
64 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0012-OMAP2-cpufreq-dont-support-freq_table.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0012-OMAP2-cpufreq-dont-support-freq_table.patch new file mode 100644 index 00000000..b57031a0 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0012-OMAP2-cpufreq-dont-support-freq_table.patch | |||
@@ -0,0 +1,129 @@ | |||
1 | From 345f93655f425c87ba01e949dc038e04542d8cd4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nishanth Menon <nm@ti.com> | ||
3 | Date: Thu, 26 May 2011 19:39:17 -0700 | ||
4 | Subject: [PATCH 12/19] OMAP2+: cpufreq: dont support !freq_table | ||
5 | |||
6 | OMAP2+ all have frequency tables, hence the hacks we had for older | ||
7 | silicon do not need to be carried forward. As part of this change, | ||
8 | use cpufreq_frequency_table_target to find the best match for | ||
9 | frequency requested. | ||
10 | |||
11 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
12 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
13 | --- | ||
14 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 67 +++++++++++++++---------------- | ||
15 | 1 files changed, 33 insertions(+), 34 deletions(-) | ||
16 | |||
17 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
18 | index 33a91ec..acf18e8 100644 | ||
19 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
20 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
21 | @@ -38,8 +38,6 @@ | ||
22 | |||
23 | #include <mach/hardware.h> | ||
24 | |||
25 | -#define VERY_HI_RATE 900000000 | ||
26 | - | ||
27 | static struct cpufreq_frequency_table *freq_table; | ||
28 | static struct clk *mpu_clk; | ||
29 | static char *mpu_clk_name; | ||
30 | @@ -47,20 +45,9 @@ static struct device *mpu_dev; | ||
31 | |||
32 | static int omap_verify_speed(struct cpufreq_policy *policy) | ||
33 | { | ||
34 | - if (freq_table) | ||
35 | - return cpufreq_frequency_table_verify(policy, freq_table); | ||
36 | - | ||
37 | - if (policy->cpu) | ||
38 | + if (!freq_table) | ||
39 | return -EINVAL; | ||
40 | - | ||
41 | - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
42 | - policy->cpuinfo.max_freq); | ||
43 | - | ||
44 | - policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; | ||
45 | - policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; | ||
46 | - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
47 | - policy->cpuinfo.max_freq); | ||
48 | - return 0; | ||
49 | + return cpufreq_frequency_table_verify(policy, freq_table); | ||
50 | } | ||
51 | |||
52 | static unsigned int omap_getspeed(unsigned int cpu) | ||
53 | @@ -78,22 +65,35 @@ static int omap_target(struct cpufreq_policy *policy, | ||
54 | unsigned int target_freq, | ||
55 | unsigned int relation) | ||
56 | { | ||
57 | - int i, ret = 0; | ||
58 | + unsigned int i; | ||
59 | + int ret = 0; | ||
60 | struct cpufreq_freqs freqs; | ||
61 | |||
62 | /* Changes not allowed until all CPUs are online */ | ||
63 | if (is_smp() && (num_online_cpus() < NR_CPUS)) | ||
64 | return ret; | ||
65 | |||
66 | - /* Ensure desired rate is within allowed range. Some govenors | ||
67 | - * (ondemand) will just pass target_freq=0 to get the minimum. */ | ||
68 | - if (target_freq < policy->min) | ||
69 | - target_freq = policy->min; | ||
70 | - if (target_freq > policy->max) | ||
71 | - target_freq = policy->max; | ||
72 | + if (!freq_table) { | ||
73 | + dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__, | ||
74 | + policy->cpu); | ||
75 | + return -EINVAL; | ||
76 | + } | ||
77 | + | ||
78 | + ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, | ||
79 | + relation, &i); | ||
80 | + if (ret) { | ||
81 | + dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n", | ||
82 | + __func__, policy->cpu, target_freq, ret); | ||
83 | + return ret; | ||
84 | + } | ||
85 | + freqs.new = freq_table[i].frequency; | ||
86 | + if (!freqs.new) { | ||
87 | + dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__, | ||
88 | + policy->cpu, target_freq); | ||
89 | + return -EINVAL; | ||
90 | + } | ||
91 | |||
92 | freqs.old = omap_getspeed(policy->cpu); | ||
93 | - freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | ||
94 | freqs.cpu = policy->cpu; | ||
95 | |||
96 | if (freqs.old == freqs.new) | ||
97 | @@ -166,19 +166,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
98 | return -EINVAL; | ||
99 | |||
100 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); | ||
101 | - opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
102 | - | ||
103 | - if (freq_table) { | ||
104 | - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
105 | - if (!result) | ||
106 | - cpufreq_frequency_table_get_attr(freq_table, | ||
107 | - policy->cpu); | ||
108 | - } else { | ||
109 | - policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; | ||
110 | - policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, | ||
111 | - VERY_HI_RATE) / 1000; | ||
112 | + result = opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
113 | + | ||
114 | + if (result) { | ||
115 | + dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n", | ||
116 | + __func__, policy->cpu, result); | ||
117 | + return result; | ||
118 | } | ||
119 | |||
120 | + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
121 | + if (!result) | ||
122 | + cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
123 | + | ||
124 | policy->min = policy->cpuinfo.min_freq; | ||
125 | policy->max = policy->cpuinfo.max_freq; | ||
126 | policy->cur = omap_getspeed(policy->cpu); | ||
127 | -- | ||
128 | 1.6.6.1 | ||
129 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0013-OMAP2-cpufreq-only-supports-OPP-library.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0013-OMAP2-cpufreq-only-supports-OPP-library.patch new file mode 100644 index 00000000..71c4fe64 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0013-OMAP2-cpufreq-only-supports-OPP-library.patch | |||
@@ -0,0 +1,46 @@ | |||
1 | From 1e5757cbc79685c6294a178d1bea76a52cffcae9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nishanth Menon <nm@ti.com> | ||
3 | Date: Thu, 26 May 2011 19:39:18 -0700 | ||
4 | Subject: [PATCH 13/19] OMAP2+: cpufreq: only supports OPP library | ||
5 | |||
6 | OMAP2 is the only family using clk_[init|exit]_cpufreq_table, however, | ||
7 | the cpufreq code does not currently use clk_init_cpufreq_table. As a | ||
8 | result, it is unusuable for OMAP2 and only usable only on platforms | ||
9 | using OPP library. | ||
10 | |||
11 | Remove the unbalanced clk_exit_cpufreq_table(). Any platforms where | ||
12 | OPPs are not availble will fail on init because a freq table will not | ||
13 | be properly initialized. | ||
14 | |||
15 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
16 | [khilman@ti.com: changelog edits, and graceful failure mode changes] | ||
17 | Acked-by: Kevin Hilman <khilman@ti.com> | ||
18 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
19 | --- | ||
20 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 3 +-- | ||
21 | 1 files changed, 1 insertions(+), 2 deletions(-) | ||
22 | |||
23 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
24 | index acf18e8..3af7cda 100644 | ||
25 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
26 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
27 | @@ -1,7 +1,7 @@ | ||
28 | /* | ||
29 | * OMAP2PLUS cpufreq driver | ||
30 | * | ||
31 | - * CPU frequency scaling for OMAP | ||
32 | + * CPU frequency scaling for OMAP using OPP information | ||
33 | * | ||
34 | * Copyright (C) 2005 Nokia Corporation | ||
35 | * Written by Tony Lindgren <tony@atomide.com> | ||
36 | @@ -203,7 +203,6 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
37 | |||
38 | static int omap_cpu_exit(struct cpufreq_policy *policy) | ||
39 | { | ||
40 | - clk_exit_cpufreq_table(&freq_table); | ||
41 | clk_put(mpu_clk); | ||
42 | return 0; | ||
43 | } | ||
44 | -- | ||
45 | 1.6.6.1 | ||
46 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0014-OMAP2-cpufreq-put-clk-if-cpu_init-failed.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0014-OMAP2-cpufreq-put-clk-if-cpu_init-failed.patch new file mode 100644 index 00000000..fffbcc90 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0014-OMAP2-cpufreq-put-clk-if-cpu_init-failed.patch | |||
@@ -0,0 +1,61 @@ | |||
1 | From bec0338ead64cdd8515ae4c94462ffbfd6ae6418 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nishanth Menon <nm@ti.com> | ||
3 | Date: Thu, 26 May 2011 19:39:19 -0700 | ||
4 | Subject: [PATCH 14/19] OMAP2+: cpufreq: put clk if cpu_init failed | ||
5 | |||
6 | Release the mpu_clk in fail paths. | ||
7 | |||
8 | Reported-by: Todd Poynor <toddpoynor@google.com> | ||
9 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
10 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
11 | --- | ||
12 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 14 +++++++++++--- | ||
13 | 1 files changed, 11 insertions(+), 3 deletions(-) | ||
14 | |||
15 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
16 | index 3af7cda..e019297 100644 | ||
17 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
18 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
19 | @@ -162,8 +162,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
20 | if (IS_ERR(mpu_clk)) | ||
21 | return PTR_ERR(mpu_clk); | ||
22 | |||
23 | - if (policy->cpu >= NR_CPUS) | ||
24 | - return -EINVAL; | ||
25 | + if (policy->cpu >= NR_CPUS) { | ||
26 | + result = -EINVAL; | ||
27 | + goto fail_ck; | ||
28 | + } | ||
29 | |||
30 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); | ||
31 | result = opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
32 | @@ -171,12 +173,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
33 | if (result) { | ||
34 | dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n", | ||
35 | __func__, policy->cpu, result); | ||
36 | - return result; | ||
37 | + goto fail_ck; | ||
38 | } | ||
39 | |||
40 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
41 | if (!result) | ||
42 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
43 | + else | ||
44 | + goto fail_ck; | ||
45 | |||
46 | policy->min = policy->cpuinfo.min_freq; | ||
47 | policy->max = policy->cpuinfo.max_freq; | ||
48 | @@ -199,6 +203,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
49 | policy->cpuinfo.transition_latency = 300 * 1000; | ||
50 | |||
51 | return 0; | ||
52 | + | ||
53 | +fail_ck: | ||
54 | + clk_put(mpu_clk); | ||
55 | + return result; | ||
56 | } | ||
57 | |||
58 | static int omap_cpu_exit(struct cpufreq_policy *policy) | ||
59 | -- | ||
60 | 1.6.6.1 | ||
61 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0015-OMAP2-cpufreq-fix-freq_table-leak.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0015-OMAP2-cpufreq-fix-freq_table-leak.patch new file mode 100644 index 00000000..8257a17d --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0015-OMAP2-cpufreq-fix-freq_table-leak.patch | |||
@@ -0,0 +1,90 @@ | |||
1 | From 0054f5049a4e65a359eca6fa8c6668fb047c9270 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nishanth Menon <nm@ti.com> | ||
3 | Date: Thu, 26 May 2011 19:39:20 -0700 | ||
4 | Subject: [PATCH 15/19] OMAP2+: cpufreq: fix freq_table leak | ||
5 | |||
6 | We use a single frequency table for multiple CPUs. But, with | ||
7 | OMAP4, since we have multiple CPUs, the cpu_init call for CPU1 | ||
8 | causes freq_table previously allocated for CPU0 to be overwritten. | ||
9 | In addition, we dont free the table on exit path. | ||
10 | |||
11 | We solve this by maintaining an atomic type counter to ensure | ||
12 | just a single table exists at a given time. | ||
13 | |||
14 | Signed-off-by: Nishanth Menon <nm@ti.com> | ||
15 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
16 | --- | ||
17 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 22 +++++++++++++++++----- | ||
18 | 1 files changed, 17 insertions(+), 5 deletions(-) | ||
19 | |||
20 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
21 | index e019297..a962a31 100644 | ||
22 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
23 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
24 | @@ -39,6 +39,7 @@ | ||
25 | #include <mach/hardware.h> | ||
26 | |||
27 | static struct cpufreq_frequency_table *freq_table; | ||
28 | +static atomic_t freq_table_users = ATOMIC_INIT(0); | ||
29 | static struct clk *mpu_clk; | ||
30 | static char *mpu_clk_name; | ||
31 | static struct device *mpu_dev; | ||
32 | @@ -153,6 +154,12 @@ skip_lpj: | ||
33 | return ret; | ||
34 | } | ||
35 | |||
36 | +static inline void freq_table_free(void) | ||
37 | +{ | ||
38 | + if (atomic_dec_and_test(&freq_table_users)) | ||
39 | + opp_free_cpufreq_table(mpu_dev, &freq_table); | ||
40 | +} | ||
41 | + | ||
42 | static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
43 | { | ||
44 | int result = 0; | ||
45 | @@ -168,7 +175,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
46 | } | ||
47 | |||
48 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); | ||
49 | - result = opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
50 | + | ||
51 | + if (atomic_inc_return(&freq_table_users) == 1) | ||
52 | + result = opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
53 | |||
54 | if (result) { | ||
55 | dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n", | ||
56 | @@ -177,10 +186,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
57 | } | ||
58 | |||
59 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
60 | - if (!result) | ||
61 | - cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
62 | - else | ||
63 | - goto fail_ck; | ||
64 | + if (result) | ||
65 | + goto fail_table; | ||
66 | + | ||
67 | + cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
68 | |||
69 | policy->min = policy->cpuinfo.min_freq; | ||
70 | policy->max = policy->cpuinfo.max_freq; | ||
71 | @@ -204,6 +213,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
72 | |||
73 | return 0; | ||
74 | |||
75 | +fail_table: | ||
76 | + freq_table_free(); | ||
77 | fail_ck: | ||
78 | clk_put(mpu_clk); | ||
79 | return result; | ||
80 | @@ -211,6 +222,7 @@ fail_ck: | ||
81 | |||
82 | static int omap_cpu_exit(struct cpufreq_policy *policy) | ||
83 | { | ||
84 | + freq_table_free(); | ||
85 | clk_put(mpu_clk); | ||
86 | return 0; | ||
87 | } | ||
88 | -- | ||
89 | 1.6.6.1 | ||
90 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0016-OMAP2-CPUfreq-Remove-superfluous-check-in-target-for.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0016-OMAP2-CPUfreq-Remove-superfluous-check-in-target-for.patch new file mode 100644 index 00000000..478b7691 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0016-OMAP2-CPUfreq-Remove-superfluous-check-in-target-for.patch | |||
@@ -0,0 +1,58 @@ | |||
1 | From 255f1830ab71e130bbdffd84e61fc7a8c3791120 Mon Sep 17 00:00:00 2001 | ||
2 | From: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
3 | Date: Fri, 3 Jun 2011 17:46:57 +0530 | ||
4 | Subject: [PATCH 16/19] OMAP2+: CPUfreq: Remove superfluous check in target() for online CPU's. | ||
5 | |||
6 | Current OMAP2PLUS CPUfreq tagret() functions returns when all | ||
7 | the CPU's are not online. This breaks CPUfreq when secondary CPUs | ||
8 | are offlined on SMP system. | ||
9 | |||
10 | The intention of that check was just avoid CPU frequency change | ||
11 | during the window when CPU becomes online but it's cpufreq_init is | ||
12 | not done yet. Otherwise it can lead to notifiers being sent on | ||
13 | a CPU which is not yet registered to the governor. | ||
14 | |||
15 | But this race conditions is already managed by the CPUfreq | ||
16 | core driver by updating the available cpumask accordingly. | ||
17 | |||
18 | OMAP CPUFReq driver make use same cpumask for the notifiers | ||
19 | so the above problem doesn't exist. In my initial implementation | ||
20 | of the OMAP4 CPUFreq driver, I was using 'for_each_online_cpu()' | ||
21 | for notifiers which lead me to add that check. Later I fixed | ||
22 | the notifies but didn't realise that the check has become | ||
23 | redundant then. | ||
24 | |||
25 | Fix it by removing the superfluous check in target(). | ||
26 | |||
27 | Thanks for Nishant Menon <nm@ti.com> for reporting issue | ||
28 | with hot-plug and Kevin Hilman <khilman@ti.com> for his | ||
29 | comment on excessive check in target(). | ||
30 | |||
31 | Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
32 | Reported-by: Nishanth Menon <nm@ti.com> | ||
33 | Tested-by: Vishwanath BS <vishwanath.bs@ti.com> | ||
34 | Cc: Kevin Hilman <khilman@ti.com> | ||
35 | Tested-by: Nishanth Menon <nm@ti.com> | ||
36 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
37 | --- | ||
38 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 4 ---- | ||
39 | 1 files changed, 0 insertions(+), 4 deletions(-) | ||
40 | |||
41 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
42 | index a962a31..eaefa49 100644 | ||
43 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
44 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
45 | @@ -70,10 +70,6 @@ static int omap_target(struct cpufreq_policy *policy, | ||
46 | int ret = 0; | ||
47 | struct cpufreq_freqs freqs; | ||
48 | |||
49 | - /* Changes not allowed until all CPUs are online */ | ||
50 | - if (is_smp() && (num_online_cpus() < NR_CPUS)) | ||
51 | - return ret; | ||
52 | - | ||
53 | if (!freq_table) { | ||
54 | dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__, | ||
55 | policy->cpu); | ||
56 | -- | ||
57 | 1.6.6.1 | ||
58 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0017-OMAP2-cpufreq-notify-even-with-bad-boot-frequency.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0017-OMAP2-cpufreq-notify-even-with-bad-boot-frequency.patch new file mode 100644 index 00000000..42ca787a --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0017-OMAP2-cpufreq-notify-even-with-bad-boot-frequency.patch | |||
@@ -0,0 +1,48 @@ | |||
1 | From 3bf92d672cb3ee7c1ec39f1f0fcf6e8dbde2ceb9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Colin Cross <ccross@google.com> | ||
3 | Date: Mon, 6 Jun 2011 21:05:29 -0500 | ||
4 | Subject: [PATCH 17/19] OMAP2+: cpufreq: notify even with bad boot frequency | ||
5 | |||
6 | Sometimes, bootloaders starts up with a frequency which is not | ||
7 | in the OPP table. At cpu_init, policy->cur contains the frequency | ||
8 | we pick at boot. It is possible that system might have fixed | ||
9 | it's boot frequency later on as part of power initialization. | ||
10 | After this condition, the first call to omap_target results in the | ||
11 | following: | ||
12 | |||
13 | omap_getspeed(actual device frequency) != policy->cur(frequency that | ||
14 | cpufreq thinks that the system is at), and it is possible that | ||
15 | freqs.old == freqs.new (because the governor requested a scale down). | ||
16 | |||
17 | We exit without triggering the notifiers in the current code, which | ||
18 | does'nt let code which depends on cpufreq_notify_transition to have | ||
19 | accurate information as to what the system frequency is. | ||
20 | |||
21 | Instead, we do a normal transition if policy->cur is wrong, then, | ||
22 | freqs.old will be the actual cpu frequency, freqs.new will be the | ||
23 | actual new cpu frequency and all required notifiers have the accurate | ||
24 | information. | ||
25 | |||
26 | Acked-by: Nishanth Menon <nm@ti.com> | ||
27 | Signed-off-by: Colin Cross <ccross@google.com> | ||
28 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
29 | --- | ||
30 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 2 +- | ||
31 | 1 files changed, 1 insertions(+), 1 deletions(-) | ||
32 | |||
33 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
34 | index eaefa49..8598928 100644 | ||
35 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
36 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
37 | @@ -93,7 +93,7 @@ static int omap_target(struct cpufreq_policy *policy, | ||
38 | freqs.old = omap_getspeed(policy->cpu); | ||
39 | freqs.cpu = policy->cpu; | ||
40 | |||
41 | - if (freqs.old == freqs.new) | ||
42 | + if (freqs.old == freqs.new && policy->cur == freqs.new) | ||
43 | return ret; | ||
44 | |||
45 | if (!is_smp()) { | ||
46 | -- | ||
47 | 1.6.6.1 | ||
48 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0018-OMAP2-cpufreq-Enable-all-CPUs-in-shared-policy-mask.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0018-OMAP2-cpufreq-Enable-all-CPUs-in-shared-policy-mask.patch new file mode 100644 index 00000000..57cec0f1 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0018-OMAP2-cpufreq-Enable-all-CPUs-in-shared-policy-mask.patch | |||
@@ -0,0 +1,42 @@ | |||
1 | From 6e092f78e67d722be6036131df6aa0b8b2fec879 Mon Sep 17 00:00:00 2001 | ||
2 | From: Todd Poynor <toddpoynor@google.com> | ||
3 | Date: Tue, 7 Jun 2011 13:57:52 -0700 | ||
4 | Subject: [PATCH 18/19] OMAP2+: cpufreq: Enable all CPUs in shared policy mask | ||
5 | |||
6 | Enable all CPUs in the shared policy in the CPU init callback. | ||
7 | Otherwise, the governor CPUFREQ_GOV_START event is invoked with | ||
8 | a policy that only includes the first CPU, leaving other CPUs | ||
9 | uninitialized by the governor. | ||
10 | |||
11 | Signed-off-by: Todd Poynor <toddpoynor@google.com> | ||
12 | Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
13 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
14 | --- | ||
15 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 4 +--- | ||
16 | 1 files changed, 1 insertions(+), 3 deletions(-) | ||
17 | |||
18 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
19 | index 8598928..1f3b2e1 100644 | ||
20 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
21 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
22 | @@ -159,7 +159,6 @@ static inline void freq_table_free(void) | ||
23 | static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
24 | { | ||
25 | int result = 0; | ||
26 | - static cpumask_var_t cpumask; | ||
27 | |||
28 | mpu_clk = clk_get(NULL, mpu_clk_name); | ||
29 | if (IS_ERR(mpu_clk)) | ||
30 | @@ -200,8 +199,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | ||
31 | */ | ||
32 | if (is_smp()) { | ||
33 | policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; | ||
34 | - cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask); | ||
35 | - cpumask_copy(policy->cpus, cpumask); | ||
36 | + cpumask_setall(policy->cpus); | ||
37 | } | ||
38 | |||
39 | /* FIXME: what's the actual transition time? */ | ||
40 | -- | ||
41 | 1.6.6.1 | ||
42 | |||
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0019-OMAP2-CPUfreq-update-lpj-with-reference-value-to-avo.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0019-OMAP2-CPUfreq-update-lpj-with-reference-value-to-avo.patch new file mode 100644 index 00000000..b5f69d16 --- /dev/null +++ b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0019-OMAP2-CPUfreq-update-lpj-with-reference-value-to-avo.patch | |||
@@ -0,0 +1,121 @@ | |||
1 | From e8fa6ffc7822b7c7e81fafb112f3064f31c5c0e3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Russell King <rmk+kernel@arm.linux.org.uk> | ||
3 | Date: Mon, 11 Jul 2011 23:10:04 +0530 | ||
4 | Subject: [PATCH 19/19] OMAP2+: CPUfreq: update lpj with reference value to avoid progressive error. | ||
5 | |||
6 | Adjust _both_ the per-cpu loops_per_jiffy and global lpj. Calibrate them | ||
7 | with with reference to the initial values to avoid a progressively | ||
8 | bigger and bigger error in the value over time. | ||
9 | |||
10 | While at this, re-use the notifiers for UP/SMP since on | ||
11 | UP machine or UP_ON_SMP policy->cpus mask would contain only | ||
12 | the boot CPU. | ||
13 | |||
14 | Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
15 | [santosh.shilimkar@ti.com: re-based against omap cpufreq | ||
16 | upstream branch and fixed notifiers] | ||
17 | Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> | ||
18 | Cc: Kevin Hilman <khilman@ti.com> | ||
19 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
20 | --- | ||
21 | arch/arm/mach-omap2/omap2plus-cpufreq.c | 50 ++++++++++++++++-------------- | ||
22 | 1 files changed, 27 insertions(+), 23 deletions(-) | ||
23 | |||
24 | diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
25 | index 1f3b2e1..de82e87 100644 | ||
26 | --- a/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
27 | +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c | ||
28 | @@ -38,6 +38,16 @@ | ||
29 | |||
30 | #include <mach/hardware.h> | ||
31 | |||
32 | +#ifdef CONFIG_SMP | ||
33 | +struct lpj_info { | ||
34 | + unsigned long ref; | ||
35 | + unsigned int freq; | ||
36 | +}; | ||
37 | + | ||
38 | +static DEFINE_PER_CPU(struct lpj_info, lpj_ref); | ||
39 | +static struct lpj_info global_lpj_ref; | ||
40 | +#endif | ||
41 | + | ||
42 | static struct cpufreq_frequency_table *freq_table; | ||
43 | static atomic_t freq_table_users = ATOMIC_INIT(0); | ||
44 | static struct clk *mpu_clk; | ||
45 | @@ -96,37 +106,18 @@ static int omap_target(struct cpufreq_policy *policy, | ||
46 | if (freqs.old == freqs.new && policy->cur == freqs.new) | ||
47 | return ret; | ||
48 | |||
49 | - if (!is_smp()) { | ||
50 | - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
51 | - goto set_freq; | ||
52 | - } | ||
53 | - | ||
54 | /* notifiers */ | ||
55 | for_each_cpu(i, policy->cpus) { | ||
56 | freqs.cpu = i; | ||
57 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
58 | } | ||
59 | |||
60 | -set_freq: | ||
61 | #ifdef CONFIG_CPU_FREQ_DEBUG | ||
62 | pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); | ||
63 | #endif | ||
64 | |||
65 | ret = clk_set_rate(mpu_clk, freqs.new * 1000); | ||
66 | - | ||
67 | - /* | ||
68 | - * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies | ||
69 | - * won't get updated when UP machine cpufreq build with | ||
70 | - * CONFIG_SMP enabled. Below code is added only to manage that | ||
71 | - * scenario | ||
72 | - */ | ||
73 | freqs.new = omap_getspeed(policy->cpu); | ||
74 | - if (!is_smp()) { | ||
75 | - loops_per_jiffy = | ||
76 | - cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new); | ||
77 | - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
78 | - goto skip_lpj; | ||
79 | - } | ||
80 | |||
81 | #ifdef CONFIG_SMP | ||
82 | /* | ||
83 | @@ -134,10 +125,24 @@ set_freq: | ||
84 | * cpufreq driver. So, update the per-CPU loops_per_jiffy value | ||
85 | * on frequency transition. We need to update all dependent CPUs. | ||
86 | */ | ||
87 | - for_each_cpu(i, policy->cpus) | ||
88 | + for_each_cpu(i, policy->cpus) { | ||
89 | + struct lpj_info *lpj = &per_cpu(lpj_ref, i); | ||
90 | + if (!lpj->freq) { | ||
91 | + lpj->ref = per_cpu(cpu_data, i).loops_per_jiffy; | ||
92 | + lpj->freq = freqs.old; | ||
93 | + } | ||
94 | + | ||
95 | per_cpu(cpu_data, i).loops_per_jiffy = | ||
96 | - cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy, | ||
97 | - freqs.old, freqs.new); | ||
98 | + cpufreq_scale(lpj->ref, lpj->freq, freqs.new); | ||
99 | + } | ||
100 | + | ||
101 | + /* And don't forget to adjust the global one */ | ||
102 | + if (!global_lpj_ref.freq) { | ||
103 | + global_lpj_ref.ref = loops_per_jiffy; | ||
104 | + global_lpj_ref.freq = freqs.old; | ||
105 | + } | ||
106 | + loops_per_jiffy = cpufreq_scale(global_lpj_ref.ref, global_lpj_ref.freq, | ||
107 | + freqs.new); | ||
108 | #endif | ||
109 | |||
110 | /* notifiers */ | ||
111 | @@ -146,7 +151,6 @@ set_freq: | ||
112 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
113 | } | ||
114 | |||
115 | -skip_lpj: | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | -- | ||
120 | 1.6.6.1 | ||
121 | |||