summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch170
1 files changed, 170 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch
new file mode 100644
index 00000000..6624d1ec
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch
@@ -0,0 +1,170 @@
1From f375d3c39d2835929d34c2a046b8c43cea6d1467 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 7/8] 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>
13---
14 arch/arm/mach-omap2/omap2plus-cpufreq.c | 73 ++++++++++++++++++++++++++-----
15 1 files changed, 62 insertions(+), 11 deletions(-)
16
17diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
18index 14f84cc..8d472f6 100644
19--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
20+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
21@@ -26,9 +26,11 @@
22 #include <linux/clk.h>
23 #include <linux/io.h>
24 #include <linux/opp.h>
25+#include <linux/cpu.h>
26
27 #include <asm/system.h>
28 #include <asm/smp_plat.h>
29+#include <asm/cpu.h>
30
31 #include <plat/clock.h>
32 #include <plat/omap-pm.h>
33@@ -63,7 +65,7 @@ static unsigned int omap_getspeed(unsigned int cpu)
34 {
35 unsigned long rate;
36
37- if (cpu)
38+ if (cpu >= NR_CPUS)
39 return 0;
40
41 rate = clk_get_rate(mpu_clk) / 1000;
42@@ -74,9 +76,13 @@ static int omap_target(struct cpufreq_policy *policy,
43 unsigned int target_freq,
44 unsigned int relation)
45 {
46- int ret = 0;
47+ int i, ret = 0;
48 struct cpufreq_freqs freqs;
49
50+ /* Changes not allowed until all CPUs are online */
51+ if (is_smp() && (num_online_cpus() < NR_CPUS))
52+ return ret;
53+
54 /* Ensure desired rate is within allowed range. Some govenors
55 * (ondemand) will just pass target_freq=0 to get the minimum. */
56 if (target_freq < policy->min)
57@@ -84,15 +90,25 @@ static int omap_target(struct cpufreq_policy *policy,
58 if (target_freq > policy->max)
59 target_freq = policy->max;
60
61- freqs.old = omap_getspeed(0);
62+ freqs.old = omap_getspeed(policy->cpu);
63 freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
64- freqs.cpu = 0;
65+ freqs.cpu = policy->cpu;
66
67 if (freqs.old == freqs.new)
68 return ret;
69
70- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
71+ if (!is_smp()) {
72+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
73+ goto set_freq;
74+ }
75+
76+ /* notifiers */
77+ for_each_cpu(i, policy->cpus) {
78+ freqs.cpu = i;
79+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
80+ }
81
82+set_freq:
83 #ifdef CONFIG_CPU_FREQ_DEBUG
84 pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
85 #endif
86@@ -105,12 +121,33 @@ static int omap_target(struct cpufreq_policy *policy,
87 * CONFIG_SMP enabled. Below code is added only to manage that
88 * scenario
89 */
90- if (!is_smp())
91+ freqs.new = omap_getspeed(policy->cpu);
92+ if (!is_smp()) {
93 loops_per_jiffy =
94 cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
95+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
96+ goto skip_lpj;
97+ }
98
99- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
100+#ifdef CONFIG_SMP
101+ /*
102+ * Note that loops_per_jiffy is not updated on SMP systems in
103+ * cpufreq driver. So, update the per-CPU loops_per_jiffy value
104+ * on frequency transition. We need to update all dependent CPUs.
105+ */
106+ for_each_cpu(i, policy->cpus)
107+ per_cpu(cpu_data, i).loops_per_jiffy =
108+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
109+ freqs.old, freqs.new);
110+#endif
111
112+ /* notifiers */
113+ for_each_cpu(i, policy->cpus) {
114+ freqs.cpu = i;
115+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
116+ }
117+
118+skip_lpj:
119 return ret;
120 }
121
122@@ -118,6 +155,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
123 {
124 int result = 0;
125 struct device *mpu_dev;
126+ static cpumask_var_t cpumask;
127
128 if (cpu_is_omap24xx())
129 mpu_clk = clk_get(NULL, "virt_prcm_set");
130@@ -129,12 +167,12 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
131 if (IS_ERR(mpu_clk))
132 return PTR_ERR(mpu_clk);
133
134- if (policy->cpu != 0)
135+ if (policy->cpu >= NR_CPUS)
136 return -EINVAL;
137
138- policy->cur = policy->min = policy->max = omap_getspeed(0);
139-
140+ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
141 mpu_dev = omap2_get_mpuss_device();
142+
143 if (!mpu_dev) {
144 pr_warning("%s: unable to get the mpu device\n", __func__);
145 return -EINVAL;
146@@ -154,7 +192,20 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
147
148 policy->min = policy->cpuinfo.min_freq;
149 policy->max = policy->cpuinfo.max_freq;
150- policy->cur = omap_getspeed(0);
151+ policy->cur = omap_getspeed(policy->cpu);
152+
153+ /*
154+ * On OMAP SMP configuartion, both processors share the voltage
155+ * and clock. So both CPUs needs to be scaled together and hence
156+ * needs software co-ordination. Use cpufreq affected_cpus
157+ * interface to handle this scenario. Additional is_smp() check
158+ * is to keep SMP_ON_UP build working.
159+ */
160+ if (is_smp()) {
161+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
162+ cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
163+ cpumask_copy(policy->cpus, cpumask);
164+ }
165
166 /* FIXME: what's the actual transition time? */
167 policy->cpuinfo.transition_latency = 300 * 1000;
168--
1691.6.6.1
170