summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-2.6.39/pm
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-2.6.39/pm')
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch38
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch44
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch33
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch48
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch78
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch100
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch134
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch879
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch27
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch31
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch263
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch32
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch33
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch669
-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
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch29
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch77
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch86
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch35
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch50
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch46
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch33
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch30
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch41
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch30
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch36
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch66
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch29
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch48
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch57
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch48
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch37
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch41
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch49
34 files changed, 3447 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch
new file mode 100644
index 00000000..9e9a8a0b
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch
@@ -0,0 +1,38 @@
1From 38dd5aadc86725f6018d23679e9daa60ca0a8319 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Thu, 12 May 2011 07:59:52 -0500
4Subject: [PATCH 1/6] OMAP2+: cpufreq: free up table on exit
5
6freq_table allocated by opp_init_cpufreq_table in omap_cpu_init
7needs to be freed in omap_cpu_exit.
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 | 3 +++
13 1 files changed, 3 insertions(+), 0 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
16index d53ce23..e38ebb8 100644
17--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
18+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
19@@ -26,6 +26,7 @@
20 #include <linux/clk.h>
21 #include <linux/io.h>
22 #include <linux/opp.h>
23+#include <linux/slab.h>
24 #include <linux/cpu.h>
25
26 #include <asm/system.h>
27@@ -216,6 +217,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
28 static int omap_cpu_exit(struct cpufreq_policy *policy)
29 {
30 clk_exit_cpufreq_table(&freq_table);
31+ kfree(freq_table);
32+ freq_table = NULL;
33 clk_put(mpu_clk);
34 return 0;
35 }
36--
371.6.6.1
38
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch
new file mode 100644
index 00000000..087724d1
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch
@@ -0,0 +1,44 @@
1From 5febdc0482e545c2a598f035c5e03931e0c3c808 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Thu, 12 May 2011 08:14:41 -0500
4Subject: [PATCH 2/6] OMAP2+: cpufreq: handle invalid cpufreq table
5
6Handle the case when cpufreq_frequency_table_cpuinfo fails. freq_table
7that we passed failed the internal test of cpufreq generic driver,
8so we should'nt be using the freq_table as such. Instead, warn and
9fallback to clock functions for validation and operation.
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 | 12 ++++++++++--
15 1 files changed, 10 insertions(+), 2 deletions(-)
16
17diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
18index e38ebb8..6e3666a 100644
19--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
20+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
21@@ -182,10 +182,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
22
23 if (freq_table) {
24 result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
25- if (!result)
26+ if (!result) {
27 cpufreq_frequency_table_get_attr(freq_table,
28 policy->cpu);
29- } else {
30+ } else {
31+ WARN(true, "%s: fallback to clk_round(freq_table=%d)\n",
32+ __func__, result);
33+ kfree(freq_table);
34+ freq_table = NULL;
35+ }
36+ }
37+
38+ if (!freq_table) {
39 policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
40 policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
41 VERY_HI_RATE) / 1000;
42--
431.6.6.1
44
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch
new file mode 100644
index 00000000..4f4cdb14
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch
@@ -0,0 +1,33 @@
1From aef7e862873e6125159a18d22a2e37b1fbab2153 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Thu, 12 May 2011 16:27:45 -0700
4Subject: [PATCH 3/6] OMAP2+: cpufreq: minor comment cleanup
5
6this should probably get squashed in..
7
8Signed-off-by: Nishanth Menon <nm@ti.com>
9Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
10---
11 arch/arm/mach-omap2/omap2plus-cpufreq.c | 6 ++++--
12 1 files changed, 4 insertions(+), 2 deletions(-)
13
14diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
15index 6e3666a..45f1e9e 100644
16--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
17+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
18@@ -84,8 +84,10 @@ static int omap_target(struct cpufreq_policy *policy,
19 if (is_smp() && (num_online_cpus() < NR_CPUS))
20 return ret;
21
22- /* Ensure desired rate is within allowed range. Some govenors
23- * (ondemand) will just pass target_freq=0 to get the minimum. */
24+ /*
25+ * Ensure desired rate is within allowed range. Some govenors
26+ * (ondemand) will just pass target_freq=0 to get the minimum.
27+ */
28 if (target_freq < policy->min)
29 target_freq = policy->min;
30 if (target_freq > policy->max)
31--
321.6.6.1
33
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch
new file mode 100644
index 00000000..dd23c082
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch
@@ -0,0 +1,48 @@
1From f231980dbd0f05229f2020e59b7242872576416f Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Fri, 13 May 2011 05:34:35 -0700
4Subject: [PATCH 4/6] OMAP2: cpufreq: use clk_init_cpufreq_table if OPPs not available
5
6OMAP2 does not use OPP tables at the moment for DVFS. Currently,
7we depend on opp table initialization to give us the freq_table,
8which makes sense for OMAP3+. for OMAP2, we should be using
9clk_init_cpufreq_table - so if the opp based frequency table
10initilization fails, fall back to clk_init_cpufreq_table to give
11us the table.
12
13Signed-off-by: Nishanth Menon <nm@ti.com>
14Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
15---
16 arch/arm/mach-omap2/omap2plus-cpufreq.c | 9 ++++++++-
17 1 files changed, 8 insertions(+), 1 deletions(-)
18
19diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
20index 45f1e9e..854f4b3 100644
21--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
22+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
23@@ -180,7 +180,13 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
24 pr_warning("%s: unable to get the mpu device\n", __func__);
25 return -EINVAL;
26 }
27- opp_init_cpufreq_table(mpu_dev, &freq_table);
28+
29+ /*
30+ * if we dont get cpufreq table using opp, use traditional omap2 lookup
31+ * as a fallback
32+ */
33+ if (opp_init_cpufreq_table(mpu_dev, &freq_table))
34+ clk_init_cpufreq_table(&freq_table);
35
36 if (freq_table) {
37 result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
38@@ -188,6 +194,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
39 cpufreq_frequency_table_get_attr(freq_table,
40 policy->cpu);
41 } else {
42+ clk_exit_cpufreq_table(&freq_table);
43 WARN(true, "%s: fallback to clk_round(freq_table=%d)\n",
44 __func__, result);
45 kfree(freq_table);
46--
471.6.6.1
48
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch
new file mode 100644
index 00000000..504d1916
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch
@@ -0,0 +1,78 @@
1From 272d76bcb22b9509ccc1b59d3a62e3930d902d17 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Fri, 13 May 2011 05:43:49 -0700
4Subject: [PATCH 5/6] OMAP2+: cpufreq: use cpufreq_frequency_table_target
5
6Use cpufreq_frequency_table_target for finding the proper target
7instead of seeing if the frequency requested is divisible alone.
8if we have a frequency table, we should restrict ourselves to
9selecting the "approved" frequencies alone and only in the case
10where the frequency table is not available should we attempt at
11closest roundable clock frequency.
12
13Signed-off-by: Nishanth Menon <nm@ti.com>
14Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
15---
16 arch/arm/mach-omap2/omap2plus-cpufreq.c | 38 ++++++++++++++++++++++--------
17 1 files changed, 28 insertions(+), 10 deletions(-)
18
19diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
20index 854f4b3..d0b4f97 100644
21--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
22+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
23@@ -77,24 +77,42 @@ static int omap_target(struct cpufreq_policy *policy,
24 unsigned int target_freq,
25 unsigned int relation)
26 {
27- int i, ret = 0;
28+ unsigned int i;
29+ int ret = 0;
30 struct cpufreq_freqs freqs;
31
32 /* Changes not allowed until all CPUs are online */
33 if (is_smp() && (num_online_cpus() < NR_CPUS))
34 return ret;
35
36- /*
37- * Ensure desired rate is within allowed range. Some govenors
38- * (ondemand) will just pass target_freq=0 to get the minimum.
39- */
40- if (target_freq < policy->min)
41- target_freq = policy->min;
42- if (target_freq > policy->max)
43- target_freq = policy->max;
44+ if (freq_table) {
45+ ret = cpufreq_frequency_table_target(policy, freq_table,
46+ target_freq, relation, &i);
47+ if (ret) {
48+ pr_debug("%s: cpu%d: no freq match for %d(ret=%d)\n",
49+ __func__, policy->cpu, target_freq, ret);
50+ return ret;
51+ }
52+ freqs.new = freq_table[i].frequency;
53+ } else {
54+ /*
55+ * Ensure desired rate is within allowed range. Some govenors
56+ * (ondemand) will just pass target_freq=0 to get the minimum.
57+ */
58+ if (target_freq < policy->min)
59+ target_freq = policy->min;
60+ if (target_freq > policy->max)
61+ target_freq = policy->max;
62+
63+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
64+ }
65+ if (!freqs.new) {
66+ pr_err("%s: cpu%d: no match for freq %d\n", __func__,
67+ policy->cpu, target_freq);
68+ return -EINVAL;
69+ }
70
71 freqs.old = omap_getspeed(policy->cpu);
72- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
73 freqs.cpu = policy->cpu;
74
75 if (freqs.old == freqs.new)
76--
771.6.6.1
78
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch
new file mode 100644
index 00000000..0cb4c91f
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch
@@ -0,0 +1,100 @@
1From 42a384af80e07534913d9002ec8d9caf5d4d305c Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Wed, 18 May 2011 01:48:23 -0500
4Subject: [PATCH 6/6] OMAP2+: cpufreq: fix freq_table leak
5
6Since we have two cpus the cpuinit call for cpu1 causes
7freq_table of cpu0 to be overwritten. instead, we maintain
8a counter to keep track of cpus who use the cpufreq table
9allocate it once(one freq table for all CPUs) and free them
10once the last user is done with it.
11
12Signed-off-by: Nishanth Menon <nm@ti.com>
13Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
14---
15 arch/arm/mach-omap2/omap2plus-cpufreq.c | 33 ++++++++++++++++++++++++------
16 1 files changed, 26 insertions(+), 7 deletions(-)
17
18diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
19index d0b4f97..fc3d0fb 100644
20--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
21+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
22@@ -42,6 +42,9 @@
23 #define VERY_HI_RATE 900000000
24
25 static struct cpufreq_frequency_table *freq_table;
26+static int freq_table_users;
27+static DEFINE_MUTEX(freq_table_lock);
28+
29 static struct clk *mpu_clk;
30
31 static int omap_verify_speed(struct cpufreq_policy *policy)
32@@ -172,6 +175,18 @@ skip_lpj:
33 return ret;
34 }
35
36+static void freq_table_free(void)
37+{
38+ if (!freq_table_users)
39+ return;
40+ freq_table_users--;
41+ if (freq_table_users)
42+ return;
43+ clk_exit_cpufreq_table(&freq_table);
44+ kfree(freq_table);
45+ freq_table = NULL;
46+}
47+
48 static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
49 {
50 int result = 0;
51@@ -199,14 +214,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
52 return -EINVAL;
53 }
54
55+ mutex_lock(&freq_table_lock);
56 /*
57 * if we dont get cpufreq table using opp, use traditional omap2 lookup
58 * as a fallback
59 */
60- if (opp_init_cpufreq_table(mpu_dev, &freq_table))
61- clk_init_cpufreq_table(&freq_table);
62+ if (!freq_table) {
63+ if (opp_init_cpufreq_table(mpu_dev, &freq_table))
64+ clk_init_cpufreq_table(&freq_table);
65+ }
66
67 if (freq_table) {
68+ freq_table_users++;
69 result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
70 if (!result) {
71 cpufreq_frequency_table_get_attr(freq_table,
72@@ -215,10 +234,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
73 clk_exit_cpufreq_table(&freq_table);
74 WARN(true, "%s: fallback to clk_round(freq_table=%d)\n",
75 __func__, result);
76- kfree(freq_table);
77- freq_table = NULL;
78+ freq_table_free();
79 }
80 }
81+ mutex_unlock(&freq_table_lock);
82
83 if (!freq_table) {
84 policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
85@@ -251,9 +270,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
86
87 static int omap_cpu_exit(struct cpufreq_policy *policy)
88 {
89- clk_exit_cpufreq_table(&freq_table);
90- kfree(freq_table);
91- freq_table = NULL;
92+ mutex_lock(&freq_table_lock);
93+ freq_table_free();
94+ mutex_unlock(&freq_table_lock);
95 clk_put(mpu_clk);
96 return 0;
97 }
98--
991.6.6.1
100
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch
new file mode 100644
index 00000000..576cd08f
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch
@@ -0,0 +1,134 @@
1From 8726f3a7218b72a1003904a24bb000b3e4f9b4d1 Mon Sep 17 00:00:00 2001
2From: Mike Turquette <mturquette@ti.com>
3Date: Tue, 17 May 2011 09:35:54 -0500
4Subject: [PATCH 1/2] cpufreq: helpers for walking the frequency table
5
6Two new functions for getting the next higher and next lower frequencies
7in the cpufreq table, based upon a frequency supplied in kHz.
8
9This is useful for cpufreq governors that do not target frequencies
10based upon a percentage or a pre-determined value, but instead access
11the cpufreq table directly.
12
13Signed-off-by: Mike Turquette <mturquette@ti.com>
14Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
15Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
16---
17 drivers/cpufreq/freq_table.c | 73 ++++++++++++++++++++++++++++++++++++++++++
18 include/linux/cpufreq.h | 9 +++++
19 2 files changed, 82 insertions(+), 0 deletions(-)
20
21diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
22index 0543221..11a307b 100644
23--- a/drivers/cpufreq/freq_table.c
24+++ b/drivers/cpufreq/freq_table.c
25@@ -13,6 +13,7 @@
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/cpufreq.h>
29+#include <linux/err.h>
30
31 #define dprintk(msg...) \
32 cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
33@@ -174,6 +175,78 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
34 }
35 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
36
37+int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy,
38+ struct cpufreq_frequency_table *table, int *index)
39+{
40+ unsigned int cur_freq;
41+ unsigned int next_lowest_freq;
42+ int optimal_index = -1;
43+ int i = 0;
44+
45+ if (!policy || IS_ERR(policy) || !table || IS_ERR(table) ||
46+ !index || IS_ERR(index))
47+ return -ENOMEM;
48+
49+ cur_freq = policy->cur;
50+ next_lowest_freq = policy->min;
51+
52+ /* we're at the lowest frequency in the table already, bail out */
53+ if (cur_freq == policy->min)
54+ return -EINVAL;
55+
56+ /* walk the list, find closest freq to cur_freq that is below it */
57+ while(table[i].frequency != CPUFREQ_TABLE_END) {
58+ if (table[i].frequency < cur_freq &&
59+ table[i].frequency >= next_lowest_freq) {
60+ next_lowest_freq = table[i].frequency;
61+ optimal_index = table[i].index;
62+ }
63+
64+ i++;
65+ }
66+
67+ *index = optimal_index;
68+
69+ return 0;
70+}
71+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_lowest);
72+
73+int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy,
74+ struct cpufreq_frequency_table *table, int *index)
75+{
76+ unsigned int cur_freq;
77+ unsigned int next_higher_freq;
78+ int optimal_index = -1;
79+ int i = 0;
80+
81+ if (!policy || IS_ERR(policy) || !table || IS_ERR(table) ||
82+ !index || IS_ERR(index))
83+ return -ENOMEM;
84+
85+ cur_freq = policy->cur;
86+ next_higher_freq = policy->max;
87+
88+ /* we're at the highest frequency in the table already, bail out */
89+ if (cur_freq == policy->max)
90+ return -EINVAL;
91+
92+ /* walk the list, find closest freq to cur_freq that is above it */
93+ while(table[i].frequency != CPUFREQ_TABLE_END) {
94+ if (table[i].frequency > cur_freq &&
95+ table[i].frequency <= next_higher_freq) {
96+ next_higher_freq = table[i].frequency;
97+ optimal_index = table[i].index;
98+ }
99+
100+ i++;
101+ }
102+
103+ *index = optimal_index;
104+
105+ return 0;
106+}
107+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_highest);
108+
109 static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table);
110 /**
111 * show_available_freqs - show available frequencies for the specified CPU
112diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
113index 9343dd3..a38fca8 100644
114--- a/include/linux/cpufreq.h
115+++ b/include/linux/cpufreq.h
116@@ -396,6 +396,15 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
117
118 void cpufreq_frequency_table_put_attr(unsigned int cpu);
119
120+/* the following are for use in governors, or anywhere else */
121+extern int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy,
122+ struct cpufreq_frequency_table *table,
123+ int *index);
124+
125+extern int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy,
126+ struct cpufreq_frequency_table *table,
127+ int *index);
128+
129
130 /*********************************************************************
131 * UNIFIED DEBUG HELPERS *
132--
1331.6.6.1
134
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch
new file mode 100644
index 00000000..731906cc
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch
@@ -0,0 +1,879 @@
1From e4c777d8314d7925e4895f00b3a7ebd64a4d830b Mon Sep 17 00:00:00 2001
2From: Mike Turquette <mturquette@ti.com>
3Date: Tue, 17 May 2011 09:43:09 -0500
4Subject: [PATCH 2/2] cpufreq: introduce hotplug governor
5
6The "hotplug" governor scales CPU frequency based on load, similar to
7"ondemand". It scales up to the highest frequency when "up_threshold"
8is crossed and scales down one frequency at a time when "down_threshold"
9is crossed. Unlike those governors, target frequencies are determined
10by directly accessing the CPUfreq frequency table, instead of taking
11some percentage of maximum available frequency.
12
13The key difference in the "hotplug" governor is that it will disable
14auxillary CPUs when the system is very idle, and enable them again once
15the system becomes busy. This is achieved by averaging load over
16multiple sampling periods; if CPUs were online or offlined based on a
17single sampling period then thrashing will occur.
18
19Sysfs entries exist for "hotplug_in_sampling_periods" and for
20"hotplug_out_sampling_periods" which determine how many consecutive
21periods get averaged to determine if auxillery CPUs should be onlined or
22offlined. Defaults are 5 periods and 20 periods respectively.
23Otherwise the standard sysfs entries you might find for "ondemand" and
24"conservative" governors are there.
25
26To use this governor it is assumed that your CPUfreq driver has
27populated the CPUfreq table, CONFIG_NO_HZ is enabled and
28CONFIG_HOTPLUG_CPU is enabled.
29
30Changes in V2:
31 Corrected default sampling periods
32 Optimized load history array resizing
33 Maintain load history when resizing array
34 Add locking to dbs_check_cpu
35 Switch from enable_nonboot_cpus to cpu_up
36 Switch from disable_nonboot_cpus to down_cpu
37 Fix some printks
38 Coding style around for-loops
39
40Signed-off-by: Mike Turquette <mturquette@ti.com>
41Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
42Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
43---
44 Documentation/cpu-freq/governors.txt | 28 ++
45 drivers/cpufreq/Kconfig | 33 ++
46 drivers/cpufreq/Makefile | 1 +
47 drivers/cpufreq/cpufreq_hotplug.c | 705 ++++++++++++++++++++++++++++++++++
48 include/linux/cpufreq.h | 3 +
49 5 files changed, 770 insertions(+), 0 deletions(-)
50 create mode 100644 drivers/cpufreq/cpufreq_hotplug.c
51
52diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
53index e74d0a2..c2e3d3d 100644
54--- a/Documentation/cpu-freq/governors.txt
55+++ b/Documentation/cpu-freq/governors.txt
56@@ -193,6 +193,34 @@ governor but for the opposite direction. For example when set to its
57 default value of '20' it means that if the CPU usage needs to be below
58 20% between samples to have the frequency decreased.
59
60+
61+2.6 Hotplug
62+-----------
63+
64+The CPUfreq governor "hotplug" operates similary to "ondemand" and
65+"conservative". It's decisions are based primarily on CPU load. Like
66+"ondemand" the "hotplug" governor will ramp up to the highest frequency
67+once the run-time tunable "up_threshold" parameter is crossed. Like
68+"conservative", the "hotplug" governor exports a "down_threshold"
69+parameter that is also tunable at run-time. When the "down_threshold"
70+is crossed the CPU transitions to the next lowest frequency in the
71+CPUfreq frequency table instead of decrementing the frequency based on a
72+percentage of maximum load.
73+
74+The main reason "hotplug" governor exists is for architectures requiring
75+that only the master CPU be online in order to hit low-power states
76+(C-states). OMAP4 is one such example of this. The "hotplug" governor
77+is also helpful in reducing thermal output in devices with tight thermal
78+constraints.
79+
80+Auxillary CPUs are onlined/offline based on CPU load, but the decision
81+to do so is made after averaging several sampling windows. This is to
82+reduce CPU hotplug "thrashing", which can be caused by normal system
83+entropy and leads to lots of spurious plug-in and plug-out transitions.
84+The number of sampling periods averaged together is tunable via the
85+"hotplug_in_sampling_periods" and "hotplug_out_sampling_periods"
86+run-time tunable parameters.
87+
88 3. The Governor Interface in the CPUfreq Core
89 =============================================
90
91diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
92index ca8ee80..c716a0e 100644
93--- a/drivers/cpufreq/Kconfig
94+++ b/drivers/cpufreq/Kconfig
95@@ -110,6 +110,19 @@ config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
96 Be aware that not all cpufreq drivers support the conservative
97 governor. If unsure have a look at the help section of the
98 driver. Fallback governor will be the performance governor.
99+
100+config CPU_FREQ_DEFAULT_GOV_HOTPLUG
101+ bool "hotplug"
102+ select CPU_FREQ_GOV_HOTPLUG
103+ select CPU_FREQ_GOV_PERFORMANCE
104+ help
105+ Use the CPUFreq governor 'hotplug' as default. This allows you
106+ to get a full dynamic frequency capable system with CPU
107+ hotplug support by simply loading your cpufreq low-level
108+ hardware driver. Be aware that not all cpufreq drivers
109+ support the hotplug governor. If unsure have a look at
110+ the help section of the driver. Fallback governor will be the
111+ performance governor.
112 endchoice
113
114 config CPU_FREQ_GOV_PERFORMANCE
115@@ -190,4 +203,24 @@ config CPU_FREQ_GOV_CONSERVATIVE
116
117 If in doubt, say N.
118
119+config CPU_FREQ_GOV_HOTPLUG
120+ tristate "'hotplug' cpufreq governor"
121+ depends on CPU_FREQ && NO_HZ && HOTPLUG_CPU
122+ help
123+ 'hotplug' - this driver mimics the frequency scaling behavior
124+ in 'ondemand', but with several key differences. First is
125+ that frequency transitions use the CPUFreq table directly,
126+ instead of incrementing in a percentage of the maximum
127+ available frequency. Second 'hotplug' will offline auxillary
128+ CPUs when the system is idle, and online those CPUs once the
129+ system becomes busy again. This last feature is needed for
130+ architectures which transition to low power states when only
131+ the "master" CPU is online, or for thermally constrained
132+ devices.
133+
134+ If you don't have one of these architectures or devices, use
135+ 'ondemand' instead.
136+
137+ If in doubt, say N.
138+
139 endif # CPU_FREQ
140diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
141index 71fc3b4..05d564c 100644
142--- a/drivers/cpufreq/Makefile
143+++ b/drivers/cpufreq/Makefile
144@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
145 obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
146 obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
147 obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
148+obj-$(CONFIG_CPU_FREQ_GOV_HOTPLUG) += cpufreq_hotplug.o
149
150 # CPUfreq cross-arch helpers
151 obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
152diff --git a/drivers/cpufreq/cpufreq_hotplug.c b/drivers/cpufreq/cpufreq_hotplug.c
153new file mode 100644
154index 0000000..85aa6d2
155--- /dev/null
156+++ b/drivers/cpufreq/cpufreq_hotplug.c
157@@ -0,0 +1,705 @@
158+/*
159+ * CPUFreq hotplug governor
160+ *
161+ * Copyright (C) 2010 Texas Instruments, Inc.
162+ * Mike Turquette <mturquette@ti.com>
163+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
164+ *
165+ * Based on ondemand governor
166+ * Copyright (C) 2001 Russell King
167+ * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>,
168+ * Jun Nakajima <jun.nakajima@intel.com>
169+ *
170+ * This program is free software; you can redistribute it and/or modify
171+ * it under the terms of the GNU General Public License version 2 as
172+ * published by the Free Software Foundation.
173+ */
174+
175+#include <linux/kernel.h>
176+#include <linux/module.h>
177+#include <linux/init.h>
178+#include <linux/cpufreq.h>
179+#include <linux/cpu.h>
180+#include <linux/jiffies.h>
181+#include <linux/kernel_stat.h>
182+#include <linux/mutex.h>
183+#include <linux/hrtimer.h>
184+#include <linux/tick.h>
185+#include <linux/ktime.h>
186+#include <linux/sched.h>
187+#include <linux/err.h>
188+#include <linux/slab.h>
189+
190+/* greater than 80% avg load across online CPUs increases frequency */
191+#define DEFAULT_UP_FREQ_MIN_LOAD (80)
192+
193+/* less than 20% avg load across online CPUs decreases frequency */
194+#define DEFAULT_DOWN_FREQ_MAX_LOAD (20)
195+
196+/* default sampling period (uSec) is bogus; 10x ondemand's default for x86 */
197+#define DEFAULT_SAMPLING_PERIOD (100000)
198+
199+/* default number of sampling periods to average before hotplug-in decision */
200+#define DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS (5)
201+
202+/* default number of sampling periods to average before hotplug-out decision */
203+#define DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS (20)
204+
205+static void do_dbs_timer(struct work_struct *work);
206+static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
207+ unsigned int event);
208+
209+#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG
210+static
211+#endif
212+struct cpufreq_governor cpufreq_gov_hotplug = {
213+ .name = "hotplug",
214+ .governor = cpufreq_governor_dbs,
215+ .owner = THIS_MODULE,
216+};
217+
218+struct cpu_dbs_info_s {
219+ cputime64_t prev_cpu_idle;
220+ cputime64_t prev_cpu_wall;
221+ cputime64_t prev_cpu_nice;
222+ struct cpufreq_policy *cur_policy;
223+ struct delayed_work work;
224+ struct cpufreq_frequency_table *freq_table;
225+ int cpu;
226+ /*
227+ * percpu mutex that serializes governor limit change with
228+ * do_dbs_timer invocation. We do not want do_dbs_timer to run
229+ * when user is changing the governor or limits.
230+ */
231+ struct mutex timer_mutex;
232+};
233+static DEFINE_PER_CPU(struct cpu_dbs_info_s, hp_cpu_dbs_info);
234+
235+static unsigned int dbs_enable; /* number of CPUs using this policy */
236+
237+/*
238+ * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on
239+ * different CPUs. It protects dbs_enable in governor start/stop.
240+ */
241+static DEFINE_MUTEX(dbs_mutex);
242+
243+static struct workqueue_struct *khotplug_wq;
244+
245+static struct dbs_tuners {
246+ unsigned int sampling_rate;
247+ unsigned int up_threshold;
248+ unsigned int down_threshold;
249+ unsigned int hotplug_in_sampling_periods;
250+ unsigned int hotplug_out_sampling_periods;
251+ unsigned int hotplug_load_index;
252+ unsigned int *hotplug_load_history;
253+ unsigned int ignore_nice;
254+ unsigned int io_is_busy;
255+} dbs_tuners_ins = {
256+ .sampling_rate = DEFAULT_SAMPLING_PERIOD,
257+ .up_threshold = DEFAULT_UP_FREQ_MIN_LOAD,
258+ .down_threshold = DEFAULT_DOWN_FREQ_MAX_LOAD,
259+ .hotplug_in_sampling_periods = DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS,
260+ .hotplug_out_sampling_periods = DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS,
261+ .hotplug_load_index = 0,
262+ .ignore_nice = 0,
263+ .io_is_busy = 0,
264+};
265+
266+/*
267+ * A corner case exists when switching io_is_busy at run-time: comparing idle
268+ * times from a non-io_is_busy period to an io_is_busy period (or vice-versa)
269+ * will misrepresent the actual change in system idleness. We ignore this
270+ * corner case: enabling io_is_busy might cause freq increase and disabling
271+ * might cause freq decrease, which probably matches the original intent.
272+ */
273+static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
274+{
275+ u64 idle_time;
276+ u64 iowait_time;
277+
278+ /* cpufreq-hotplug always assumes CONFIG_NO_HZ */
279+ idle_time = get_cpu_idle_time_us(cpu, wall);
280+
281+ /* add time spent doing I/O to idle time */
282+ if (dbs_tuners_ins.io_is_busy) {
283+ iowait_time = get_cpu_iowait_time_us(cpu, wall);
284+ /* cpufreq-hotplug always assumes CONFIG_NO_HZ */
285+ if (iowait_time != -1ULL && idle_time >= iowait_time)
286+ idle_time -= iowait_time;
287+ }
288+
289+ return idle_time;
290+}
291+
292+/************************** sysfs interface ************************/
293+
294+/* XXX look at global sysfs macros in cpufreq.h, can those be used here? */
295+
296+/* cpufreq_hotplug Governor Tunables */
297+#define show_one(file_name, object) \
298+static ssize_t show_##file_name \
299+(struct kobject *kobj, struct attribute *attr, char *buf) \
300+{ \
301+ return sprintf(buf, "%u\n", dbs_tuners_ins.object); \
302+}
303+show_one(sampling_rate, sampling_rate);
304+show_one(up_threshold, up_threshold);
305+show_one(down_threshold, down_threshold);
306+show_one(hotplug_in_sampling_periods, hotplug_in_sampling_periods);
307+show_one(hotplug_out_sampling_periods, hotplug_out_sampling_periods);
308+show_one(ignore_nice_load, ignore_nice);
309+show_one(io_is_busy, io_is_busy);
310+
311+static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
312+ const char *buf, size_t count)
313+{
314+ unsigned int input;
315+ int ret;
316+ ret = sscanf(buf, "%u", &input);
317+ if (ret != 1)
318+ return -EINVAL;
319+
320+ mutex_lock(&dbs_mutex);
321+ dbs_tuners_ins.sampling_rate = input;
322+ mutex_unlock(&dbs_mutex);
323+
324+ return count;
325+}
326+
327+static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
328+ const char *buf, size_t count)
329+{
330+ unsigned int input;
331+ int ret;
332+ ret = sscanf(buf, "%u", &input);
333+
334+ if (ret != 1 || input <= dbs_tuners_ins.down_threshold) {
335+ return -EINVAL;
336+ }
337+
338+ mutex_lock(&dbs_mutex);
339+ dbs_tuners_ins.up_threshold = input;
340+ mutex_unlock(&dbs_mutex);
341+
342+ return count;
343+}
344+
345+static ssize_t store_down_threshold(struct kobject *a, struct attribute *b,
346+ const char *buf, size_t count)
347+{
348+ unsigned int input;
349+ int ret;
350+ ret = sscanf(buf, "%u", &input);
351+
352+ if (ret != 1 || input >= dbs_tuners_ins.up_threshold) {
353+ return -EINVAL;
354+ }
355+
356+ mutex_lock(&dbs_mutex);
357+ dbs_tuners_ins.down_threshold = input;
358+ mutex_unlock(&dbs_mutex);
359+
360+ return count;
361+}
362+
363+static ssize_t store_hotplug_in_sampling_periods(struct kobject *a,
364+ struct attribute *b, const char *buf, size_t count)
365+{
366+ unsigned int input;
367+ unsigned int *temp;
368+ unsigned int max_windows;
369+ int ret;
370+ ret = sscanf(buf, "%u", &input);
371+
372+ if (ret != 1)
373+ return -EINVAL;
374+
375+ /* already using this value, bail out */
376+ if (input == dbs_tuners_ins.hotplug_in_sampling_periods)
377+ return count;
378+
379+ mutex_lock(&dbs_mutex);
380+ ret = count;
381+ max_windows = max(dbs_tuners_ins.hotplug_in_sampling_periods,
382+ dbs_tuners_ins.hotplug_out_sampling_periods);
383+
384+ /* no need to resize array */
385+ if (input <= max_windows) {
386+ dbs_tuners_ins.hotplug_in_sampling_periods = input;
387+ goto out;
388+ }
389+
390+ /* resize array */
391+ temp = kmalloc((sizeof(unsigned int) * input), GFP_KERNEL);
392+
393+ if (!temp || IS_ERR(temp)) {
394+ ret = -ENOMEM;
395+ goto out;
396+ }
397+
398+ memcpy(temp, dbs_tuners_ins.hotplug_load_history,
399+ (max_windows * sizeof(unsigned int)));
400+ kfree(dbs_tuners_ins.hotplug_load_history);
401+
402+ /* replace old buffer, old number of sampling periods & old index */
403+ dbs_tuners_ins.hotplug_load_history = temp;
404+ dbs_tuners_ins.hotplug_in_sampling_periods = input;
405+ dbs_tuners_ins.hotplug_load_index = max_windows;
406+out:
407+ mutex_unlock(&dbs_mutex);
408+
409+ return ret;
410+}
411+
412+static ssize_t store_hotplug_out_sampling_periods(struct kobject *a,
413+ struct attribute *b, const char *buf, size_t count)
414+{
415+ unsigned int input;
416+ unsigned int *temp;
417+ unsigned int max_windows;
418+ int ret;
419+ ret = sscanf(buf, "%u", &input);
420+
421+ if (ret != 1)
422+ return -EINVAL;
423+
424+ /* already using this value, bail out */
425+ if (input == dbs_tuners_ins.hotplug_out_sampling_periods)
426+ return count;
427+
428+ mutex_lock(&dbs_mutex);
429+ ret = count;
430+ max_windows = max(dbs_tuners_ins.hotplug_in_sampling_periods,
431+ dbs_tuners_ins.hotplug_out_sampling_periods);
432+
433+ /* no need to resize array */
434+ if (input <= max_windows) {
435+ dbs_tuners_ins.hotplug_out_sampling_periods = input;
436+ goto out;
437+ }
438+
439+ /* resize array */
440+ temp = kmalloc((sizeof(unsigned int) * input), GFP_KERNEL);
441+
442+ if (!temp || IS_ERR(temp)) {
443+ ret = -ENOMEM;
444+ goto out;
445+ }
446+
447+ memcpy(temp, dbs_tuners_ins.hotplug_load_history,
448+ (max_windows * sizeof(unsigned int)));
449+ kfree(dbs_tuners_ins.hotplug_load_history);
450+
451+ /* replace old buffer, old number of sampling periods & old index */
452+ dbs_tuners_ins.hotplug_load_history = temp;
453+ dbs_tuners_ins.hotplug_out_sampling_periods = input;
454+ dbs_tuners_ins.hotplug_load_index = max_windows;
455+out:
456+ mutex_unlock(&dbs_mutex);
457+
458+ return ret;
459+}
460+
461+static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
462+ const char *buf, size_t count)
463+{
464+ unsigned int input;
465+ int ret;
466+
467+ unsigned int j;
468+
469+ ret = sscanf(buf, "%u", &input);
470+ if (ret != 1)
471+ return -EINVAL;
472+
473+ if (input > 1)
474+ input = 1;
475+
476+ mutex_lock(&dbs_mutex);
477+ if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
478+ mutex_unlock(&dbs_mutex);
479+ return count;
480+ }
481+ dbs_tuners_ins.ignore_nice = input;
482+
483+ /* we need to re-evaluate prev_cpu_idle */
484+ for_each_online_cpu(j) {
485+ struct cpu_dbs_info_s *dbs_info;
486+ dbs_info = &per_cpu(hp_cpu_dbs_info, j);
487+ dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
488+ &dbs_info->prev_cpu_wall);
489+ if (dbs_tuners_ins.ignore_nice)
490+ dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
491+
492+ }
493+ mutex_unlock(&dbs_mutex);
494+
495+ return count;
496+}
497+
498+static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
499+ const char *buf, size_t count)
500+{
501+ unsigned int input;
502+ int ret;
503+
504+ ret = sscanf(buf, "%u", &input);
505+ if (ret != 1)
506+ return -EINVAL;
507+
508+ mutex_lock(&dbs_mutex);
509+ dbs_tuners_ins.io_is_busy = !!input;
510+ mutex_unlock(&dbs_mutex);
511+
512+ return count;
513+}
514+
515+define_one_global_rw(sampling_rate);
516+define_one_global_rw(up_threshold);
517+define_one_global_rw(down_threshold);
518+define_one_global_rw(hotplug_in_sampling_periods);
519+define_one_global_rw(hotplug_out_sampling_periods);
520+define_one_global_rw(ignore_nice_load);
521+define_one_global_rw(io_is_busy);
522+
523+static struct attribute *dbs_attributes[] = {
524+ &sampling_rate.attr,
525+ &up_threshold.attr,
526+ &down_threshold.attr,
527+ &hotplug_in_sampling_periods.attr,
528+ &hotplug_out_sampling_periods.attr,
529+ &ignore_nice_load.attr,
530+ &io_is_busy.attr,
531+ NULL
532+};
533+
534+static struct attribute_group dbs_attr_group = {
535+ .attrs = dbs_attributes,
536+ .name = "hotplug",
537+};
538+
539+/************************** sysfs end ************************/
540+
541+static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
542+{
543+ /* combined load of all enabled CPUs */
544+ unsigned int total_load = 0;
545+ /* single largest CPU load */
546+ unsigned int max_load = 0;
547+ /* average load across all enabled CPUs */
548+ unsigned int avg_load = 0;
549+ /* average load across multiple sampling periods for hotplug events */
550+ unsigned int hotplug_in_avg_load = 0;
551+ unsigned int hotplug_out_avg_load = 0;
552+ /* number of sampling periods averaged for hotplug decisions */
553+ unsigned int periods;
554+
555+ struct cpufreq_policy *policy;
556+ unsigned int index = 0;
557+ unsigned int i, j;
558+
559+ policy = this_dbs_info->cur_policy;
560+
561+ /*
562+ * cpu load accounting
563+ * get highest load, total load and average load across all CPUs
564+ */
565+ for_each_cpu(j, policy->cpus) {
566+ unsigned int load;
567+ unsigned int idle_time, wall_time;
568+ cputime64_t cur_wall_time, cur_idle_time;
569+ struct cpu_dbs_info_s *j_dbs_info;
570+
571+ j_dbs_info = &per_cpu(hp_cpu_dbs_info, j);
572+
573+ /* update both cur_idle_time and cur_wall_time */
574+ cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
575+
576+ /* how much wall time has passed since last iteration? */
577+ wall_time = (unsigned int) cputime64_sub(cur_wall_time,
578+ j_dbs_info->prev_cpu_wall);
579+ j_dbs_info->prev_cpu_wall = cur_wall_time;
580+
581+ /* how much idle time has passed since last iteration? */
582+ idle_time = (unsigned int) cputime64_sub(cur_idle_time,
583+ j_dbs_info->prev_cpu_idle);
584+ j_dbs_info->prev_cpu_idle = cur_idle_time;
585+
586+ if (unlikely(!wall_time || wall_time < idle_time))
587+ continue;
588+
589+ /* load is the percentage of time not spent in idle */
590+ load = 100 * (wall_time - idle_time) / wall_time;
591+
592+ /* keep track of combined load across all CPUs */
593+ total_load += load;
594+
595+ /* keep track of highest single load across all CPUs */
596+ if (load > max_load)
597+ max_load = load;
598+ }
599+
600+ /* calculate the average load across all related CPUs */
601+ avg_load = total_load / num_online_cpus();
602+
603+
604+ /*
605+ * hotplug load accounting
606+ * average load over multiple sampling periods
607+ */
608+
609+ /* how many sampling periods do we use for hotplug decisions? */
610+ periods = max(dbs_tuners_ins.hotplug_in_sampling_periods,
611+ dbs_tuners_ins.hotplug_out_sampling_periods);
612+
613+ /* store avg_load in the circular buffer */
614+ dbs_tuners_ins.hotplug_load_history[dbs_tuners_ins.hotplug_load_index]
615+ = avg_load;
616+
617+ /* compute average load across in & out sampling periods */
618+ for (i = 0, j = dbs_tuners_ins.hotplug_load_index;
619+ i < periods; i++, j--) {
620+ if (i < dbs_tuners_ins.hotplug_in_sampling_periods)
621+ hotplug_in_avg_load +=
622+ dbs_tuners_ins.hotplug_load_history[j];
623+ if (i < dbs_tuners_ins.hotplug_out_sampling_periods)
624+ hotplug_out_avg_load +=
625+ dbs_tuners_ins.hotplug_load_history[j];
626+
627+ if (j == 0)
628+ j = periods;
629+ }
630+
631+ hotplug_in_avg_load = hotplug_in_avg_load /
632+ dbs_tuners_ins.hotplug_in_sampling_periods;
633+
634+ hotplug_out_avg_load = hotplug_out_avg_load /
635+ dbs_tuners_ins.hotplug_out_sampling_periods;
636+
637+ /* return to first element if we're at the circular buffer's end */
638+ if (++dbs_tuners_ins.hotplug_load_index == periods)
639+ dbs_tuners_ins.hotplug_load_index = 0;
640+
641+ /* check for frequency increase */
642+ if (avg_load > dbs_tuners_ins.up_threshold) {
643+ /* should we enable auxillary CPUs? */
644+ if (num_online_cpus() < 2 && hotplug_in_avg_load >
645+ dbs_tuners_ins.up_threshold) {
646+ /* hotplug with cpufreq is nasty
647+ * a call to cpufreq_governor_dbs may cause a lockup.
648+ * wq is not running here so its safe.
649+ */
650+ mutex_unlock(&this_dbs_info->timer_mutex);
651+ cpu_up(1);
652+ mutex_lock(&this_dbs_info->timer_mutex);
653+ goto out;
654+ }
655+
656+ /* increase to highest frequency supported */
657+ if (policy->cur < policy->max)
658+ __cpufreq_driver_target(policy, policy->max,
659+ CPUFREQ_RELATION_H);
660+
661+ goto out;
662+ }
663+
664+ /* check for frequency decrease */
665+ if (avg_load < dbs_tuners_ins.down_threshold) {
666+ /* are we at the minimum frequency already? */
667+ if (policy->cur == policy->min) {
668+ /* should we disable auxillary CPUs? */
669+ if (num_online_cpus() > 1 && hotplug_out_avg_load <
670+ dbs_tuners_ins.down_threshold) {
671+ mutex_unlock(&this_dbs_info->timer_mutex);
672+ cpu_down(1);
673+ mutex_lock(&this_dbs_info->timer_mutex);
674+ }
675+ goto out;
676+ }
677+
678+ /* bump down to the next lowest frequency in the table */
679+ if (cpufreq_frequency_table_next_lowest(policy,
680+ this_dbs_info->freq_table, &index)) {
681+ pr_err("%s: failed to get next lowest frequency\n",
682+ __func__);
683+ goto out;
684+ }
685+
686+ __cpufreq_driver_target(policy,
687+ this_dbs_info->freq_table[index].frequency,
688+ CPUFREQ_RELATION_L);
689+ }
690+out:
691+ return;
692+}
693+
694+static void do_dbs_timer(struct work_struct *work)
695+{
696+ struct cpu_dbs_info_s *dbs_info =
697+ container_of(work, struct cpu_dbs_info_s, work.work);
698+ unsigned int cpu = dbs_info->cpu;
699+
700+ /* We want all related CPUs to do sampling nearly on same jiffy */
701+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
702+
703+ mutex_lock(&dbs_info->timer_mutex);
704+ dbs_check_cpu(dbs_info);
705+ queue_delayed_work_on(cpu, khotplug_wq, &dbs_info->work, delay);
706+ mutex_unlock(&dbs_info->timer_mutex);
707+}
708+
709+static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
710+{
711+ /* We want all related CPUs to do sampling nearly on same jiffy */
712+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
713+ delay -= jiffies % delay;
714+
715+ INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
716+ queue_delayed_work_on(dbs_info->cpu, khotplug_wq, &dbs_info->work,
717+ delay);
718+}
719+
720+static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
721+{
722+ cancel_delayed_work_sync(&dbs_info->work);
723+}
724+
725+static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
726+ unsigned int event)
727+{
728+ unsigned int cpu = policy->cpu;
729+ struct cpu_dbs_info_s *this_dbs_info;
730+ unsigned int i, j, max_periods;
731+ int rc;
732+
733+ this_dbs_info = &per_cpu(hp_cpu_dbs_info, cpu);
734+
735+ switch (event) {
736+ case CPUFREQ_GOV_START:
737+ if ((!cpu_online(cpu)) || (!policy->cur))
738+ return -EINVAL;
739+
740+ mutex_lock(&dbs_mutex);
741+ dbs_enable++;
742+ for_each_cpu(j, policy->cpus) {
743+ struct cpu_dbs_info_s *j_dbs_info;
744+ j_dbs_info = &per_cpu(hp_cpu_dbs_info, j);
745+ j_dbs_info->cur_policy = policy;
746+
747+ j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
748+ &j_dbs_info->prev_cpu_wall);
749+ if (dbs_tuners_ins.ignore_nice) {
750+ j_dbs_info->prev_cpu_nice =
751+ kstat_cpu(j).cpustat.nice;
752+ }
753+
754+ max_periods = max(DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS,
755+ DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS);
756+ dbs_tuners_ins.hotplug_load_history = kmalloc(
757+ (sizeof(unsigned int) * max_periods),
758+ GFP_KERNEL);
759+ if (!dbs_tuners_ins.hotplug_load_history) {
760+ WARN_ON(1);
761+ return -ENOMEM;
762+ }
763+ for (i = 0; i < max_periods; i++)
764+ dbs_tuners_ins.hotplug_load_history[i] = 50;
765+ }
766+ this_dbs_info->cpu = cpu;
767+ this_dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
768+ /*
769+ * Start the timerschedule work, when this governor
770+ * is used for first time
771+ */
772+ if (dbs_enable == 1) {
773+ rc = sysfs_create_group(cpufreq_global_kobject,
774+ &dbs_attr_group);
775+ if (rc) {
776+ mutex_unlock(&dbs_mutex);
777+ return rc;
778+ }
779+ }
780+ mutex_unlock(&dbs_mutex);
781+
782+ mutex_init(&this_dbs_info->timer_mutex);
783+ dbs_timer_init(this_dbs_info);
784+ break;
785+
786+ case CPUFREQ_GOV_STOP:
787+ dbs_timer_exit(this_dbs_info);
788+
789+ mutex_lock(&dbs_mutex);
790+ mutex_destroy(&this_dbs_info->timer_mutex);
791+ dbs_enable--;
792+ mutex_unlock(&dbs_mutex);
793+ if (!dbs_enable)
794+ sysfs_remove_group(cpufreq_global_kobject,
795+ &dbs_attr_group);
796+ kfree(dbs_tuners_ins.hotplug_load_history);
797+ /*
798+ * XXX BIG CAVEAT: Stopping the governor with CPU1 offline
799+ * will result in it remaining offline until the user onlines
800+ * it again. It is up to the user to do this (for now).
801+ */
802+ break;
803+
804+ case CPUFREQ_GOV_LIMITS:
805+ mutex_lock(&this_dbs_info->timer_mutex);
806+ if (policy->max < this_dbs_info->cur_policy->cur)
807+ __cpufreq_driver_target(this_dbs_info->cur_policy,
808+ policy->max, CPUFREQ_RELATION_H);
809+ else if (policy->min > this_dbs_info->cur_policy->cur)
810+ __cpufreq_driver_target(this_dbs_info->cur_policy,
811+ policy->min, CPUFREQ_RELATION_L);
812+ mutex_unlock(&this_dbs_info->timer_mutex);
813+ break;
814+ }
815+ return 0;
816+}
817+
818+static int __init cpufreq_gov_dbs_init(void)
819+{
820+ int err;
821+ cputime64_t wall;
822+ u64 idle_time;
823+ int cpu = get_cpu();
824+
825+ idle_time = get_cpu_idle_time_us(cpu, &wall);
826+ put_cpu();
827+ if (idle_time != -1ULL) {
828+ dbs_tuners_ins.up_threshold = DEFAULT_UP_FREQ_MIN_LOAD;
829+ } else {
830+ pr_err("cpufreq-hotplug: %s: assumes CONFIG_NO_HZ\n",
831+ __func__);
832+ return -EINVAL;
833+ }
834+
835+ khotplug_wq = create_workqueue("khotplug");
836+ if (!khotplug_wq) {
837+ pr_err("Creation of khotplug failed\n");
838+ return -EFAULT;
839+ }
840+ err = cpufreq_register_governor(&cpufreq_gov_hotplug);
841+ if (err)
842+ destroy_workqueue(khotplug_wq);
843+
844+ return err;
845+}
846+
847+static void __exit cpufreq_gov_dbs_exit(void)
848+{
849+ cpufreq_unregister_governor(&cpufreq_gov_hotplug);
850+ destroy_workqueue(khotplug_wq);
851+}
852+
853+MODULE_AUTHOR("Mike Turquette <mturquette@ti.com>");
854+MODULE_DESCRIPTION("'cpufreq_hotplug' - cpufreq governor for dynamic frequency scaling and CPU hotplugging");
855+MODULE_LICENSE("GPL");
856+
857+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG
858+fs_initcall(cpufreq_gov_dbs_init);
859+#else
860+module_init(cpufreq_gov_dbs_init);
861+#endif
862+module_exit(cpufreq_gov_dbs_exit);
863diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
864index a38fca8..6cbc3df 100644
865--- a/include/linux/cpufreq.h
866+++ b/include/linux/cpufreq.h
867@@ -355,6 +355,9 @@ extern struct cpufreq_governor cpufreq_gov_ondemand;
868 #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE)
869 extern struct cpufreq_governor cpufreq_gov_conservative;
870 #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative)
871+#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG)
872+extern struct cpufreq_governor cpufreq_gov_hotplug;
873+#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_hotplug)
874 #endif
875
876
877--
8781.6.6.1
879
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch
new file mode 100644
index 00000000..d150dfc6
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch
@@ -0,0 +1,27 @@
1From 33668b07abd5e66a263cc8b4b88587646f38bed0 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 1/8] 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>
8---
9 arch/arm/plat-omap/cpu-omap.c | 2 +-
10 1 files changed, 1 insertions(+), 1 deletions(-)
11
12diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
13index da4f68d..cd09d4b 100644
14--- a/arch/arm/plat-omap/cpu-omap.c
15+++ b/arch/arm/plat-omap/cpu-omap.c
16@@ -160,7 +160,7 @@ static int __init omap_cpufreq_init(void)
17 return cpufreq_register_driver(&omap_driver);
18 }
19
20-arch_initcall(omap_cpufreq_init);
21+late_initcall(omap_cpufreq_init);
22
23 /*
24 * if ever we want to remove this, upon cleanup call:
25--
261.6.6.1
27
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch
new file mode 100644
index 00000000..d62e04d1
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch
@@ -0,0 +1,31 @@
1From e89b1544450fb8410a44004e48d6b330bc39f0ce Mon Sep 17 00:00:00 2001
2From: Kevin Hilman <khilman@deeprootsystems.com>
3Date: Wed, 11 Aug 2010 17:05:38 -0700
4Subject: [PATCH 2/8] 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>
10---
11 arch/arm/plat-omap/cpu-omap.c | 4 ++++
12 1 files changed, 4 insertions(+), 0 deletions(-)
13
14diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
15index cd09d4b..1b36664 100644
16--- a/arch/arm/plat-omap/cpu-omap.c
17+++ b/arch/arm/plat-omap/cpu-omap.c
18@@ -126,6 +126,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
19 VERY_HI_RATE) / 1000;
20 }
21
22+ policy->min = policy->cpuinfo.min_freq;
23+ policy->max = policy->cpuinfo.max_freq;
24+ policy->cur = omap_getspeed(0);
25+
26 /* FIXME: what's the actual transition time? */
27 policy->cpuinfo.transition_latency = 300 * 1000;
28
29--
301.6.6.1
31
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch
new file mode 100644
index 00000000..fbe16213
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch
@@ -0,0 +1,263 @@
1From 948b868e4a83b054e8a58362238bc6cd61c0aeab Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Mon, 10 Nov 2008 17:00:25 +0530
4Subject: [PATCH 3/8] 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>
117---
118 arch/arm/mach-omap2/clock.h | 14 +++++++++++++-
119 arch/arm/mach-omap2/clock34xx.c | 2 ++
120 arch/arm/plat-omap/cpu-omap.c | 34 +++++++++++++++++++++++++++++++---
121 3 files changed, 46 insertions(+), 4 deletions(-)
122
123diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
124index e10ff2b..0a07e50 100644
125--- a/arch/arm/mach-omap2/clock.h
126+++ b/arch/arm/mach-omap2/clock.h
127@@ -141,7 +141,9 @@ extern const struct clksel_rate gpt_sys_rates[];
128 extern const struct clksel_rate gfx_l3_rates[];
129 extern const struct clksel_rate dsp_ick_rates[];
130
131-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
132+#ifdef CONFIG_CPU_FREQ
133+
134+#ifdef CONFIG_ARCH_OMAP2
135 extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
136 extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
137 #else
138@@ -149,6 +151,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
139 #define omap2_clk_exit_cpufreq_table 0
140 #endif
141
142+#ifdef CONFIG_ARCH_OMAP3
143+extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
144+extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
145+#else
146+#define omap3_clk_init_cpufreq_table 0
147+#define omap3_clk_exit_cpufreq_table 0
148+#endif
149+
150+#endif /* CONFIG_CPU_FREQ */
151+
152 extern const struct clkops clkops_omap2_iclk_dflt_wait;
153 extern const struct clkops clkops_omap2_iclk_dflt;
154 extern const struct clkops clkops_omap2_iclk_idle_only;
155diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
156index 1fc96b9..119e135 100644
157--- a/arch/arm/mach-omap2/clock34xx.c
158+++ b/arch/arm/mach-omap2/clock34xx.c
159@@ -20,6 +20,8 @@
160 #include <linux/kernel.h>
161 #include <linux/clk.h>
162 #include <linux/io.h>
163+#include <linux/err.h>
164+#include <linux/cpufreq.h>
165
166 #include <plat/clock.h>
167
168diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
169index 1b36664..f0f9430 100644
170--- a/arch/arm/plat-omap/cpu-omap.c
171+++ b/arch/arm/plat-omap/cpu-omap.c
172@@ -8,6 +8,10 @@
173 *
174 * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
175 *
176+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
177+ * Updated to support OMAP3
178+ * Rajendra Nayak <rnayak@ti.com>
179+ *
180 * This program is free software; you can redistribute it and/or modify
181 * it under the terms of the GNU General Public License version 2 as
182 * published by the Free Software Foundation.
183@@ -26,12 +30,19 @@
184 #include <plat/clock.h>
185 #include <asm/system.h>
186
187+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
188+#include <plat/omap-pm.h>
189+#include <plat/opp.h>
190+#endif
191+
192 #define VERY_HI_RATE 900000000
193
194 static struct cpufreq_frequency_table *freq_table;
195
196 #ifdef CONFIG_ARCH_OMAP1
197 #define MPU_CLK "mpu"
198+#elif CONFIG_ARCH_OMAP3
199+#define MPU_CLK "arm_fck"
200 #else
201 #define MPU_CLK "virt_prcm_set"
202 #endif
203@@ -73,7 +84,13 @@ static int omap_target(struct cpufreq_policy *policy,
204 unsigned int target_freq,
205 unsigned int relation)
206 {
207+#ifdef CONFIG_ARCH_OMAP1
208 struct cpufreq_freqs freqs;
209+#endif
210+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
211+ unsigned long freq;
212+ struct device *mpu_dev = omap2_get_mpuss_device();
213+#endif
214 int ret = 0;
215
216 /* Ensure desired rate is within allowed range. Some govenors
217@@ -83,13 +100,13 @@ static int omap_target(struct cpufreq_policy *policy,
218 if (target_freq > policy->max)
219 target_freq = policy->max;
220
221+#ifdef CONFIG_ARCH_OMAP1
222 freqs.old = omap_getspeed(0);
223 freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
224 freqs.cpu = 0;
225
226 if (freqs.old == freqs.new)
227 return ret;
228-
229 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
230 #ifdef CONFIG_CPU_FREQ_DEBUG
231 printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
232@@ -97,7 +114,11 @@ static int omap_target(struct cpufreq_policy *policy,
233 #endif
234 ret = clk_set_rate(mpu_clk, freqs.new * 1000);
235 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
236-
237+#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
238+ freq = target_freq * 1000;
239+ if (opp_find_freq_ceil(mpu_dev, &freq))
240+ omap_pm_cpu_set_freq(freq);
241+#endif
242 return ret;
243 }
244
245@@ -114,7 +135,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
246
247 policy->cur = policy->min = policy->max = omap_getspeed(0);
248
249- clk_init_cpufreq_table(&freq_table);
250+ if (!cpu_is_omap34xx()) {
251+ clk_init_cpufreq_table(&freq_table);
252+ } else {
253+ struct device *mpu_dev = omap2_get_mpuss_device();
254+
255+ opp_init_cpufreq_table(mpu_dev, &freq_table);
256+ }
257+
258 if (freq_table) {
259 result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
260 if (!result)
261--
2621.6.6.1
263
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch
new file mode 100644
index 00000000..36742e43
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch
@@ -0,0 +1,32 @@
1From 86227f1eb341e571163464cb0a412ed2179f2541 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 4/8] 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>
13---
14 arch/arm/plat-omap/cpu-omap.c | 2 +-
15 1 files changed, 1 insertions(+), 1 deletions(-)
16
17diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
18index f0f9430..c3ac065 100644
19--- a/arch/arm/plat-omap/cpu-omap.c
20+++ b/arch/arm/plat-omap/cpu-omap.c
21@@ -41,7 +41,7 @@ static struct cpufreq_frequency_table *freq_table;
22
23 #ifdef CONFIG_ARCH_OMAP1
24 #define MPU_CLK "mpu"
25-#elif CONFIG_ARCH_OMAP3
26+#elif defined(CONFIG_ARCH_OMAP3)
27 #define MPU_CLK "arm_fck"
28 #else
29 #define MPU_CLK "virt_prcm_set"
30--
311.6.6.1
32
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch
new file mode 100644
index 00000000..7cf69325
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch
@@ -0,0 +1,33 @@
1From 4764137dd613362656726a15cb8184724aeb99bb Mon Sep 17 00:00:00 2001
2From: Kevin Hilman <khilman@deeprootsystems.com>
3Date: Tue, 16 Nov 2010 11:48:41 -0800
4Subject: [PATCH 5/8] cpufreq: fixup after new OPP layer merged
5
6---
7 arch/arm/plat-omap/cpu-omap.c | 3 ++-
8 1 files changed, 2 insertions(+), 1 deletions(-)
9
10diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
11index c3ac065..9cd2709 100644
12--- a/arch/arm/plat-omap/cpu-omap.c
13+++ b/arch/arm/plat-omap/cpu-omap.c
14@@ -25,6 +25,7 @@
15 #include <linux/err.h>
16 #include <linux/clk.h>
17 #include <linux/io.h>
18+#include <linux/opp.h>
19
20 #include <mach/hardware.h>
21 #include <plat/clock.h>
22@@ -32,7 +33,7 @@
23
24 #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
25 #include <plat/omap-pm.h>
26-#include <plat/opp.h>
27+#include <plat/common.h>
28 #endif
29
30 #define VERY_HI_RATE 900000000
31--
321.6.6.1
33
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch
new file mode 100644
index 00000000..cfc257e0
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch
@@ -0,0 +1,669 @@
1From e16548716c5cbc3c9885d05f1654d83d5411a3a7 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 6/8] 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
13Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
14Cc: Kevin Hilman <khilman@ti.com>
15Cc: Vishwanath BS <vishwanath.bs@ti.com>
16---
17 arch/arm/mach-omap1/Makefile | 3 +
18 arch/arm/mach-omap1/omap1-cpufreq.c | 176 ++++++++++++++++++++++++++
19 arch/arm/mach-omap2/Makefile | 3 +
20 arch/arm/mach-omap2/omap2plus-cpufreq.c | 201 ++++++++++++++++++++++++++++++
21 arch/arm/plat-omap/Makefile | 1 -
22 arch/arm/plat-omap/cpu-omap.c | 204 -------------------------------
23 6 files changed, 383 insertions(+), 205 deletions(-)
24 create mode 100644 arch/arm/mach-omap1/omap1-cpufreq.c
25 create mode 100644 arch/arm/mach-omap2/omap2plus-cpufreq.c
26 delete mode 100644 arch/arm/plat-omap/cpu-omap.c
27
28diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
29index af98117..e5082b0 100644
30--- a/arch/arm/mach-omap1/Makefile
31+++ b/arch/arm/mach-omap1/Makefile
32@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
33
34 obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
35
36+# CPUFREQ driver
37+obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o
38+
39 # Power Management
40 obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
41
42diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c
43new file mode 100644
44index 0000000..682cdc8
45--- /dev/null
46+++ b/arch/arm/mach-omap1/omap1-cpufreq.c
47@@ -0,0 +1,176 @@
48+/*
49+ * OMAP1 cpufreq driver
50+ *
51+ * CPU frequency scaling for OMAP
52+ *
53+ * Copyright (C) 2005 Nokia Corporation
54+ * Written by Tony Lindgren <tony@atomide.com>
55+ *
56+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
57+ *
58+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
59+ * Updated to support OMAP3
60+ * Rajendra Nayak <rnayak@ti.com>
61+ *
62+ * This program is free software; you can redistribute it and/or modify
63+ * it under the terms of the GNU General Public License version 2 as
64+ * published by the Free Software Foundation.
65+ */
66+#include <linux/types.h>
67+#include <linux/kernel.h>
68+#include <linux/sched.h>
69+#include <linux/cpufreq.h>
70+#include <linux/delay.h>
71+#include <linux/init.h>
72+#include <linux/err.h>
73+#include <linux/clk.h>
74+#include <linux/io.h>
75+#include <linux/opp.h>
76+
77+#include <asm/system.h>
78+
79+#include <plat/clock.h>
80+#include <plat/omap-pm.h>
81+
82+#include <mach/hardware.h>
83+
84+#define VERY_HI_RATE 900000000
85+
86+static struct cpufreq_frequency_table *freq_table;
87+static struct clk *mpu_clk;
88+
89+static int omap_verify_speed(struct cpufreq_policy *policy)
90+{
91+ if (freq_table)
92+ return cpufreq_frequency_table_verify(policy, freq_table);
93+
94+ if (policy->cpu)
95+ return -EINVAL;
96+
97+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
98+ policy->cpuinfo.max_freq);
99+
100+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
101+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
102+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
103+ policy->cpuinfo.max_freq);
104+ return 0;
105+}
106+
107+static unsigned int omap_getspeed(unsigned int cpu)
108+{
109+ unsigned long rate;
110+
111+ if (cpu)
112+ return 0;
113+
114+ rate = clk_get_rate(mpu_clk) / 1000;
115+ return rate;
116+}
117+
118+static int omap_target(struct cpufreq_policy *policy,
119+ unsigned int target_freq,
120+ unsigned int relation)
121+{
122+ struct cpufreq_freqs freqs;
123+ int ret = 0;
124+
125+ /* Ensure desired rate is within allowed range. Some govenors
126+ * (ondemand) will just pass target_freq=0 to get the minimum. */
127+ if (target_freq < policy->min)
128+ target_freq = policy->min;
129+ if (target_freq > policy->max)
130+ target_freq = policy->max;
131+
132+ freqs.old = omap_getspeed(0);
133+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
134+ freqs.cpu = 0;
135+
136+ if (freqs.old == freqs.new)
137+ return ret;
138+
139+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
140+
141+#ifdef CONFIG_CPU_FREQ_DEBUG
142+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
143+#endif
144+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
145+
146+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
147+
148+ return ret;
149+}
150+
151+static int __init omap_cpu_init(struct cpufreq_policy *policy)
152+{
153+ int result = 0;
154+
155+ mpu_clk = clk_get(NULL, "mpu");
156+ if (IS_ERR(mpu_clk))
157+ return PTR_ERR(mpu_clk);
158+
159+ if (policy->cpu != 0)
160+ return -EINVAL;
161+
162+ policy->cur = policy->min = policy->max = omap_getspeed(0);
163+
164+ clk_init_cpufreq_table(&freq_table);
165+
166+ if (freq_table) {
167+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
168+ if (!result)
169+ cpufreq_frequency_table_get_attr(freq_table,
170+ policy->cpu);
171+ } else {
172+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
173+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
174+ VERY_HI_RATE) / 1000;
175+ }
176+
177+ policy->min = policy->cpuinfo.min_freq;
178+ policy->max = policy->cpuinfo.max_freq;
179+ policy->cur = omap_getspeed(0);
180+
181+ /* FIXME: what's the actual transition time? */
182+ policy->cpuinfo.transition_latency = 300 * 1000;
183+
184+ return 0;
185+}
186+
187+static int omap_cpu_exit(struct cpufreq_policy *policy)
188+{
189+ clk_exit_cpufreq_table(&freq_table);
190+ clk_put(mpu_clk);
191+ return 0;
192+}
193+
194+static struct freq_attr *omap_cpufreq_attr[] = {
195+ &cpufreq_freq_attr_scaling_available_freqs,
196+ NULL,
197+};
198+
199+static struct cpufreq_driver omap_driver = {
200+ .flags = CPUFREQ_STICKY,
201+ .verify = omap_verify_speed,
202+ .target = omap_target,
203+ .get = omap_getspeed,
204+ .init = omap_cpu_init,
205+ .exit = omap_cpu_exit,
206+ .name = "omap1",
207+ .attr = omap_cpufreq_attr,
208+};
209+
210+static int __init omap_cpufreq_init(void)
211+{
212+ return cpufreq_register_driver(&omap_driver);
213+}
214+
215+static void __exit omap_cpufreq_exit(void)
216+{
217+ cpufreq_unregister_driver(&omap_driver);
218+}
219+
220+MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs");
221+MODULE_LICENSE("GPL");
222+module_init(omap_cpufreq_init);
223+module_exit(omap_cpufreq_exit);
224diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
225index 05cd983..e9c2445 100644
226--- a/arch/arm/mach-omap2/Makefile
227+++ b/arch/arm/mach-omap2/Makefile
228@@ -56,6 +56,9 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
229 obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
230 endif
231
232+# CPUFREQ driver
233+obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o
234+
235 # Power Management
236 ifeq ($(CONFIG_PM),y)
237 obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
238diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
239new file mode 100644
240index 0000000..14f84cc
241--- /dev/null
242+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
243@@ -0,0 +1,201 @@
244+/*
245+ * OMAP2PLUS cpufreq driver
246+ *
247+ * CPU frequency scaling for OMAP
248+ *
249+ * Copyright (C) 2005 Nokia Corporation
250+ * Written by Tony Lindgren <tony@atomide.com>
251+ *
252+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
253+ *
254+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
255+ * Updated to support OMAP3
256+ * Rajendra Nayak <rnayak@ti.com>
257+ *
258+ * This program is free software; you can redistribute it and/or modify
259+ * it under the terms of the GNU General Public License version 2 as
260+ * published by the Free Software Foundation.
261+ */
262+#include <linux/types.h>
263+#include <linux/kernel.h>
264+#include <linux/sched.h>
265+#include <linux/cpufreq.h>
266+#include <linux/delay.h>
267+#include <linux/init.h>
268+#include <linux/err.h>
269+#include <linux/clk.h>
270+#include <linux/io.h>
271+#include <linux/opp.h>
272+
273+#include <asm/system.h>
274+#include <asm/smp_plat.h>
275+
276+#include <plat/clock.h>
277+#include <plat/omap-pm.h>
278+#include <plat/common.h>
279+
280+#include <mach/hardware.h>
281+
282+#define VERY_HI_RATE 900000000
283+
284+static struct cpufreq_frequency_table *freq_table;
285+static struct clk *mpu_clk;
286+
287+static int omap_verify_speed(struct cpufreq_policy *policy)
288+{
289+ if (freq_table)
290+ return cpufreq_frequency_table_verify(policy, freq_table);
291+
292+ if (policy->cpu)
293+ return -EINVAL;
294+
295+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
296+ policy->cpuinfo.max_freq);
297+
298+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
299+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
300+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
301+ policy->cpuinfo.max_freq);
302+ return 0;
303+}
304+
305+static unsigned int omap_getspeed(unsigned int cpu)
306+{
307+ unsigned long rate;
308+
309+ if (cpu)
310+ return 0;
311+
312+ rate = clk_get_rate(mpu_clk) / 1000;
313+ return rate;
314+}
315+
316+static int omap_target(struct cpufreq_policy *policy,
317+ unsigned int target_freq,
318+ unsigned int relation)
319+{
320+ int ret = 0;
321+ struct cpufreq_freqs freqs;
322+
323+ /* Ensure desired rate is within allowed range. Some govenors
324+ * (ondemand) will just pass target_freq=0 to get the minimum. */
325+ if (target_freq < policy->min)
326+ target_freq = policy->min;
327+ if (target_freq > policy->max)
328+ target_freq = policy->max;
329+
330+ freqs.old = omap_getspeed(0);
331+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
332+ freqs.cpu = 0;
333+
334+ if (freqs.old == freqs.new)
335+ return ret;
336+
337+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
338+
339+#ifdef CONFIG_CPU_FREQ_DEBUG
340+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
341+#endif
342+
343+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
344+
345+ /*
346+ * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies
347+ * won't get updated when UP machine cpufreq build with
348+ * CONFIG_SMP enabled. Below code is added only to manage that
349+ * scenario
350+ */
351+ if (!is_smp())
352+ loops_per_jiffy =
353+ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
354+
355+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
356+
357+ return ret;
358+}
359+
360+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
361+{
362+ int result = 0;
363+ struct device *mpu_dev;
364+
365+ if (cpu_is_omap24xx())
366+ mpu_clk = clk_get(NULL, "virt_prcm_set");
367+ else if (cpu_is_omap34xx())
368+ mpu_clk = clk_get(NULL, "dpll1_ck");
369+ else if (cpu_is_omap34xx())
370+ mpu_clk = clk_get(NULL, "dpll_mpu_ck");
371+
372+ if (IS_ERR(mpu_clk))
373+ return PTR_ERR(mpu_clk);
374+
375+ if (policy->cpu != 0)
376+ return -EINVAL;
377+
378+ policy->cur = policy->min = policy->max = omap_getspeed(0);
379+
380+ mpu_dev = omap2_get_mpuss_device();
381+ if (!mpu_dev) {
382+ pr_warning("%s: unable to get the mpu device\n", __func__);
383+ return -EINVAL;
384+ }
385+ opp_init_cpufreq_table(mpu_dev, &freq_table);
386+
387+ if (freq_table) {
388+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
389+ if (!result)
390+ cpufreq_frequency_table_get_attr(freq_table,
391+ policy->cpu);
392+ } else {
393+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
394+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
395+ VERY_HI_RATE) / 1000;
396+ }
397+
398+ policy->min = policy->cpuinfo.min_freq;
399+ policy->max = policy->cpuinfo.max_freq;
400+ policy->cur = omap_getspeed(0);
401+
402+ /* FIXME: what's the actual transition time? */
403+ policy->cpuinfo.transition_latency = 300 * 1000;
404+
405+ return 0;
406+}
407+
408+static int omap_cpu_exit(struct cpufreq_policy *policy)
409+{
410+ clk_exit_cpufreq_table(&freq_table);
411+ clk_put(mpu_clk);
412+ return 0;
413+}
414+
415+static struct freq_attr *omap_cpufreq_attr[] = {
416+ &cpufreq_freq_attr_scaling_available_freqs,
417+ NULL,
418+};
419+
420+static struct cpufreq_driver omap_driver = {
421+ .flags = CPUFREQ_STICKY,
422+ .verify = omap_verify_speed,
423+ .target = omap_target,
424+ .get = omap_getspeed,
425+ .init = omap_cpu_init,
426+ .exit = omap_cpu_exit,
427+ .name = "omap2plus",
428+ .attr = omap_cpufreq_attr,
429+};
430+
431+static int __init omap_cpufreq_init(void)
432+{
433+ return cpufreq_register_driver(&omap_driver);
434+}
435+
436+static void __exit omap_cpufreq_exit(void)
437+{
438+ cpufreq_unregister_driver(&omap_driver);
439+}
440+
441+MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs");
442+MODULE_LICENSE("GPL");
443+module_init(omap_cpufreq_init);
444+module_exit(omap_cpufreq_exit);
445diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
446index a4a1285..ec7862e 100644
447--- a/arch/arm/plat-omap/Makefile
448+++ b/arch/arm/plat-omap/Makefile
449@@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
450 obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
451 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
452
453-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
454 obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
455 obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
456 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
457diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
458deleted file mode 100644
459index 9cd2709..0000000
460--- a/arch/arm/plat-omap/cpu-omap.c
461+++ /dev/null
462@@ -1,204 +0,0 @@
463-/*
464- * linux/arch/arm/plat-omap/cpu-omap.c
465- *
466- * CPU frequency scaling for OMAP
467- *
468- * Copyright (C) 2005 Nokia Corporation
469- * Written by Tony Lindgren <tony@atomide.com>
470- *
471- * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
472- *
473- * Copyright (C) 2007-2008 Texas Instruments, Inc.
474- * Updated to support OMAP3
475- * Rajendra Nayak <rnayak@ti.com>
476- *
477- * This program is free software; you can redistribute it and/or modify
478- * it under the terms of the GNU General Public License version 2 as
479- * published by the Free Software Foundation.
480- */
481-#include <linux/types.h>
482-#include <linux/kernel.h>
483-#include <linux/sched.h>
484-#include <linux/cpufreq.h>
485-#include <linux/delay.h>
486-#include <linux/init.h>
487-#include <linux/err.h>
488-#include <linux/clk.h>
489-#include <linux/io.h>
490-#include <linux/opp.h>
491-
492-#include <mach/hardware.h>
493-#include <plat/clock.h>
494-#include <asm/system.h>
495-
496-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
497-#include <plat/omap-pm.h>
498-#include <plat/common.h>
499-#endif
500-
501-#define VERY_HI_RATE 900000000
502-
503-static struct cpufreq_frequency_table *freq_table;
504-
505-#ifdef CONFIG_ARCH_OMAP1
506-#define MPU_CLK "mpu"
507-#elif defined(CONFIG_ARCH_OMAP3)
508-#define MPU_CLK "arm_fck"
509-#else
510-#define MPU_CLK "virt_prcm_set"
511-#endif
512-
513-static struct clk *mpu_clk;
514-
515-/* TODO: Add support for SDRAM timing changes */
516-
517-static int omap_verify_speed(struct cpufreq_policy *policy)
518-{
519- if (freq_table)
520- return cpufreq_frequency_table_verify(policy, freq_table);
521-
522- if (policy->cpu)
523- return -EINVAL;
524-
525- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
526- policy->cpuinfo.max_freq);
527-
528- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
529- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
530- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
531- policy->cpuinfo.max_freq);
532- return 0;
533-}
534-
535-static unsigned int omap_getspeed(unsigned int cpu)
536-{
537- unsigned long rate;
538-
539- if (cpu)
540- return 0;
541-
542- rate = clk_get_rate(mpu_clk) / 1000;
543- return rate;
544-}
545-
546-static int omap_target(struct cpufreq_policy *policy,
547- unsigned int target_freq,
548- unsigned int relation)
549-{
550-#ifdef CONFIG_ARCH_OMAP1
551- struct cpufreq_freqs freqs;
552-#endif
553-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
554- unsigned long freq;
555- struct device *mpu_dev = omap2_get_mpuss_device();
556-#endif
557- int ret = 0;
558-
559- /* Ensure desired rate is within allowed range. Some govenors
560- * (ondemand) will just pass target_freq=0 to get the minimum. */
561- if (target_freq < policy->min)
562- target_freq = policy->min;
563- if (target_freq > policy->max)
564- target_freq = policy->max;
565-
566-#ifdef CONFIG_ARCH_OMAP1
567- freqs.old = omap_getspeed(0);
568- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
569- freqs.cpu = 0;
570-
571- if (freqs.old == freqs.new)
572- return ret;
573- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
574-#ifdef CONFIG_CPU_FREQ_DEBUG
575- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
576- freqs.old, freqs.new);
577-#endif
578- ret = clk_set_rate(mpu_clk, freqs.new * 1000);
579- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
580-#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
581- freq = target_freq * 1000;
582- if (opp_find_freq_ceil(mpu_dev, &freq))
583- omap_pm_cpu_set_freq(freq);
584-#endif
585- return ret;
586-}
587-
588-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
589-{
590- int result = 0;
591-
592- mpu_clk = clk_get(NULL, MPU_CLK);
593- if (IS_ERR(mpu_clk))
594- return PTR_ERR(mpu_clk);
595-
596- if (policy->cpu != 0)
597- return -EINVAL;
598-
599- policy->cur = policy->min = policy->max = omap_getspeed(0);
600-
601- if (!cpu_is_omap34xx()) {
602- clk_init_cpufreq_table(&freq_table);
603- } else {
604- struct device *mpu_dev = omap2_get_mpuss_device();
605-
606- opp_init_cpufreq_table(mpu_dev, &freq_table);
607- }
608-
609- if (freq_table) {
610- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
611- if (!result)
612- cpufreq_frequency_table_get_attr(freq_table,
613- policy->cpu);
614- } else {
615- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
616- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
617- VERY_HI_RATE) / 1000;
618- }
619-
620- policy->min = policy->cpuinfo.min_freq;
621- policy->max = policy->cpuinfo.max_freq;
622- policy->cur = omap_getspeed(0);
623-
624- /* FIXME: what's the actual transition time? */
625- policy->cpuinfo.transition_latency = 300 * 1000;
626-
627- return 0;
628-}
629-
630-static int omap_cpu_exit(struct cpufreq_policy *policy)
631-{
632- clk_exit_cpufreq_table(&freq_table);
633- clk_put(mpu_clk);
634- return 0;
635-}
636-
637-static struct freq_attr *omap_cpufreq_attr[] = {
638- &cpufreq_freq_attr_scaling_available_freqs,
639- NULL,
640-};
641-
642-static struct cpufreq_driver omap_driver = {
643- .flags = CPUFREQ_STICKY,
644- .verify = omap_verify_speed,
645- .target = omap_target,
646- .get = omap_getspeed,
647- .init = omap_cpu_init,
648- .exit = omap_cpu_exit,
649- .name = "omap",
650- .attr = omap_cpufreq_attr,
651-};
652-
653-static int __init omap_cpufreq_init(void)
654-{
655- return cpufreq_register_driver(&omap_driver);
656-}
657-
658-late_initcall(omap_cpufreq_init);
659-
660-/*
661- * if ever we want to remove this, upon cleanup call:
662- *
663- * cpufreq_unregister_driver()
664- * cpufreq_frequency_table_put_attr()
665- */
666-
667--
6681.6.6.1
669
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
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch
new file mode 100644
index 00000000..3797443c
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch
@@ -0,0 +1,29 @@
1From 6e101764a47cb6975a555e2237843ad391a542a4 Mon Sep 17 00:00:00 2001
2From: Jarkko Nikula <jhnikula@gmail.com>
3Date: Thu, 14 Apr 2011 16:21:58 +0300
4Subject: [PATCH 8/8] 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>
10---
11 arch/arm/mach-omap2/omap2plus-cpufreq.c | 2 +-
12 1 files changed, 1 insertions(+), 1 deletions(-)
13
14diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
15index 8d472f6..d53ce23 100644
16--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
17+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
18@@ -161,7 +161,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
19 mpu_clk = clk_get(NULL, "virt_prcm_set");
20 else if (cpu_is_omap34xx())
21 mpu_clk = clk_get(NULL, "dpll1_ck");
22- else if (cpu_is_omap34xx())
23+ else if (cpu_is_omap44xx())
24 mpu_clk = clk_get(NULL, "dpll_mpu_ck");
25
26 if (IS_ERR(mpu_clk))
27--
281.6.6.1
29
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch
new file mode 100644
index 00000000..d9b05173
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch
@@ -0,0 +1,77 @@
1From 988f50cb51d18e81ed2f7673a09694d28c9d086a Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Tue, 5 Apr 2011 15:22:31 +0530
4Subject: [PATCH 1/6] OMAP2+: clockdomain: Add an api to read idle mode
5
6Add a clockdomain api to check if hardware supervised
7idle transitions are enabled on a clockdomain.
8
9Signed-off-by: Rajendra Nayak <rnayak@ti.com>
10---
11 arch/arm/mach-omap2/clockdomain.c | 21 +++++++++++++++++++++
12 arch/arm/mach-omap2/clockdomain.h | 3 +++
13 2 files changed, 24 insertions(+), 0 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
16index 6cb6c03..2ab3686 100644
17--- a/arch/arm/mach-omap2/clockdomain.c
18+++ b/arch/arm/mach-omap2/clockdomain.c
19@@ -795,6 +795,27 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
20 arch_clkdm->clkdm_deny_idle(clkdm);
21 }
22
23+/**
24+ * clkdm_is_idle - Check if the clkdm hwsup/autoidle is enabled
25+ * @clkdm: struct clockdomain *
26+ *
27+ * Returns true if the clockdomain is in hardware-supervised
28+ * idle mode, or 0 otherwise.
29+ *
30+ */
31+int clkdm_is_idle(struct clockdomain *clkdm)
32+{
33+ if (!clkdm)
34+ return -EINVAL;
35+
36+ if (!arch_clkdm || !arch_clkdm->clkdm_is_idle)
37+ return -EINVAL;
38+
39+ pr_debug("clockdomain: reading idle state for %s\n", clkdm->name);
40+
41+ return arch_clkdm->clkdm_is_idle(clkdm);
42+}
43+
44
45 /* Clockdomain-to-clock framework interface code */
46
47diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
48index 5823584..085ed82 100644
49--- a/arch/arm/mach-omap2/clockdomain.h
50+++ b/arch/arm/mach-omap2/clockdomain.h
51@@ -138,6 +138,7 @@ struct clockdomain {
52 * @clkdm_wakeup: Force a clockdomain to wakeup
53 * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain
54 * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
55+ * @clkdm_is_idle: Check if hw supervised idle transitions are enabled
56 * @clkdm_clk_enable: Put the clkdm in right state for a clock enable
57 * @clkdm_clk_disable: Put the clkdm in right state for a clock disable
58 */
59@@ -154,6 +155,7 @@ struct clkdm_ops {
60 int (*clkdm_wakeup)(struct clockdomain *clkdm);
61 void (*clkdm_allow_idle)(struct clockdomain *clkdm);
62 void (*clkdm_deny_idle)(struct clockdomain *clkdm);
63+ int (*clkdm_is_idle)(struct clockdomain *clkdm);
64 int (*clkdm_clk_enable)(struct clockdomain *clkdm);
65 int (*clkdm_clk_disable)(struct clockdomain *clkdm);
66 };
67@@ -177,6 +179,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
68
69 void clkdm_allow_idle(struct clockdomain *clkdm);
70 void clkdm_deny_idle(struct clockdomain *clkdm);
71+int clkdm_is_idle(struct clockdomain *clkdm);
72
73 int clkdm_wakeup(struct clockdomain *clkdm);
74 int clkdm_sleep(struct clockdomain *clkdm);
75--
761.6.6.1
77
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch
new file mode 100644
index 00000000..c7c1ea0b
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch
@@ -0,0 +1,86 @@
1From e3ba8d41bfafd782f3ee7f8930d9bf393986c662 Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Tue, 5 Apr 2011 15:22:36 +0530
4Subject: [PATCH 2/6] OMAP2+: clockdomain: Add SoC support for clkdm_is_idle
5
6Add the SoC specific implemenation for clkdm_is_idle
7for OMAP2/3 and OMAP4.
8
9Signed-off-by: Rajendra Nayak <rnayak@ti.com>
10---
11 arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 12 ++++++++++++
12 arch/arm/mach-omap2/clockdomain44xx.c | 7 +++++++
13 2 files changed, 19 insertions(+), 0 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
16index 48d0db7..db49baa 100644
17--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
18+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
19@@ -13,6 +13,7 @@
20 */
21
22 #include <linux/types.h>
23+#include <linux/errno.h>
24 #include <plat/prcm.h>
25 #include "prm.h"
26 #include "prm2xxx_3xxx.h"
27@@ -146,6 +147,15 @@ static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
28 _clkdm_del_autodeps(clkdm);
29 }
30
31+static int omap2_clkdm_is_idle(struct clockdomain *clkdm)
32+{
33+ if (!clkdm->clktrctrl_mask)
34+ return -1;
35+
36+ return omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
37+ clkdm->clktrctrl_mask);
38+}
39+
40 static void _enable_hwsup(struct clockdomain *clkdm)
41 {
42 if (cpu_is_omap24xx())
43@@ -252,6 +262,7 @@ struct clkdm_ops omap2_clkdm_operations = {
44 .clkdm_wakeup = omap2_clkdm_wakeup,
45 .clkdm_allow_idle = omap2_clkdm_allow_idle,
46 .clkdm_deny_idle = omap2_clkdm_deny_idle,
47+ .clkdm_is_idle = omap2_clkdm_is_idle,
48 .clkdm_clk_enable = omap2_clkdm_clk_enable,
49 .clkdm_clk_disable = omap2_clkdm_clk_disable,
50 };
51@@ -269,6 +280,7 @@ struct clkdm_ops omap3_clkdm_operations = {
52 .clkdm_wakeup = omap3_clkdm_wakeup,
53 .clkdm_allow_idle = omap3_clkdm_allow_idle,
54 .clkdm_deny_idle = omap3_clkdm_deny_idle,
55+ .clkdm_is_idle = omap2_clkdm_is_idle,
56 .clkdm_clk_enable = omap2_clkdm_clk_enable,
57 .clkdm_clk_disable = omap2_clkdm_clk_disable,
58 };
59diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
60index a1a4ecd..4b10727 100644
61--- a/arch/arm/mach-omap2/clockdomain44xx.c
62+++ b/arch/arm/mach-omap2/clockdomain44xx.c
63@@ -93,6 +93,12 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
64 clkdm->cm_inst, clkdm->clkdm_offs);
65 }
66
67+static int omap4_clkdm_is_idle(struct clockdomain *clkdm)
68+{
69+ return omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
70+ clkdm->cm_inst, clkdm->clkdm_offs);
71+}
72+
73 static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
74 {
75 bool hwsup = false;
76@@ -132,6 +138,7 @@ struct clkdm_ops omap4_clkdm_operations = {
77 .clkdm_wakeup = omap4_clkdm_wakeup,
78 .clkdm_allow_idle = omap4_clkdm_allow_idle,
79 .clkdm_deny_idle = omap4_clkdm_deny_idle,
80+ .clkdm_is_idle = omap4_clkdm_is_idle,
81 .clkdm_clk_enable = omap4_clkdm_clk_enable,
82 .clkdm_clk_disable = omap4_clkdm_clk_disable,
83 };
84--
851.6.6.1
86
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch
new file mode 100644
index 00000000..cbe5ca20
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch
@@ -0,0 +1,35 @@
1From 7cdc87071a4bb390ad5d7ddea210bd2b4d662114 Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Tue, 5 Apr 2011 15:22:41 +0530
4Subject: [PATCH 3/6] OMAP2+: PM: Initialise sleep_switch to a non-valid value
5
6sleep_switch which is initialised to 0 in omap_set_pwrdm_state
7happens to be a valid sleep_switch type (FORCEWAKEUP_SWITCH)
8which are defined as
9#define FORCEWAKEUP_SWITCH 0
10#define LOWPOWERSTATE_SWITCH 1
11
12This causes the function to wrongly program some clock domains
13even when the Powerdomain is in ON state.
14
15Signed-off-by: Rajendra Nayak <rnayak@ti.com>
16---
17 arch/arm/mach-omap2/pm.c | 2 +-
18 1 files changed, 1 insertions(+), 1 deletions(-)
19
20diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
21index 49486f5..d48813f 100644
22--- a/arch/arm/mach-omap2/pm.c
23+++ b/arch/arm/mach-omap2/pm.c
24@@ -106,7 +106,7 @@ static void omap2_init_processor_devices(void)
25 int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
26 {
27 u32 cur_state;
28- int sleep_switch = 0;
29+ int sleep_switch = -1;
30 int ret = 0;
31
32 if (pwrdm == NULL || IS_ERR(pwrdm))
33--
341.6.6.1
35
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch
new file mode 100644
index 00000000..16eedf9a
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch
@@ -0,0 +1,50 @@
1From cec133850aa42c03d912c764aaa441677e782eca Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Tue, 5 Apr 2011 15:22:48 +0530
4Subject: [PATCH 4/6] OMAP2+: PM: idle clkdms only if already in idle
5
6The omap_set_pwrdm_state function forces clockdomains
7to idle, without checking the existing idle state
8programmed, instead based solely on the HW capability
9of the clockdomain to support idle.
10This is wrong and the clockdomains should be idled
11post a state_switch *only* if idle transitions on the
12clockdomain were already enabled.
13
14Signed-off-by: Rajendra Nayak <rnayak@ti.com>
15---
16 arch/arm/mach-omap2/pm.c | 4 +++-
17 1 files changed, 3 insertions(+), 1 deletions(-)
18
19diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
20index d48813f..840b0e1 100644
21--- a/arch/arm/mach-omap2/pm.c
22+++ b/arch/arm/mach-omap2/pm.c
23@@ -108,6 +108,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
24 u32 cur_state;
25 int sleep_switch = -1;
26 int ret = 0;
27+ int hwsup = 0;
28
29 if (pwrdm == NULL || IS_ERR(pwrdm))
30 return -EINVAL;
31@@ -127,6 +128,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
32 (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
33 sleep_switch = LOWPOWERSTATE_SWITCH;
34 } else {
35+ hwsup = clkdm_is_idle(pwrdm->pwrdm_clkdms[0]);
36 clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
37 pwrdm_wait_transition(pwrdm);
38 sleep_switch = FORCEWAKEUP_SWITCH;
39@@ -142,7 +144,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
40
41 switch (sleep_switch) {
42 case FORCEWAKEUP_SWITCH:
43- if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
44+ if (hwsup)
45 clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
46 else
47 clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
48--
491.6.6.1
50
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch
new file mode 100644
index 00000000..b0af9e7f
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch
@@ -0,0 +1,46 @@
1From 8fb6b7c488b31fbff5b81bdeea5dbb236342458b Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Tue, 29 Mar 2011 22:37:43 +0530
4Subject: [PATCH 5/6] OMAP2+: hwmod: Follow the recomended PRCM sequence
5
6Follow the recomended PRCM sequence.
7This still does not take care of Optional clocks.
8
9Signed-off-by: Rajendra Nayak <rnayak@ti.com>
10---
11 arch/arm/mach-omap2/omap_hwmod.c | 9 ++++++++-
12 1 files changed, 8 insertions(+), 1 deletions(-)
13
14diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
15index e034294..fc0db0c 100644
16--- a/arch/arm/mach-omap2/omap_hwmod.c
17+++ b/arch/arm/mach-omap2/omap_hwmod.c
18@@ -1223,6 +1223,7 @@ static int _reset(struct omap_hwmod *oh)
19 static int _enable(struct omap_hwmod *oh)
20 {
21 int r;
22+ int hwsup = 0;
23
24 if (oh->_state != _HWMOD_STATE_INITIALIZED &&
25 oh->_state != _HWMOD_STATE_IDLE &&
26@@ -1250,10 +1251,16 @@ static int _enable(struct omap_hwmod *oh)
27 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
28
29 _add_initiator_dep(oh, mpu_oh);
30+ if (oh->_clk && oh->_clk->clkdm) {
31+ hwsup = clkdm_is_idle(oh->_clk->clkdm);
32+ clkdm_wakeup(oh->_clk->clkdm);
33+ }
34 _enable_clocks(oh);
35-
36 r = _wait_target_ready(oh);
37 if (!r) {
38+ if (oh->_clk && oh->_clk->clkdm && hwsup)
39+ clkdm_allow_idle(oh->_clk->clkdm);
40+
41 oh->_state = _HWMOD_STATE_ENABLED;
42
43 /* Access the sysconfig only if the target is ready */
44--
451.6.6.1
46
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch
new file mode 100644
index 00000000..a8fc0c07
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch
@@ -0,0 +1,33 @@
1From 7b74888d198c260992349fab214cad3adf853ef9 Mon Sep 17 00:00:00 2001
2From: Rajendra Nayak <rnayak@ti.com>
3Date: Tue, 2 Mar 2010 17:25:30 +0530
4Subject: [PATCH 6/6] OMAP: Serial: Check wk_st only if present
5
6Uart on the resume path tries to read wk_st registers, even
7on architectures were its not present/populated.
8This patch fixes the issue.
9
10Signed-off-by: Rajendra Nayak <rnayak@ti.com>
11---
12 arch/arm/mach-omap2/serial.c | 5 +++--
13 1 files changed, 3 insertions(+), 2 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
16index 1ac361b..a0046ce 100644
17--- a/arch/arm/mach-omap2/serial.c
18+++ b/arch/arm/mach-omap2/serial.c
19@@ -418,8 +418,9 @@ void omap_uart_resume_idle(int num)
20 }
21
22 /* Check for normal UART wakeup */
23- if (__raw_readl(uart->wk_st) & uart->wk_mask)
24- omap_uart_block_sleep(uart);
25+ if (uart->wk_st && uart->wk_mask)
26+ if (__raw_readl(uart->wk_st) & uart->wk_mask)
27+ omap_uart_block_sleep(uart);
28 return;
29 }
30 }
31--
321.6.6.1
33
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch
new file mode 100644
index 00000000..0d1cbce6
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch
@@ -0,0 +1,30 @@
1From 4af697edf9d1d85d2735e86e86e1203c3509dcba Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Sat, 12 Feb 2011 17:27:14 +0530
4Subject: [PATCH 01/12] OMAP3+: voltage: remove spurious pr_notice for debugfs
5
6cat of debugfs entry for vp_volt provides voltage. The additional pr_notice
7is just spam on console and provides no additional information.
8
9Signed-off-by: Nishanth Menon <nm@ti.com>
10Signed-off-by: Kevin Hilman <khilman@ti.com>
11Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
12---
13 arch/arm/mach-omap2/voltage.c | 1 -
14 1 files changed, 0 insertions(+), 1 deletions(-)
15
16diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
17index 0c1552d..9ef3789 100644
18--- a/arch/arm/mach-omap2/voltage.c
19+++ b/arch/arm/mach-omap2/voltage.c
20@@ -148,7 +148,6 @@ static int vp_volt_debug_get(void *data, u64 *val)
21 }
22
23 vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
24- pr_notice("curr_vsel = %x\n", vsel);
25
26 if (!vdd->pmic_info->vsel_to_uv) {
27 pr_warning("PMIC function to convert vsel to voltage"
28--
291.6.6.1
30
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch
new file mode 100644
index 00000000..7b137925
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch
@@ -0,0 +1,41 @@
1From 37fb1c8eeecd39542716d3d0c7c5e3ca0eb198f8 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Sun, 13 Mar 2011 09:07:23 +0530
4Subject: [PATCH 02/12] OMAP4: PM: remove redundant #ifdef CONFIG_PM
5
6pm44xx.c is built only when CONFIG_PM is setup,
7remove redundant CONFIG_PM check.
8
9This also fixes:
10https://bugzilla.kernel.org/show_bug.cgi?id=25022
11
12Reported-by: Martin Etti <ettl.martin@gmx.de>
13
14Signed-off-by: Nishanth Menon <nm@ti.com>
15Signed-off-by: Kevin Hilman <khilman@ti.com>
16Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
17---
18 arch/arm/mach-omap2/pm44xx.c | 2 --
19 1 files changed, 0 insertions(+), 2 deletions(-)
20
21diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
22index 76cfff2..59a870b 100644
23--- a/arch/arm/mach-omap2/pm44xx.c
24+++ b/arch/arm/mach-omap2/pm44xx.c
25@@ -105,13 +105,11 @@ static int __init omap4_pm_init(void)
26
27 pr_err("Power Management for TI OMAP4.\n");
28
29-#ifdef CONFIG_PM
30 ret = pwrdm_for_each(pwrdms_setup, NULL);
31 if (ret) {
32 pr_err("Failed to setup powerdomains\n");
33 goto err2;
34 }
35-#endif
36
37 #ifdef CONFIG_SUSPEND
38 suspend_set_ops(&omap_pm_ops);
39--
401.6.6.1
41
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch
new file mode 100644
index 00000000..6c37b622
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch
@@ -0,0 +1,30 @@
1From a22a0dcefe99c8ee260e0c489bc44e6e14bb1ccb Mon Sep 17 00:00:00 2001
2From: Aaro Koskinen <aaro.koskinen@nokia.com>
3Date: Thu, 24 Mar 2011 18:35:31 +0200
4Subject: [PATCH 03/12] OMAP3+: smartreflex: fix sr_late_init() error path in probe
5
6sr_late_init() will take care of freeing the resources.
7
8Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
9Signed-off-by: Kevin Hilman <khilman@ti.com>
10Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
11---
12 arch/arm/mach-omap2/smartreflex.c | 2 +-
13 1 files changed, 1 insertions(+), 1 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
16index 13e24f9..dbc4b6f 100644
17--- a/arch/arm/mach-omap2/smartreflex.c
18+++ b/arch/arm/mach-omap2/smartreflex.c
19@@ -883,7 +883,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
20 ret = sr_late_init(sr_info);
21 if (ret) {
22 pr_warning("%s: Error in SR late init\n", __func__);
23- goto err_release_region;
24+ return ret;
25 }
26 }
27
28--
291.6.6.1
30
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch
new file mode 100644
index 00000000..263094d5
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch
@@ -0,0 +1,36 @@
1From db9c7da6a78be8584c96c83a3a2d1c8aeb623da8 Mon Sep 17 00:00:00 2001
2From: Aaro Koskinen <aaro.koskinen@nokia.com>
3Date: Thu, 24 Mar 2011 18:35:32 +0200
4Subject: [PATCH 04/12] OMAP3+: smartreflex: request the memory region
5
6We are releasing the memory region, but never actually request it.
7
8Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
9Signed-off-by: Kevin Hilman <khilman@ti.com>
10Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
11---
12 arch/arm/mach-omap2/smartreflex.c | 8 ++++++++
13 1 files changed, 8 insertions(+), 0 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
16index dbc4b6f..703143a 100644
17--- a/arch/arm/mach-omap2/smartreflex.c
18+++ b/arch/arm/mach-omap2/smartreflex.c
19@@ -847,6 +847,14 @@ static int __init omap_sr_probe(struct platform_device *pdev)
20 goto err_free_devinfo;
21 }
22
23+ mem = request_mem_region(mem->start, resource_size(mem),
24+ dev_name(&pdev->dev));
25+ if (!mem) {
26+ dev_err(&pdev->dev, "%s: no mem region\n", __func__);
27+ ret = -EBUSY;
28+ goto err_free_devinfo;
29+ }
30+
31 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
32
33 pm_runtime_enable(&pdev->dev);
34--
351.6.6.1
36
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch
new file mode 100644
index 00000000..ea1e5673
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch
@@ -0,0 +1,66 @@
1From b3ca51ac09da7c260c28df396d4c830814697ff0 Mon Sep 17 00:00:00 2001
2From: Aaro Koskinen <aaro.koskinen@nokia.com>
3Date: Thu, 24 Mar 2011 18:35:33 +0200
4Subject: [PATCH 05/12] OMAP3+: smartreflex: fix ioremap leak on probe error
5
6Add missing iounmap() to error paths.
7
8Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
9Signed-off-by: Kevin Hilman <khilman@ti.com>
10Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
11---
12 arch/arm/mach-omap2/smartreflex.c | 10 ++++++----
13 1 files changed, 6 insertions(+), 4 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
16index 703143a..156807e 100644
17--- a/arch/arm/mach-omap2/smartreflex.c
18+++ b/arch/arm/mach-omap2/smartreflex.c
19@@ -904,7 +904,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
20 vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
21 if (!vdd_dbg_dir) {
22 ret = -EINVAL;
23- goto err_release_region;
24+ goto err_iounmap;
25 }
26
27 sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
28@@ -912,7 +912,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
29 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
30 __func__);
31 ret = PTR_ERR(sr_info->dbg_dir);
32- goto err_release_region;
33+ goto err_iounmap;
34 }
35
36 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
37@@ -929,7 +929,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
38 dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
39 "for n-values\n", __func__);
40 ret = PTR_ERR(nvalue_dir);
41- goto err_release_region;
42+ goto err_iounmap;
43 }
44
45 omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
46@@ -939,7 +939,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
47 "entries for n-values\n",
48 __func__, sr_info->voltdm->name);
49 ret = -ENODATA;
50- goto err_release_region;
51+ goto err_iounmap;
52 }
53
54 for (i = 0; i < sr_info->nvalue_count; i++) {
55@@ -953,6 +953,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
56
57 return ret;
58
59+err_iounmap:
60+ iounmap(sr_info->base);
61 err_release_region:
62 release_mem_region(mem->start, resource_size(mem));
63 err_free_devinfo:
64--
651.6.6.1
66
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch
new file mode 100644
index 00000000..cda6da63
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch
@@ -0,0 +1,29 @@
1From 92e63a2f098ce344cfc51ec9a7420e1a5cf85c3e Mon Sep 17 00:00:00 2001
2From: Aaro Koskinen <aaro.koskinen@nokia.com>
3Date: Thu, 24 Mar 2011 18:35:34 +0200
4Subject: [PATCH 06/12] OMAP3+: smartreflex: delete instance from sr_list on probe error
5
6If the probe fails, the node should be deleted from sr_list.
7
8Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
9Signed-off-by: Kevin Hilman <khilman@ti.com>
10Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
11---
12 arch/arm/mach-omap2/smartreflex.c | 1 +
13 1 files changed, 1 insertions(+), 0 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
16index 156807e..f0a488a 100644
17--- a/arch/arm/mach-omap2/smartreflex.c
18+++ b/arch/arm/mach-omap2/smartreflex.c
19@@ -954,6 +954,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
20 return ret;
21
22 err_iounmap:
23+ list_del(&sr_info->node);
24 iounmap(sr_info->base);
25 err_release_region:
26 release_mem_region(mem->start, resource_size(mem));
27--
281.6.6.1
29
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch
new file mode 100644
index 00000000..d4543a46
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch
@@ -0,0 +1,48 @@
1From c194377152df812bcb29fff8f217ffbde59089be Mon Sep 17 00:00:00 2001
2From: Aaro Koskinen <aaro.koskinen@nokia.com>
3Date: Thu, 24 Mar 2011 18:35:35 +0200
4Subject: [PATCH 07/12] OMAP3+: smartreflex: delete debugfs entries on probe error
5
6Delete created debugfs entries if probe fails.
7
8Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
9Signed-off-by: Kevin Hilman <khilman@ti.com>
10Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
11---
12 arch/arm/mach-omap2/smartreflex.c | 6 ++++--
13 1 files changed, 4 insertions(+), 2 deletions(-)
14
15diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
16index f0a488a..fb7dc52 100644
17--- a/arch/arm/mach-omap2/smartreflex.c
18+++ b/arch/arm/mach-omap2/smartreflex.c
19@@ -929,7 +929,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
20 dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
21 "for n-values\n", __func__);
22 ret = PTR_ERR(nvalue_dir);
23- goto err_iounmap;
24+ goto err_debugfs;
25 }
26
27 omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
28@@ -939,7 +939,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
29 "entries for n-values\n",
30 __func__, sr_info->voltdm->name);
31 ret = -ENODATA;
32- goto err_iounmap;
33+ goto err_debugfs;
34 }
35
36 for (i = 0; i < sr_info->nvalue_count; i++) {
37@@ -953,6 +953,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
38
39 return ret;
40
41+err_debugfs:
42+ debugfs_remove_recursive(sr_info->dbg_dir);
43 err_iounmap:
44 list_del(&sr_info->node);
45 iounmap(sr_info->base);
46--
471.6.6.1
48
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch
new file mode 100644
index 00000000..e3ee0412
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch
@@ -0,0 +1,57 @@
1From 2b9e07516cc3853340b5e06e9ae7244ca5681466 Mon Sep 17 00:00:00 2001
2From: Jean Pihet <j-pihet@ti.com>
3Date: Fri, 29 Apr 2011 11:26:22 +0200
4Subject: [PATCH 08/12] OMAP3 cpuidle: remove useless SDP specific timings
5
6The cpuidle states settings can be overriden by some board-
7specific settings, by calling omap3_pm_init_cpuidle.
8Remove the 3430SDP specific states settings registration
9since the figures are identical to the default ones (in cpuidle34xx.c).
10
11Signed-off-by: Jean Pihet <j-pihet@ti.com>
12Signed-off-by: Kevin Hilman <khilman@ti.com>
13Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
14---
15 arch/arm/mach-omap2/board-3430sdp.c | 19 -------------------
16 1 files changed, 0 insertions(+), 19 deletions(-)
17
18diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
19index 9afd087..7ffad7b 100644
20--- a/arch/arm/mach-omap2/board-3430sdp.c
21+++ b/arch/arm/mach-omap2/board-3430sdp.c
22@@ -59,24 +59,6 @@
23
24 #define TWL4030_MSECURE_GPIO 22
25
26-/* FIXME: These values need to be updated based on more profiling on 3430sdp*/
27-static struct cpuidle_params omap3_cpuidle_params_table[] = {
28- /* C1 */
29- {1, 2, 2, 5},
30- /* C2 */
31- {1, 10, 10, 30},
32- /* C3 */
33- {1, 50, 50, 300},
34- /* C4 */
35- {1, 1500, 1800, 4000},
36- /* C5 */
37- {1, 2500, 7500, 12000},
38- /* C6 */
39- {1, 3000, 8500, 15000},
40- /* C7 */
41- {1, 10000, 30000, 300000},
42-};
43-
44 static uint32_t board_keymap[] = {
45 KEY(0, 0, KEY_LEFT),
46 KEY(0, 1, KEY_RIGHT),
47@@ -883,7 +865,6 @@ static void __init omap_3430sdp_init(void)
48 omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
49 omap_board_config = sdp3430_config;
50 omap_board_config_size = ARRAY_SIZE(sdp3430_config);
51- omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
52 omap3430_i2c_init();
53 omap_display_init(&sdp3430_dss_data);
54 if (omap_rev() > OMAP3430_REV_ES1_0)
55--
561.6.6.1
57
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch
new file mode 100644
index 00000000..c44371df
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch
@@ -0,0 +1,48 @@
1From a0f28097b944930e479998780863b9e5a39e30b3 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Mon, 14 Feb 2011 12:16:36 +0530
4Subject: [PATCH 09/12] OMAP3+: SR: make notify independent of class
5
6Interrupt notification mechanism of SmartReflex can be used by the
7choice of implementation of the class driver. For example, Class 2 and
8Class 1.5 of SmartReflex can both use the interrupt notification to
9identify the transition of voltage or other events.
10
11Hence, the actual class does not matter for notifier. Let the class
12driver's handling decide how it should be used. SmartReflex driver
13should provide just the primitives.
14
15Signed-off-by: Nishanth Menon <nm@ti.com>
16Signed-off-by: Kevin Hilman <khilman@ti.com>
17Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
18---
19 arch/arm/mach-omap2/smartreflex.c | 6 ++----
20 1 files changed, 2 insertions(+), 4 deletions(-)
21
22diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
23index fb7dc52..3ee7261 100644
24--- a/arch/arm/mach-omap2/smartreflex.c
25+++ b/arch/arm/mach-omap2/smartreflex.c
26@@ -143,7 +143,7 @@ static irqreturn_t sr_interrupt(int irq, void *data)
27 sr_write_reg(sr_info, IRQSTATUS, status);
28 }
29
30- if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
31+ if (sr_class->notify)
32 sr_class->notify(sr_info->voltdm, status);
33
34 return IRQ_HANDLED;
35@@ -258,9 +258,7 @@ static int sr_late_init(struct omap_sr *sr_info)
36 struct resource *mem;
37 int ret = 0;
38
39- if (sr_class->class_type == SR_CLASS2 &&
40- sr_class->notify_flags && sr_info->irq) {
41-
42+ if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
43 name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
44 if (name == NULL) {
45 ret = -ENOMEM;
46--
471.6.6.1
48
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch
new file mode 100644
index 00000000..e25c3e86
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch
@@ -0,0 +1,37 @@
1From ca5dc57538a566681731102e09a9d1865a4a7020 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Mon, 14 Feb 2011 12:41:10 +0530
4Subject: [PATCH 10/12] OMAP3+: SR: disable interrupt by default
5
6We will enable and disable interrupt on a need basis in the class
7driver. We need to keep the IRQ disabled by default else the
8forceupdate or vcbypass events could trigger events that we don't
9need/expect to handle.
10
11This is a preparation for SmartReflex AVS class drivers such as
12class 2 and class 1.5 which would need to use interrupts. Existing
13SmartReflex AVS class 3 driver does not require to use interrupts
14and is not impacted by this change.
15
16Signed-off-by: Nishanth Menon <nm@ti.com>
17Signed-off-by: Kevin Hilman <khilman@ti.com>
18Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
19---
20 arch/arm/mach-omap2/smartreflex.c | 1 +
21 1 files changed, 1 insertions(+), 0 deletions(-)
22
23diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
24index 3ee7261..616ef62 100644
25--- a/arch/arm/mach-omap2/smartreflex.c
26+++ b/arch/arm/mach-omap2/smartreflex.c
27@@ -268,6 +268,7 @@ static int sr_late_init(struct omap_sr *sr_info)
28 0, name, (void *)sr_info);
29 if (ret)
30 goto error;
31+ disable_irq(sr_info->irq);
32 }
33
34 if (pdata && pdata->enable_on_init)
35--
361.6.6.1
37
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch
new file mode 100644
index 00000000..b96682ea
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch
@@ -0,0 +1,41 @@
1From 4aa67e94d6b13905abcf3e95cb66ea7be9c2e8dd Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Mon, 14 Feb 2011 21:14:17 +0530
4Subject: [PATCH 11/12] OMAP3+: SR: enable/disable SR only on need
5
6Since we already know the state of the autocomp enablement, we can
7see if the requested state is different from the current state and
8enable/disable SR only on the need basis.
9
10Signed-off-by: Nishanth Menon <nm@ti.com>
11Signed-off-by: Kevin Hilman <khilman@ti.com>
12Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
13---
14 arch/arm/mach-omap2/smartreflex.c | 11 +++++++----
15 1 files changed, 7 insertions(+), 4 deletions(-)
16
17diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
18index 616ef62..3bd9fac 100644
19--- a/arch/arm/mach-omap2/smartreflex.c
20+++ b/arch/arm/mach-omap2/smartreflex.c
21@@ -807,10 +807,13 @@ static int omap_sr_autocomp_store(void *data, u64 val)
22 return -EINVAL;
23 }
24
25- if (!val)
26- sr_stop_vddautocomp(sr_info);
27- else
28- sr_start_vddautocomp(sr_info);
29+ /* control enable/disable only if there is a delta in value */
30+ if (sr_info->autocomp_active != val) {
31+ if (!val)
32+ sr_stop_vddautocomp(sr_info);
33+ else
34+ sr_start_vddautocomp(sr_info);
35+ }
36
37 return 0;
38 }
39--
401.6.6.1
41
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch
new file mode 100644
index 00000000..eda76a0d
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch
@@ -0,0 +1,49 @@
1From 0c2089eecdfc3a85a376eddf9c77857f3d575be6 Mon Sep 17 00:00:00 2001
2From: Nishanth Menon <nm@ti.com>
3Date: Mon, 14 Feb 2011 12:33:13 +0530
4Subject: [PATCH 12/12] OMAP3+: SR: fix cosmetic indentation
5
6Error label case seems to have a 2 tab indentation when just 1 is
7necessary.
8
9Signed-off-by: Nishanth Menon <nm@ti.com>
10Signed-off-by: Kevin Hilman <khilman@ti.com>
11Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
12---
13 arch/arm/mach-omap2/smartreflex.c | 20 ++++++++++----------
14 1 files changed, 10 insertions(+), 10 deletions(-)
15
16diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
17index 3bd9fac..2ce2fb7 100644
18--- a/arch/arm/mach-omap2/smartreflex.c
19+++ b/arch/arm/mach-omap2/smartreflex.c
20@@ -277,16 +277,16 @@ static int sr_late_init(struct omap_sr *sr_info)
21 return ret;
22
23 error:
24- iounmap(sr_info->base);
25- mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
26- release_mem_region(mem->start, resource_size(mem));
27- list_del(&sr_info->node);
28- dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
29- "interrupt handler. Smartreflex will"
30- "not function as desired\n", __func__);
31- kfree(name);
32- kfree(sr_info);
33- return ret;
34+ iounmap(sr_info->base);
35+ mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
36+ release_mem_region(mem->start, resource_size(mem));
37+ list_del(&sr_info->node);
38+ dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
39+ "interrupt handler. Smartreflex will"
40+ "not function as desired\n", __func__);
41+ kfree(name);
42+ kfree(sr_info);
43+ return ret;
44 }
45
46 static void sr_v1_disable(struct omap_sr *sr)
47--
481.6.6.1
49