summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-3.0/pm-wip
diff options
context:
space:
mode:
authorKoen Kooi <koen@dominion.thruhere.net>2011-07-20 14:41:45 +0200
committerKoen Kooi <koen@dominion.thruhere.net>2011-07-20 14:41:45 +0200
commite125e989fafda1faf6d3f5dc33e949cd7d4b5a97 (patch)
tree5359f8bbfa60493160ef883083f863fce5ea2fb4 /recipes-kernel/linux/linux-3.0/pm-wip
parent7018fe0a81fa33c6d73d6296d25517b5d427d0a7 (diff)
downloadmeta-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')
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0001-PM-OPP-introduce-function-to-free-cpufreq-table.patch84
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0002-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch28
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0003-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch32
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0004-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch264
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0005-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch33
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0006-cpufreq-fixup-after-new-OPP-layer-merged.patch34
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch673
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0008-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch171
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0009-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch30
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0010-OMAP2-cpufreq-move-clk-name-decision-to-init.patch64
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0011-OMAP2-cpufreq-deny-initialization-if-no-mpudev.patch64
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0012-OMAP2-cpufreq-dont-support-freq_table.patch129
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0013-OMAP2-cpufreq-only-supports-OPP-library.patch46
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0014-OMAP2-cpufreq-put-clk-if-cpu_init-failed.patch61
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0015-OMAP2-cpufreq-fix-freq_table-leak.patch90
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0016-OMAP2-CPUfreq-Remove-superfluous-check-in-target-for.patch58
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0017-OMAP2-cpufreq-notify-even-with-bad-boot-frequency.patch48
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0018-OMAP2-cpufreq-Enable-all-CPUs-in-shared-policy-mask.patch42
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0019-OMAP2-CPUfreq-update-lpj-with-reference-value-to-avo.patch121
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 @@
1From e029940bc6c0ff4ad3c8e2b4f31d0a3de78eff32 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Wed, 25 May 2011 00:43:26 -0700
4Subject: [PATCH 01/19] PM: OPP: introduce function to free cpufreq table
5
6cpufreq table allocated by opp_init_cpufreq_table is better
7freed by OPP layer itself. This allows future modifications to
8the table handling to be transparent to the users.
9
10Signed-off-by: Nishanth Menon <nm@ti.com>
11Acked-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
18diff --git a/Documentation/power/opp.txt b/Documentation/power/opp.txt
19index 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
31diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
32index 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 */
57diff --git a/include/linux/opp.h b/include/linux/opp.h
58index 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--
831.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 @@
1From 895fc8961297666b46b4cd3f8c01010051d2164e Mon Sep 17 00:00:00 2001
2From: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
3Date: Wed, 11 Aug 2010 17:02:43 -0700
4Subject: [PATCH 02/19] OMAP: CPUfreq: ensure driver initializes after cpufreq framework and governors
5
6Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
7Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
8Signed-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
13diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
14index 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--
271.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 @@
1From 62bd1b0f18ee6c6bad1573c2f06e74b0abc418a3 Mon Sep 17 00:00:00 2001
2From: Kevin Hilman <khilman@deeprootsystems.com>
3Date: Wed, 11 Aug 2010 17:05:38 -0700
4Subject: [PATCH 03/19] OMAP: CPUfreq: ensure policy is fully initialized
5
6Ensure policy min/max/cur values are initialized when OMAP
7CPUfreq driver starts.
8
9Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
10Signed-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
15diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
16index 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--
311.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 @@
1From afa9b062a33a9d9d2d9077cc519e1375b8338e39 Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Mon, 10 Nov 2008 17:00:25 +0530
4Subject: [PATCH 04/19] OMAP3 PM: CPUFreq driver for OMAP3
5
6CPUFreq driver for OMAP3
7
8With 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
12Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
13Signed-off-by: Rajendra Nayak <rnayak@ti.com>
14
15OMAP3: PM: CPUFreq: Fix omap_getspeed.
16
17Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
18
19Make sure omap cpufreq driver initializes after cpufreq framework and governors
20
21Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
22
23merge: CPUFreq: remove obsolete funcs
24
25OMAP3 clock: Update cpufreq driver
26
27This patch removes all refrences to virtual clock
28nodes in CPUFreq driver.
29
30Signed-off-by: Rajendra Nayak <rnayak@ti.com>
31Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
32Signed-off-by: Jean Pihet <jpihet@mvista.com>
33
34PM: Prevent direct cpufreq scaling during initialization
35
36It is seen that the OMAP specific cpufreq initialization code tries to
37scale the MPU frequency to the highest possible without taking care of
38the voltage level. On power on reset the power IC does not provide the
39necessary voltage for the highest available MPU frequency (that would
40satisfy all Si families). This potentially is an window of opportunity
41for things to go wrong.
42
43Signed-off-by: Romit Dasgupta <romit@ti.com>
44Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
45
46OMAP3: PM: enable 600MHz (overdrive) OPP
47
48Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
49
50omap3: introduce cpufreq
51
52OMAP OPP layer functions now have dependencies of CONFIG_CPU_FREQ only.
53
54With this patch, omap opp layer now has its compilation flags
55bound to CONFIG_CPU_FREQ. Also its code has been removed from pm34xx.c.
56
57A new file has been created to contain cpu freq code related to
58OMAP3: cpufreq34xx.c
59
60OMAP34xx and OMAP36xx family OPPs are made available
61
62Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com>
63Signed-off-by: Paul Walmsley <paul@pwsan.com>
64Signed-off-by: Nishanth Menon <nm@ti.com>
65Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
66Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
67Signed-off-by: Romit Dasgupta <romit@ti.com>
68Signed-off-by: Rajendra Nayak <rnayak@ti.com>
69
70omap3: cpufreq: allow default opp table init
71
72For board files which choose to override the defaults, the existing
73mechanism will work, for boards that would like to work with defaults,
74allow init_common_hw to call init_opp_table to initialize if not
75already initialized. this will allow all omap boards which have opp
76tables predefined for a silicon to use the same.
77
78Originally reported for overo:
79http://marc.info/?t=127265269400004&r=1&w=2
80
81Signed-off-by: Nishanth Menon <nm@ti.com>
82Reported-by: Peter Tseng <tsenpet09@gmail.com>
83Cc: Cliff Brake <cliff.brake@gmail.com>
84Cc: Kevin Hilman <khilman@deeprootsystems.com>
85
86OMAP2: update OPP data to be device based
87
88Cc: Nishanth Menon <nm@ti.com>
89Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
90
91OMAP3: CPUfreq: update to device-based OPP API
92
93Update usage of OPP API to use new device-based API. This requires
94getting the 'struct device' for the MPU and using that with the OPP
95API.
96
97Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
98
99omap3: opp: make independent of cpufreq
100
101Make opp3xx data which is registered with the opp layer
102dependent purely on CONFIG_PM as opp layer and pm.c users
103are CONFIG_PM dependent not cpufreq dependent.
104so we rename the data definition to opp3xxx_data.c (inline with what
105we have for omap2), also move the build definition to be under
106the existing CONFIG_PM build instead of CPUFREQ.
107
108Cc: Eduardo Valentin <eduardo.valentin@nokia.com>
109Cc: Kevin Hilman <khilman@deeprootsystems.com>
110Cc: Paul Walmsley <paul@pwsan.com>
111Cc: Rajendra Nayak <rnayak@ti.com>
112Cc: Sanjeev Premi <premi@ti.com>
113Cc: Thara Gopinath <thara@ti.com>
114Cc: Tony Lindgren <tony@atomide.com>
115
116Signed-off-by: Nishanth Menon <nm@ti.com>
117Signed-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
124diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
125index 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;
156diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
157index 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
169diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
170index 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--
2631.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 @@
1From c93327d36f0dc4ea6693fcae54c561eb8bafdd1e Mon Sep 17 00:00:00 2001
2From: Silesh C V <silesh@ti.com>
3Date: Wed, 29 Sep 2010 14:52:54 +0530
4Subject: [PATCH 05/19] OMAP: PM: CPUFREQ: Fix conditional compilation
5
6Fix conditional compilation. A conditional expresiion
7should follow "#elif", in this case #elif clause should
8check whether CONFIG_ARCH_OMAP3 is defined or not
9(ie. defined(CONFIG_ARCH_OMAP3)) rather than checking for
10the value of the macro.
11
12Signed-off-by: Silesh C V <silesh@ti.com>
13Signed-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
18diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
19index 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--
321.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 @@
1From b8246b5d5edc98155628ba88510bc7e67baf7acf Mon Sep 17 00:00:00 2001
2From: Kevin Hilman <khilman@deeprootsystems.com>
3Date: Tue, 16 Nov 2010 11:48:41 -0800
4Subject: [PATCH 06/19] cpufreq: fixup after new OPP layer merged
5
6Signed-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
11diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
12index 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--
331.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 @@
1From 9f9061d3e98aa6db7d5c3feabd5a2d93eb3cb737 Mon Sep 17 00:00:00 2001
2From: Santosh Shilimkar <santosh.shilimkar@ti.com>
3Date: Mon, 14 Mar 2011 17:08:48 +0530
4Subject: [PATCH 07/19] OMAP: cpufreq: Split OMAP1 and OMAP2PLUS CPUfreq drivers.
5
6This patch is an attempt to cleanup the #ifdeferry in the
7omap CPUfreq drivers.
8
9The split betwenn OMAP1 and OMAP2PLUS is logical because
10 - OMAP1 doesn't support opp layer.
11 - OMAP1 build is seperate from omap2plus.
12
13Includes minor header/copyright updates reported by Todd Poynor.
14
15Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
16Cc: Kevin Hilman <khilman@ti.com>
17Cc: Vishwanath BS <vishwanath.bs@ti.com>
18Cc: Todd Poynor <toddpoynor@google.com>
19Cc: Nishanth Menon <nm@ti.com>
20Signed-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
33diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
34index 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
47diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c
48new file mode 100644
49index 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);
228diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
229index 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
242diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
243new file mode 100644
244index 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);
449diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
450index 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
461diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
462deleted file mode 100644
463index 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--
6721.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 @@
1From f5dc16c8178d0c0bcad795f8ebc71934c4028472 Mon Sep 17 00:00:00 2001
2From: Santosh Shilimkar <santosh.shilimkar@ti.com>
3Date: Mon, 14 Mar 2011 17:08:49 +0530
4Subject: [PATCH 08/19] OMAP2PLUS: cpufreq: Add SMP support to cater OMAP4430
5
6On OMAP SMP configuartion, both processors share the voltage
7and clock. So both CPUs needs to be scaled together and hence
8needs software co-ordination.
9
10Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
11Cc: Kevin Hilman <khilman@ti.com>
12cc: Vishwanath BS <vishwanath.bs@ti.com>
13Signed-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
18diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
19index 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--
1701.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 @@
1From 07367b4c3afd8e881c4cf50ef35d081c4ac252b8 Mon Sep 17 00:00:00 2001
2From: Jarkko Nikula <jhnikula@gmail.com>
3Date: Thu, 14 Apr 2011 16:21:58 +0300
4Subject: [PATCH 09/19] OMAP2PLUS: cpufreq: Fix typo when attempting to set mpu_clk for OMAP4
5
6Fix this typo as there is no dpll_mpu_ck for OMAP3 and code flow is clearly
7trying to set mpu_clk for OMAP4 for which this dpll_mpu_ck is available.
8
9Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
10Signed-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
15diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
16index 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--
291.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 @@
1From 4d3e024c2f7f0334874bbb2a168b62e91cb2517a Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Wed, 25 May 2011 16:38:46 -0700
4Subject: [PATCH 10/19] OMAP2+: cpufreq: move clk name decision to init
5
6Clk name does'nt need to dynamically detected during clk init.
7move them off to driver initialization, if we dont have a clk name,
8there is no point in registering the driver anyways. The actual clk
9get and put is left at cpu_init and exit functions.
10
11Signed-off-by: Nishanth Menon <nm@ti.com>
12Signed-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
17diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
18index 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--
631.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 @@
1From 85afa12ad2a6e7a23ddf4b25e78e0ce5b9f18a64 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Wed, 25 May 2011 16:38:47 -0700
4Subject: [PATCH 11/19] OMAP2+: cpufreq: deny initialization if no mpudev
5
6if we do not have mpu_dev we normally fail in cpu_init. It is better
7to fail driver registration if the devices are not available.
8
9Signed-off-by: Nishanth Menon <nm@ti.com>
10Signed-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
15diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
16index 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--
631.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 @@
1From 345f93655f425c87ba01e949dc038e04542d8cd4 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Thu, 26 May 2011 19:39:17 -0700
4Subject: [PATCH 12/19] OMAP2+: cpufreq: dont support !freq_table
5
6OMAP2+ all have frequency tables, hence the hacks we had for older
7silicon do not need to be carried forward. As part of this change,
8use cpufreq_frequency_table_target to find the best match for
9frequency requested.
10
11Signed-off-by: Nishanth Menon <nm@ti.com>
12Signed-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
17diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
18index 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--
1281.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 @@
1From 1e5757cbc79685c6294a178d1bea76a52cffcae9 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Thu, 26 May 2011 19:39:18 -0700
4Subject: [PATCH 13/19] OMAP2+: cpufreq: only supports OPP library
5
6OMAP2 is the only family using clk_[init|exit]_cpufreq_table, however,
7the cpufreq code does not currently use clk_init_cpufreq_table. As a
8result, it is unusuable for OMAP2 and only usable only on platforms
9using OPP library.
10
11Remove the unbalanced clk_exit_cpufreq_table(). Any platforms where
12OPPs are not availble will fail on init because a freq table will not
13be properly initialized.
14
15Signed-off-by: Nishanth Menon <nm@ti.com>
16[khilman@ti.com: changelog edits, and graceful failure mode changes]
17Acked-by: Kevin Hilman <khilman@ti.com>
18Signed-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
23diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
24index 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--
451.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 @@
1From bec0338ead64cdd8515ae4c94462ffbfd6ae6418 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Thu, 26 May 2011 19:39:19 -0700
4Subject: [PATCH 14/19] OMAP2+: cpufreq: put clk if cpu_init failed
5
6Release the mpu_clk in fail paths.
7
8Reported-by: Todd Poynor <toddpoynor@google.com>
9Signed-off-by: Nishanth Menon <nm@ti.com>
10Signed-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
15diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
16index 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--
601.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 @@
1From 0054f5049a4e65a359eca6fa8c6668fb047c9270 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Thu, 26 May 2011 19:39:20 -0700
4Subject: [PATCH 15/19] OMAP2+: cpufreq: fix freq_table leak
5
6We use a single frequency table for multiple CPUs. But, with
7OMAP4, since we have multiple CPUs, the cpu_init call for CPU1
8causes freq_table previously allocated for CPU0 to be overwritten.
9In addition, we dont free the table on exit path.
10
11We solve this by maintaining an atomic type counter to ensure
12just a single table exists at a given time.
13
14Signed-off-by: Nishanth Menon <nm@ti.com>
15Signed-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
20diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
21index 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--
891.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 @@
1From 255f1830ab71e130bbdffd84e61fc7a8c3791120 Mon Sep 17 00:00:00 2001
2From: Santosh Shilimkar <santosh.shilimkar@ti.com>
3Date: Fri, 3 Jun 2011 17:46:57 +0530
4Subject: [PATCH 16/19] OMAP2+: CPUfreq: Remove superfluous check in target() for online CPU's.
5
6Current OMAP2PLUS CPUfreq tagret() functions returns when all
7the CPU's are not online. This breaks CPUfreq when secondary CPUs
8are offlined on SMP system.
9
10The intention of that check was just avoid CPU frequency change
11during the window when CPU becomes online but it's cpufreq_init is
12not done yet. Otherwise it can lead to notifiers being sent on
13a CPU which is not yet registered to the governor.
14
15But this race conditions is already managed by the CPUfreq
16core driver by updating the available cpumask accordingly.
17
18OMAP CPUFReq driver make use same cpumask for the notifiers
19so the above problem doesn't exist. In my initial implementation
20of the OMAP4 CPUFreq driver, I was using 'for_each_online_cpu()'
21for notifiers which lead me to add that check. Later I fixed
22the notifies but didn't realise that the check has become
23redundant then.
24
25Fix it by removing the superfluous check in target().
26
27Thanks for Nishant Menon <nm@ti.com> for reporting issue
28with hot-plug and Kevin Hilman <khilman@ti.com> for his
29comment on excessive check in target().
30
31Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
32Reported-by: Nishanth Menon <nm@ti.com>
33Tested-by: Vishwanath BS <vishwanath.bs@ti.com>
34Cc: Kevin Hilman <khilman@ti.com>
35Tested-by: Nishanth Menon <nm@ti.com>
36Signed-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
41diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
42index 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--
571.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 @@
1From 3bf92d672cb3ee7c1ec39f1f0fcf6e8dbde2ceb9 Mon Sep 17 00:00:00 2001
2From: Colin Cross <ccross@google.com>
3Date: Mon, 6 Jun 2011 21:05:29 -0500
4Subject: [PATCH 17/19] OMAP2+: cpufreq: notify even with bad boot frequency
5
6Sometimes, bootloaders starts up with a frequency which is not
7in the OPP table. At cpu_init, policy->cur contains the frequency
8we pick at boot. It is possible that system might have fixed
9it's boot frequency later on as part of power initialization.
10After this condition, the first call to omap_target results in the
11following:
12
13omap_getspeed(actual device frequency) != policy->cur(frequency that
14cpufreq thinks that the system is at), and it is possible that
15freqs.old == freqs.new (because the governor requested a scale down).
16
17We exit without triggering the notifiers in the current code, which
18does'nt let code which depends on cpufreq_notify_transition to have
19accurate information as to what the system frequency is.
20
21Instead, we do a normal transition if policy->cur is wrong, then,
22freqs.old will be the actual cpu frequency, freqs.new will be the
23actual new cpu frequency and all required notifiers have the accurate
24information.
25
26Acked-by: Nishanth Menon <nm@ti.com>
27Signed-off-by: Colin Cross <ccross@google.com>
28Signed-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
33diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
34index 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--
471.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 @@
1From 6e092f78e67d722be6036131df6aa0b8b2fec879 Mon Sep 17 00:00:00 2001
2From: Todd Poynor <toddpoynor@google.com>
3Date: Tue, 7 Jun 2011 13:57:52 -0700
4Subject: [PATCH 18/19] OMAP2+: cpufreq: Enable all CPUs in shared policy mask
5
6Enable all CPUs in the shared policy in the CPU init callback.
7Otherwise, the governor CPUFREQ_GOV_START event is invoked with
8a policy that only includes the first CPU, leaving other CPUs
9uninitialized by the governor.
10
11Signed-off-by: Todd Poynor <toddpoynor@google.com>
12Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
13Signed-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
18diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
19index 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--
411.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 @@
1From e8fa6ffc7822b7c7e81fafb112f3064f31c5c0e3 Mon Sep 17 00:00:00 2001
2From: Russell King <rmk+kernel@arm.linux.org.uk>
3Date: Mon, 11 Jul 2011 23:10:04 +0530
4Subject: [PATCH 19/19] OMAP2+: CPUfreq: update lpj with reference value to avoid progressive error.
5
6Adjust _both_ the per-cpu loops_per_jiffy and global lpj. Calibrate them
7with with reference to the initial values to avoid a progressively
8bigger and bigger error in the value over time.
9
10While at this, re-use the notifiers for UP/SMP since on
11UP machine or UP_ON_SMP policy->cpus mask would contain only
12the boot CPU.
13
14Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
15[santosh.shilimkar@ti.com: re-based against omap cpufreq
16upstream branch and fixed notifiers]
17Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
18Cc: Kevin Hilman <khilman@ti.com>
19Signed-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
24diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
25index 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--
1201.6.6.1
121