aboutsummaryrefslogtreecommitdiffstats
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 @@
+From 38dd5aadc86725f6018d23679e9daa60ca0a8319 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Thu, 12 May 2011 07:59:52 -0500
+Subject: [PATCH 1/6] OMAP2+: cpufreq: free up table on exit
+
+freq_table allocated by opp_init_cpufreq_table in omap_cpu_init
+needs to be freed in omap_cpu_exit.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index d53ce23..e38ebb8 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -26,6 +26,7 @@
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/opp.h>
++#include <linux/slab.h>
+ #include <linux/cpu.h>
+
+ #include <asm/system.h>
+@@ -216,6 +217,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ static int omap_cpu_exit(struct cpufreq_policy *policy)
+ {
+ clk_exit_cpufreq_table(&freq_table);
++ kfree(freq_table);
++ freq_table = NULL;
+ clk_put(mpu_clk);
+ return 0;
+ }
+--
+1.6.6.1
+
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 @@
+From 5febdc0482e545c2a598f035c5e03931e0c3c808 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Thu, 12 May 2011 08:14:41 -0500
+Subject: [PATCH 2/6] OMAP2+: cpufreq: handle invalid cpufreq table
+
+Handle the case when cpufreq_frequency_table_cpuinfo fails. freq_table
+that we passed failed the internal test of cpufreq generic driver,
+so we should'nt be using the freq_table as such. Instead, warn and
+fallback to clock functions for validation and operation.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 12 ++++++++++--
+ 1 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index e38ebb8..6e3666a 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -182,10 +182,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+- if (!result)
++ if (!result) {
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+- } else {
++ } else {
++ WARN(true, "%s: fallback to clk_round(freq_table=%d)\n",
++ __func__, result);
++ kfree(freq_table);
++ freq_table = NULL;
++ }
++ }
++
++ if (!freq_table) {
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+ VERY_HI_RATE) / 1000;
+--
+1.6.6.1
+
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 @@
+From aef7e862873e6125159a18d22a2e37b1fbab2153 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Thu, 12 May 2011 16:27:45 -0700
+Subject: [PATCH 3/6] OMAP2+: cpufreq: minor comment cleanup
+
+this should probably get squashed in..
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index 6e3666a..45f1e9e 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -84,8 +84,10 @@ static int omap_target(struct cpufreq_policy *policy,
+ if (is_smp() && (num_online_cpus() < NR_CPUS))
+ return ret;
+
+- /* Ensure desired rate is within allowed range. Some govenors
+- * (ondemand) will just pass target_freq=0 to get the minimum. */
++ /*
++ * Ensure desired rate is within allowed range. Some govenors
++ * (ondemand) will just pass target_freq=0 to get the minimum.
++ */
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+ if (target_freq > policy->max)
+--
+1.6.6.1
+
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 @@
+From f231980dbd0f05229f2020e59b7242872576416f Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Fri, 13 May 2011 05:34:35 -0700
+Subject: [PATCH 4/6] OMAP2: cpufreq: use clk_init_cpufreq_table if OPPs not available
+
+OMAP2 does not use OPP tables at the moment for DVFS. Currently,
+we depend on opp table initialization to give us the freq_table,
+which makes sense for OMAP3+. for OMAP2, we should be using
+clk_init_cpufreq_table - so if the opp based frequency table
+initilization fails, fall back to clk_init_cpufreq_table to give
+us the table.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 9 ++++++++-
+ 1 files changed, 8 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index 45f1e9e..854f4b3 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -180,7 +180,13 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ pr_warning("%s: unable to get the mpu device\n", __func__);
+ return -EINVAL;
+ }
+- opp_init_cpufreq_table(mpu_dev, &freq_table);
++
++ /*
++ * if we dont get cpufreq table using opp, use traditional omap2 lookup
++ * as a fallback
++ */
++ if (opp_init_cpufreq_table(mpu_dev, &freq_table))
++ clk_init_cpufreq_table(&freq_table);
+
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+@@ -188,6 +194,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
++ clk_exit_cpufreq_table(&freq_table);
+ WARN(true, "%s: fallback to clk_round(freq_table=%d)\n",
+ __func__, result);
+ kfree(freq_table);
+--
+1.6.6.1
+
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 @@
+From 272d76bcb22b9509ccc1b59d3a62e3930d902d17 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Fri, 13 May 2011 05:43:49 -0700
+Subject: [PATCH 5/6] OMAP2+: cpufreq: use cpufreq_frequency_table_target
+
+Use cpufreq_frequency_table_target for finding the proper target
+instead of seeing if the frequency requested is divisible alone.
+if we have a frequency table, we should restrict ourselves to
+selecting the "approved" frequencies alone and only in the case
+where the frequency table is not available should we attempt at
+closest roundable clock frequency.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 38 ++++++++++++++++++++++--------
+ 1 files changed, 28 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index 854f4b3..d0b4f97 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -77,24 +77,42 @@ static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+ {
+- int i, ret = 0;
++ unsigned int i;
++ int ret = 0;
+ struct cpufreq_freqs freqs;
+
+ /* Changes not allowed until all CPUs are online */
+ if (is_smp() && (num_online_cpus() < NR_CPUS))
+ return ret;
+
+- /*
+- * Ensure desired rate is within allowed range. Some govenors
+- * (ondemand) will just pass target_freq=0 to get the minimum.
+- */
+- if (target_freq < policy->min)
+- target_freq = policy->min;
+- if (target_freq > policy->max)
+- target_freq = policy->max;
++ if (freq_table) {
++ ret = cpufreq_frequency_table_target(policy, freq_table,
++ target_freq, relation, &i);
++ if (ret) {
++ pr_debug("%s: cpu%d: no freq match for %d(ret=%d)\n",
++ __func__, policy->cpu, target_freq, ret);
++ return ret;
++ }
++ freqs.new = freq_table[i].frequency;
++ } else {
++ /*
++ * Ensure desired rate is within allowed range. Some govenors
++ * (ondemand) will just pass target_freq=0 to get the minimum.
++ */
++ if (target_freq < policy->min)
++ target_freq = policy->min;
++ if (target_freq > policy->max)
++ target_freq = policy->max;
++
++ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
++ }
++ if (!freqs.new) {
++ pr_err("%s: cpu%d: no match for freq %d\n", __func__,
++ policy->cpu, target_freq);
++ return -EINVAL;
++ }
+
+ freqs.old = omap_getspeed(policy->cpu);
+- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+ freqs.cpu = policy->cpu;
+
+ if (freqs.old == freqs.new)
+--
+1.6.6.1
+
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 @@
+From 42a384af80e07534913d9002ec8d9caf5d4d305c Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Wed, 18 May 2011 01:48:23 -0500
+Subject: [PATCH 6/6] OMAP2+: cpufreq: fix freq_table leak
+
+Since we have two cpus the cpuinit call for cpu1 causes
+freq_table of cpu0 to be overwritten. instead, we maintain
+a counter to keep track of cpus who use the cpufreq table
+allocate it once(one freq table for all CPUs) and free them
+once the last user is done with it.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 33 ++++++++++++++++++++++++------
+ 1 files changed, 26 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index d0b4f97..fc3d0fb 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -42,6 +42,9 @@
+ #define VERY_HI_RATE 900000000
+
+ static struct cpufreq_frequency_table *freq_table;
++static int freq_table_users;
++static DEFINE_MUTEX(freq_table_lock);
++
+ static struct clk *mpu_clk;
+
+ static int omap_verify_speed(struct cpufreq_policy *policy)
+@@ -172,6 +175,18 @@ skip_lpj:
+ return ret;
+ }
+
++static void freq_table_free(void)
++{
++ if (!freq_table_users)
++ return;
++ freq_table_users--;
++ if (freq_table_users)
++ return;
++ clk_exit_cpufreq_table(&freq_table);
++ kfree(freq_table);
++ freq_table = NULL;
++}
++
+ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ {
+ int result = 0;
+@@ -199,14 +214,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ return -EINVAL;
+ }
+
++ mutex_lock(&freq_table_lock);
+ /*
+ * if we dont get cpufreq table using opp, use traditional omap2 lookup
+ * as a fallback
+ */
+- if (opp_init_cpufreq_table(mpu_dev, &freq_table))
+- clk_init_cpufreq_table(&freq_table);
++ if (!freq_table) {
++ if (opp_init_cpufreq_table(mpu_dev, &freq_table))
++ clk_init_cpufreq_table(&freq_table);
++ }
+
+ if (freq_table) {
++ freq_table_users++;
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result) {
+ cpufreq_frequency_table_get_attr(freq_table,
+@@ -215,10 +234,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ clk_exit_cpufreq_table(&freq_table);
+ WARN(true, "%s: fallback to clk_round(freq_table=%d)\n",
+ __func__, result);
+- kfree(freq_table);
+- freq_table = NULL;
++ freq_table_free();
+ }
+ }
++ mutex_unlock(&freq_table_lock);
+
+ if (!freq_table) {
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+@@ -251,9 +270,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+
+ static int omap_cpu_exit(struct cpufreq_policy *policy)
+ {
+- clk_exit_cpufreq_table(&freq_table);
+- kfree(freq_table);
+- freq_table = NULL;
++ mutex_lock(&freq_table_lock);
++ freq_table_free();
++ mutex_unlock(&freq_table_lock);
+ clk_put(mpu_clk);
+ return 0;
+ }
+--
+1.6.6.1
+
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 @@
+From 8726f3a7218b72a1003904a24bb000b3e4f9b4d1 Mon Sep 17 00:00:00 2001
+From: Mike Turquette <mturquette@ti.com>
+Date: Tue, 17 May 2011 09:35:54 -0500
+Subject: [PATCH 1/2] cpufreq: helpers for walking the frequency table
+
+Two new functions for getting the next higher and next lower frequencies
+in the cpufreq table, based upon a frequency supplied in kHz.
+
+This is useful for cpufreq governors that do not target frequencies
+based upon a percentage or a pre-determined value, but instead access
+the cpufreq table directly.
+
+Signed-off-by: Mike Turquette <mturquette@ti.com>
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ drivers/cpufreq/freq_table.c | 73 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/cpufreq.h | 9 +++++
+ 2 files changed, 82 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
+index 0543221..11a307b 100644
+--- a/drivers/cpufreq/freq_table.c
++++ b/drivers/cpufreq/freq_table.c
+@@ -13,6 +13,7 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/cpufreq.h>
++#include <linux/err.h>
+
+ #define dprintk(msg...) \
+ cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
+@@ -174,6 +175,78 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+ }
+ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
+
++int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy,
++ struct cpufreq_frequency_table *table, int *index)
++{
++ unsigned int cur_freq;
++ unsigned int next_lowest_freq;
++ int optimal_index = -1;
++ int i = 0;
++
++ if (!policy || IS_ERR(policy) || !table || IS_ERR(table) ||
++ !index || IS_ERR(index))
++ return -ENOMEM;
++
++ cur_freq = policy->cur;
++ next_lowest_freq = policy->min;
++
++ /* we're at the lowest frequency in the table already, bail out */
++ if (cur_freq == policy->min)
++ return -EINVAL;
++
++ /* walk the list, find closest freq to cur_freq that is below it */
++ while(table[i].frequency != CPUFREQ_TABLE_END) {
++ if (table[i].frequency < cur_freq &&
++ table[i].frequency >= next_lowest_freq) {
++ next_lowest_freq = table[i].frequency;
++ optimal_index = table[i].index;
++ }
++
++ i++;
++ }
++
++ *index = optimal_index;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_lowest);
++
++int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy,
++ struct cpufreq_frequency_table *table, int *index)
++{
++ unsigned int cur_freq;
++ unsigned int next_higher_freq;
++ int optimal_index = -1;
++ int i = 0;
++
++ if (!policy || IS_ERR(policy) || !table || IS_ERR(table) ||
++ !index || IS_ERR(index))
++ return -ENOMEM;
++
++ cur_freq = policy->cur;
++ next_higher_freq = policy->max;
++
++ /* we're at the highest frequency in the table already, bail out */
++ if (cur_freq == policy->max)
++ return -EINVAL;
++
++ /* walk the list, find closest freq to cur_freq that is above it */
++ while(table[i].frequency != CPUFREQ_TABLE_END) {
++ if (table[i].frequency > cur_freq &&
++ table[i].frequency <= next_higher_freq) {
++ next_higher_freq = table[i].frequency;
++ optimal_index = table[i].index;
++ }
++
++ i++;
++ }
++
++ *index = optimal_index;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_highest);
++
+ static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table);
+ /**
+ * show_available_freqs - show available frequencies for the specified CPU
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index 9343dd3..a38fca8 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -396,6 +396,15 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
+
+ void cpufreq_frequency_table_put_attr(unsigned int cpu);
+
++/* the following are for use in governors, or anywhere else */
++extern int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy,
++ struct cpufreq_frequency_table *table,
++ int *index);
++
++extern int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy,
++ struct cpufreq_frequency_table *table,
++ int *index);
++
+
+ /*********************************************************************
+ * UNIFIED DEBUG HELPERS *
+--
+1.6.6.1
+
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 @@
+From e4c777d8314d7925e4895f00b3a7ebd64a4d830b Mon Sep 17 00:00:00 2001
+From: Mike Turquette <mturquette@ti.com>
+Date: Tue, 17 May 2011 09:43:09 -0500
+Subject: [PATCH 2/2] cpufreq: introduce hotplug governor
+
+The "hotplug" governor scales CPU frequency based on load, similar to
+"ondemand". It scales up to the highest frequency when "up_threshold"
+is crossed and scales down one frequency at a time when "down_threshold"
+is crossed. Unlike those governors, target frequencies are determined
+by directly accessing the CPUfreq frequency table, instead of taking
+some percentage of maximum available frequency.
+
+The key difference in the "hotplug" governor is that it will disable
+auxillary CPUs when the system is very idle, and enable them again once
+the system becomes busy. This is achieved by averaging load over
+multiple sampling periods; if CPUs were online or offlined based on a
+single sampling period then thrashing will occur.
+
+Sysfs entries exist for "hotplug_in_sampling_periods" and for
+"hotplug_out_sampling_periods" which determine how many consecutive
+periods get averaged to determine if auxillery CPUs should be onlined or
+offlined. Defaults are 5 periods and 20 periods respectively.
+Otherwise the standard sysfs entries you might find for "ondemand" and
+"conservative" governors are there.
+
+To use this governor it is assumed that your CPUfreq driver has
+populated the CPUfreq table, CONFIG_NO_HZ is enabled and
+CONFIG_HOTPLUG_CPU is enabled.
+
+Changes in V2:
+ Corrected default sampling periods
+ Optimized load history array resizing
+ Maintain load history when resizing array
+ Add locking to dbs_check_cpu
+ Switch from enable_nonboot_cpus to cpu_up
+ Switch from disable_nonboot_cpus to down_cpu
+ Fix some printks
+ Coding style around for-loops
+
+Signed-off-by: Mike Turquette <mturquette@ti.com>
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ Documentation/cpu-freq/governors.txt | 28 ++
+ drivers/cpufreq/Kconfig | 33 ++
+ drivers/cpufreq/Makefile | 1 +
+ drivers/cpufreq/cpufreq_hotplug.c | 705 ++++++++++++++++++++++++++++++++++
+ include/linux/cpufreq.h | 3 +
+ 5 files changed, 770 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/cpufreq/cpufreq_hotplug.c
+
+diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
+index e74d0a2..c2e3d3d 100644
+--- a/Documentation/cpu-freq/governors.txt
++++ b/Documentation/cpu-freq/governors.txt
+@@ -193,6 +193,34 @@ governor but for the opposite direction. For example when set to its
+ default value of '20' it means that if the CPU usage needs to be below
+ 20% between samples to have the frequency decreased.
+
++
++2.6 Hotplug
++-----------
++
++The CPUfreq governor "hotplug" operates similary to "ondemand" and
++"conservative". It's decisions are based primarily on CPU load. Like
++"ondemand" the "hotplug" governor will ramp up to the highest frequency
++once the run-time tunable "up_threshold" parameter is crossed. Like
++"conservative", the "hotplug" governor exports a "down_threshold"
++parameter that is also tunable at run-time. When the "down_threshold"
++is crossed the CPU transitions to the next lowest frequency in the
++CPUfreq frequency table instead of decrementing the frequency based on a
++percentage of maximum load.
++
++The main reason "hotplug" governor exists is for architectures requiring
++that only the master CPU be online in order to hit low-power states
++(C-states). OMAP4 is one such example of this. The "hotplug" governor
++is also helpful in reducing thermal output in devices with tight thermal
++constraints.
++
++Auxillary CPUs are onlined/offline based on CPU load, but the decision
++to do so is made after averaging several sampling windows. This is to
++reduce CPU hotplug "thrashing", which can be caused by normal system
++entropy and leads to lots of spurious plug-in and plug-out transitions.
++The number of sampling periods averaged together is tunable via the
++"hotplug_in_sampling_periods" and "hotplug_out_sampling_periods"
++run-time tunable parameters.
++
+ 3. The Governor Interface in the CPUfreq Core
+ =============================================
+
+diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
+index ca8ee80..c716a0e 100644
+--- a/drivers/cpufreq/Kconfig
++++ b/drivers/cpufreq/Kconfig
+@@ -110,6 +110,19 @@ config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
+ Be aware that not all cpufreq drivers support the conservative
+ governor. If unsure have a look at the help section of the
+ driver. Fallback governor will be the performance governor.
++
++config CPU_FREQ_DEFAULT_GOV_HOTPLUG
++ bool "hotplug"
++ select CPU_FREQ_GOV_HOTPLUG
++ select CPU_FREQ_GOV_PERFORMANCE
++ help
++ Use the CPUFreq governor 'hotplug' as default. This allows you
++ to get a full dynamic frequency capable system with CPU
++ hotplug support by simply loading your cpufreq low-level
++ hardware driver. Be aware that not all cpufreq drivers
++ support the hotplug governor. If unsure have a look at
++ the help section of the driver. Fallback governor will be the
++ performance governor.
+ endchoice
+
+ config CPU_FREQ_GOV_PERFORMANCE
+@@ -190,4 +203,24 @@ config CPU_FREQ_GOV_CONSERVATIVE
+
+ If in doubt, say N.
+
++config CPU_FREQ_GOV_HOTPLUG
++ tristate "'hotplug' cpufreq governor"
++ depends on CPU_FREQ && NO_HZ && HOTPLUG_CPU
++ help
++ 'hotplug' - this driver mimics the frequency scaling behavior
++ in 'ondemand', but with several key differences. First is
++ that frequency transitions use the CPUFreq table directly,
++ instead of incrementing in a percentage of the maximum
++ available frequency. Second 'hotplug' will offline auxillary
++ CPUs when the system is idle, and online those CPUs once the
++ system becomes busy again. This last feature is needed for
++ architectures which transition to low power states when only
++ the "master" CPU is online, or for thermally constrained
++ devices.
++
++ If you don't have one of these architectures or devices, use
++ 'ondemand' instead.
++
++ If in doubt, say N.
++
+ endif # CPU_FREQ
+diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
+index 71fc3b4..05d564c 100644
+--- a/drivers/cpufreq/Makefile
++++ b/drivers/cpufreq/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
+ obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o
+ obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o
+ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o
++obj-$(CONFIG_CPU_FREQ_GOV_HOTPLUG) += cpufreq_hotplug.o
+
+ # CPUfreq cross-arch helpers
+ obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
+diff --git a/drivers/cpufreq/cpufreq_hotplug.c b/drivers/cpufreq/cpufreq_hotplug.c
+new file mode 100644
+index 0000000..85aa6d2
+--- /dev/null
++++ b/drivers/cpufreq/cpufreq_hotplug.c
+@@ -0,0 +1,705 @@
++/*
++ * CPUFreq hotplug governor
++ *
++ * Copyright (C) 2010 Texas Instruments, Inc.
++ * Mike Turquette <mturquette@ti.com>
++ * Santosh Shilimkar <santosh.shilimkar@ti.com>
++ *
++ * Based on ondemand governor
++ * Copyright (C) 2001 Russell King
++ * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>,
++ * Jun Nakajima <jun.nakajima@intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/cpufreq.h>
++#include <linux/cpu.h>
++#include <linux/jiffies.h>
++#include <linux/kernel_stat.h>
++#include <linux/mutex.h>
++#include <linux/hrtimer.h>
++#include <linux/tick.h>
++#include <linux/ktime.h>
++#include <linux/sched.h>
++#include <linux/err.h>
++#include <linux/slab.h>
++
++/* greater than 80% avg load across online CPUs increases frequency */
++#define DEFAULT_UP_FREQ_MIN_LOAD (80)
++
++/* less than 20% avg load across online CPUs decreases frequency */
++#define DEFAULT_DOWN_FREQ_MAX_LOAD (20)
++
++/* default sampling period (uSec) is bogus; 10x ondemand's default for x86 */
++#define DEFAULT_SAMPLING_PERIOD (100000)
++
++/* default number of sampling periods to average before hotplug-in decision */
++#define DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS (5)
++
++/* default number of sampling periods to average before hotplug-out decision */
++#define DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS (20)
++
++static void do_dbs_timer(struct work_struct *work);
++static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
++ unsigned int event);
++
++#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG
++static
++#endif
++struct cpufreq_governor cpufreq_gov_hotplug = {
++ .name = "hotplug",
++ .governor = cpufreq_governor_dbs,
++ .owner = THIS_MODULE,
++};
++
++struct cpu_dbs_info_s {
++ cputime64_t prev_cpu_idle;
++ cputime64_t prev_cpu_wall;
++ cputime64_t prev_cpu_nice;
++ struct cpufreq_policy *cur_policy;
++ struct delayed_work work;
++ struct cpufreq_frequency_table *freq_table;
++ int cpu;
++ /*
++ * percpu mutex that serializes governor limit change with
++ * do_dbs_timer invocation. We do not want do_dbs_timer to run
++ * when user is changing the governor or limits.
++ */
++ struct mutex timer_mutex;
++};
++static DEFINE_PER_CPU(struct cpu_dbs_info_s, hp_cpu_dbs_info);
++
++static unsigned int dbs_enable; /* number of CPUs using this policy */
++
++/*
++ * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on
++ * different CPUs. It protects dbs_enable in governor start/stop.
++ */
++static DEFINE_MUTEX(dbs_mutex);
++
++static struct workqueue_struct *khotplug_wq;
++
++static struct dbs_tuners {
++ unsigned int sampling_rate;
++ unsigned int up_threshold;
++ unsigned int down_threshold;
++ unsigned int hotplug_in_sampling_periods;
++ unsigned int hotplug_out_sampling_periods;
++ unsigned int hotplug_load_index;
++ unsigned int *hotplug_load_history;
++ unsigned int ignore_nice;
++ unsigned int io_is_busy;
++} dbs_tuners_ins = {
++ .sampling_rate = DEFAULT_SAMPLING_PERIOD,
++ .up_threshold = DEFAULT_UP_FREQ_MIN_LOAD,
++ .down_threshold = DEFAULT_DOWN_FREQ_MAX_LOAD,
++ .hotplug_in_sampling_periods = DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS,
++ .hotplug_out_sampling_periods = DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS,
++ .hotplug_load_index = 0,
++ .ignore_nice = 0,
++ .io_is_busy = 0,
++};
++
++/*
++ * A corner case exists when switching io_is_busy at run-time: comparing idle
++ * times from a non-io_is_busy period to an io_is_busy period (or vice-versa)
++ * will misrepresent the actual change in system idleness. We ignore this
++ * corner case: enabling io_is_busy might cause freq increase and disabling
++ * might cause freq decrease, which probably matches the original intent.
++ */
++static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
++{
++ u64 idle_time;
++ u64 iowait_time;
++
++ /* cpufreq-hotplug always assumes CONFIG_NO_HZ */
++ idle_time = get_cpu_idle_time_us(cpu, wall);
++
++ /* add time spent doing I/O to idle time */
++ if (dbs_tuners_ins.io_is_busy) {
++ iowait_time = get_cpu_iowait_time_us(cpu, wall);
++ /* cpufreq-hotplug always assumes CONFIG_NO_HZ */
++ if (iowait_time != -1ULL && idle_time >= iowait_time)
++ idle_time -= iowait_time;
++ }
++
++ return idle_time;
++}
++
++/************************** sysfs interface ************************/
++
++/* XXX look at global sysfs macros in cpufreq.h, can those be used here? */
++
++/* cpufreq_hotplug Governor Tunables */
++#define show_one(file_name, object) \
++static ssize_t show_##file_name \
++(struct kobject *kobj, struct attribute *attr, char *buf) \
++{ \
++ return sprintf(buf, "%u\n", dbs_tuners_ins.object); \
++}
++show_one(sampling_rate, sampling_rate);
++show_one(up_threshold, up_threshold);
++show_one(down_threshold, down_threshold);
++show_one(hotplug_in_sampling_periods, hotplug_in_sampling_periods);
++show_one(hotplug_out_sampling_periods, hotplug_out_sampling_periods);
++show_one(ignore_nice_load, ignore_nice);
++show_one(io_is_busy, io_is_busy);
++
++static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
++ const char *buf, size_t count)
++{
++ unsigned int input;
++ int ret;
++ ret = sscanf(buf, "%u", &input);
++ if (ret != 1)
++ return -EINVAL;
++
++ mutex_lock(&dbs_mutex);
++ dbs_tuners_ins.sampling_rate = input;
++ mutex_unlock(&dbs_mutex);
++
++ return count;
++}
++
++static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
++ const char *buf, size_t count)
++{
++ unsigned int input;
++ int ret;
++ ret = sscanf(buf, "%u", &input);
++
++ if (ret != 1 || input <= dbs_tuners_ins.down_threshold) {
++ return -EINVAL;
++ }
++
++ mutex_lock(&dbs_mutex);
++ dbs_tuners_ins.up_threshold = input;
++ mutex_unlock(&dbs_mutex);
++
++ return count;
++}
++
++static ssize_t store_down_threshold(struct kobject *a, struct attribute *b,
++ const char *buf, size_t count)
++{
++ unsigned int input;
++ int ret;
++ ret = sscanf(buf, "%u", &input);
++
++ if (ret != 1 || input >= dbs_tuners_ins.up_threshold) {
++ return -EINVAL;
++ }
++
++ mutex_lock(&dbs_mutex);
++ dbs_tuners_ins.down_threshold = input;
++ mutex_unlock(&dbs_mutex);
++
++ return count;
++}
++
++static ssize_t store_hotplug_in_sampling_periods(struct kobject *a,
++ struct attribute *b, const char *buf, size_t count)
++{
++ unsigned int input;
++ unsigned int *temp;
++ unsigned int max_windows;
++ int ret;
++ ret = sscanf(buf, "%u", &input);
++
++ if (ret != 1)
++ return -EINVAL;
++
++ /* already using this value, bail out */
++ if (input == dbs_tuners_ins.hotplug_in_sampling_periods)
++ return count;
++
++ mutex_lock(&dbs_mutex);
++ ret = count;
++ max_windows = max(dbs_tuners_ins.hotplug_in_sampling_periods,
++ dbs_tuners_ins.hotplug_out_sampling_periods);
++
++ /* no need to resize array */
++ if (input <= max_windows) {
++ dbs_tuners_ins.hotplug_in_sampling_periods = input;
++ goto out;
++ }
++
++ /* resize array */
++ temp = kmalloc((sizeof(unsigned int) * input), GFP_KERNEL);
++
++ if (!temp || IS_ERR(temp)) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ memcpy(temp, dbs_tuners_ins.hotplug_load_history,
++ (max_windows * sizeof(unsigned int)));
++ kfree(dbs_tuners_ins.hotplug_load_history);
++
++ /* replace old buffer, old number of sampling periods & old index */
++ dbs_tuners_ins.hotplug_load_history = temp;
++ dbs_tuners_ins.hotplug_in_sampling_periods = input;
++ dbs_tuners_ins.hotplug_load_index = max_windows;
++out:
++ mutex_unlock(&dbs_mutex);
++
++ return ret;
++}
++
++static ssize_t store_hotplug_out_sampling_periods(struct kobject *a,
++ struct attribute *b, const char *buf, size_t count)
++{
++ unsigned int input;
++ unsigned int *temp;
++ unsigned int max_windows;
++ int ret;
++ ret = sscanf(buf, "%u", &input);
++
++ if (ret != 1)
++ return -EINVAL;
++
++ /* already using this value, bail out */
++ if (input == dbs_tuners_ins.hotplug_out_sampling_periods)
++ return count;
++
++ mutex_lock(&dbs_mutex);
++ ret = count;
++ max_windows = max(dbs_tuners_ins.hotplug_in_sampling_periods,
++ dbs_tuners_ins.hotplug_out_sampling_periods);
++
++ /* no need to resize array */
++ if (input <= max_windows) {
++ dbs_tuners_ins.hotplug_out_sampling_periods = input;
++ goto out;
++ }
++
++ /* resize array */
++ temp = kmalloc((sizeof(unsigned int) * input), GFP_KERNEL);
++
++ if (!temp || IS_ERR(temp)) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ memcpy(temp, dbs_tuners_ins.hotplug_load_history,
++ (max_windows * sizeof(unsigned int)));
++ kfree(dbs_tuners_ins.hotplug_load_history);
++
++ /* replace old buffer, old number of sampling periods & old index */
++ dbs_tuners_ins.hotplug_load_history = temp;
++ dbs_tuners_ins.hotplug_out_sampling_periods = input;
++ dbs_tuners_ins.hotplug_load_index = max_windows;
++out:
++ mutex_unlock(&dbs_mutex);
++
++ return ret;
++}
++
++static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
++ const char *buf, size_t count)
++{
++ unsigned int input;
++ int ret;
++
++ unsigned int j;
++
++ ret = sscanf(buf, "%u", &input);
++ if (ret != 1)
++ return -EINVAL;
++
++ if (input > 1)
++ input = 1;
++
++ mutex_lock(&dbs_mutex);
++ if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
++ mutex_unlock(&dbs_mutex);
++ return count;
++ }
++ dbs_tuners_ins.ignore_nice = input;
++
++ /* we need to re-evaluate prev_cpu_idle */
++ for_each_online_cpu(j) {
++ struct cpu_dbs_info_s *dbs_info;
++ dbs_info = &per_cpu(hp_cpu_dbs_info, j);
++ dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
++ &dbs_info->prev_cpu_wall);
++ if (dbs_tuners_ins.ignore_nice)
++ dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
++
++ }
++ mutex_unlock(&dbs_mutex);
++
++ return count;
++}
++
++static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
++ const char *buf, size_t count)
++{
++ unsigned int input;
++ int ret;
++
++ ret = sscanf(buf, "%u", &input);
++ if (ret != 1)
++ return -EINVAL;
++
++ mutex_lock(&dbs_mutex);
++ dbs_tuners_ins.io_is_busy = !!input;
++ mutex_unlock(&dbs_mutex);
++
++ return count;
++}
++
++define_one_global_rw(sampling_rate);
++define_one_global_rw(up_threshold);
++define_one_global_rw(down_threshold);
++define_one_global_rw(hotplug_in_sampling_periods);
++define_one_global_rw(hotplug_out_sampling_periods);
++define_one_global_rw(ignore_nice_load);
++define_one_global_rw(io_is_busy);
++
++static struct attribute *dbs_attributes[] = {
++ &sampling_rate.attr,
++ &up_threshold.attr,
++ &down_threshold.attr,
++ &hotplug_in_sampling_periods.attr,
++ &hotplug_out_sampling_periods.attr,
++ &ignore_nice_load.attr,
++ &io_is_busy.attr,
++ NULL
++};
++
++static struct attribute_group dbs_attr_group = {
++ .attrs = dbs_attributes,
++ .name = "hotplug",
++};
++
++/************************** sysfs end ************************/
++
++static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
++{
++ /* combined load of all enabled CPUs */
++ unsigned int total_load = 0;
++ /* single largest CPU load */
++ unsigned int max_load = 0;
++ /* average load across all enabled CPUs */
++ unsigned int avg_load = 0;
++ /* average load across multiple sampling periods for hotplug events */
++ unsigned int hotplug_in_avg_load = 0;
++ unsigned int hotplug_out_avg_load = 0;
++ /* number of sampling periods averaged for hotplug decisions */
++ unsigned int periods;
++
++ struct cpufreq_policy *policy;
++ unsigned int index = 0;
++ unsigned int i, j;
++
++ policy = this_dbs_info->cur_policy;
++
++ /*
++ * cpu load accounting
++ * get highest load, total load and average load across all CPUs
++ */
++ for_each_cpu(j, policy->cpus) {
++ unsigned int load;
++ unsigned int idle_time, wall_time;
++ cputime64_t cur_wall_time, cur_idle_time;
++ struct cpu_dbs_info_s *j_dbs_info;
++
++ j_dbs_info = &per_cpu(hp_cpu_dbs_info, j);
++
++ /* update both cur_idle_time and cur_wall_time */
++ cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
++
++ /* how much wall time has passed since last iteration? */
++ wall_time = (unsigned int) cputime64_sub(cur_wall_time,
++ j_dbs_info->prev_cpu_wall);
++ j_dbs_info->prev_cpu_wall = cur_wall_time;
++
++ /* how much idle time has passed since last iteration? */
++ idle_time = (unsigned int) cputime64_sub(cur_idle_time,
++ j_dbs_info->prev_cpu_idle);
++ j_dbs_info->prev_cpu_idle = cur_idle_time;
++
++ if (unlikely(!wall_time || wall_time < idle_time))
++ continue;
++
++ /* load is the percentage of time not spent in idle */
++ load = 100 * (wall_time - idle_time) / wall_time;
++
++ /* keep track of combined load across all CPUs */
++ total_load += load;
++
++ /* keep track of highest single load across all CPUs */
++ if (load > max_load)
++ max_load = load;
++ }
++
++ /* calculate the average load across all related CPUs */
++ avg_load = total_load / num_online_cpus();
++
++
++ /*
++ * hotplug load accounting
++ * average load over multiple sampling periods
++ */
++
++ /* how many sampling periods do we use for hotplug decisions? */
++ periods = max(dbs_tuners_ins.hotplug_in_sampling_periods,
++ dbs_tuners_ins.hotplug_out_sampling_periods);
++
++ /* store avg_load in the circular buffer */
++ dbs_tuners_ins.hotplug_load_history[dbs_tuners_ins.hotplug_load_index]
++ = avg_load;
++
++ /* compute average load across in & out sampling periods */
++ for (i = 0, j = dbs_tuners_ins.hotplug_load_index;
++ i < periods; i++, j--) {
++ if (i < dbs_tuners_ins.hotplug_in_sampling_periods)
++ hotplug_in_avg_load +=
++ dbs_tuners_ins.hotplug_load_history[j];
++ if (i < dbs_tuners_ins.hotplug_out_sampling_periods)
++ hotplug_out_avg_load +=
++ dbs_tuners_ins.hotplug_load_history[j];
++
++ if (j == 0)
++ j = periods;
++ }
++
++ hotplug_in_avg_load = hotplug_in_avg_load /
++ dbs_tuners_ins.hotplug_in_sampling_periods;
++
++ hotplug_out_avg_load = hotplug_out_avg_load /
++ dbs_tuners_ins.hotplug_out_sampling_periods;
++
++ /* return to first element if we're at the circular buffer's end */
++ if (++dbs_tuners_ins.hotplug_load_index == periods)
++ dbs_tuners_ins.hotplug_load_index = 0;
++
++ /* check for frequency increase */
++ if (avg_load > dbs_tuners_ins.up_threshold) {
++ /* should we enable auxillary CPUs? */
++ if (num_online_cpus() < 2 && hotplug_in_avg_load >
++ dbs_tuners_ins.up_threshold) {
++ /* hotplug with cpufreq is nasty
++ * a call to cpufreq_governor_dbs may cause a lockup.
++ * wq is not running here so its safe.
++ */
++ mutex_unlock(&this_dbs_info->timer_mutex);
++ cpu_up(1);
++ mutex_lock(&this_dbs_info->timer_mutex);
++ goto out;
++ }
++
++ /* increase to highest frequency supported */
++ if (policy->cur < policy->max)
++ __cpufreq_driver_target(policy, policy->max,
++ CPUFREQ_RELATION_H);
++
++ goto out;
++ }
++
++ /* check for frequency decrease */
++ if (avg_load < dbs_tuners_ins.down_threshold) {
++ /* are we at the minimum frequency already? */
++ if (policy->cur == policy->min) {
++ /* should we disable auxillary CPUs? */
++ if (num_online_cpus() > 1 && hotplug_out_avg_load <
++ dbs_tuners_ins.down_threshold) {
++ mutex_unlock(&this_dbs_info->timer_mutex);
++ cpu_down(1);
++ mutex_lock(&this_dbs_info->timer_mutex);
++ }
++ goto out;
++ }
++
++ /* bump down to the next lowest frequency in the table */
++ if (cpufreq_frequency_table_next_lowest(policy,
++ this_dbs_info->freq_table, &index)) {
++ pr_err("%s: failed to get next lowest frequency\n",
++ __func__);
++ goto out;
++ }
++
++ __cpufreq_driver_target(policy,
++ this_dbs_info->freq_table[index].frequency,
++ CPUFREQ_RELATION_L);
++ }
++out:
++ return;
++}
++
++static void do_dbs_timer(struct work_struct *work)
++{
++ struct cpu_dbs_info_s *dbs_info =
++ container_of(work, struct cpu_dbs_info_s, work.work);
++ unsigned int cpu = dbs_info->cpu;
++
++ /* We want all related CPUs to do sampling nearly on same jiffy */
++ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
++
++ mutex_lock(&dbs_info->timer_mutex);
++ dbs_check_cpu(dbs_info);
++ queue_delayed_work_on(cpu, khotplug_wq, &dbs_info->work, delay);
++ mutex_unlock(&dbs_info->timer_mutex);
++}
++
++static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
++{
++ /* We want all related CPUs to do sampling nearly on same jiffy */
++ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
++ delay -= jiffies % delay;
++
++ INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
++ queue_delayed_work_on(dbs_info->cpu, khotplug_wq, &dbs_info->work,
++ delay);
++}
++
++static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
++{
++ cancel_delayed_work_sync(&dbs_info->work);
++}
++
++static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
++ unsigned int event)
++{
++ unsigned int cpu = policy->cpu;
++ struct cpu_dbs_info_s *this_dbs_info;
++ unsigned int i, j, max_periods;
++ int rc;
++
++ this_dbs_info = &per_cpu(hp_cpu_dbs_info, cpu);
++
++ switch (event) {
++ case CPUFREQ_GOV_START:
++ if ((!cpu_online(cpu)) || (!policy->cur))
++ return -EINVAL;
++
++ mutex_lock(&dbs_mutex);
++ dbs_enable++;
++ for_each_cpu(j, policy->cpus) {
++ struct cpu_dbs_info_s *j_dbs_info;
++ j_dbs_info = &per_cpu(hp_cpu_dbs_info, j);
++ j_dbs_info->cur_policy = policy;
++
++ j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
++ &j_dbs_info->prev_cpu_wall);
++ if (dbs_tuners_ins.ignore_nice) {
++ j_dbs_info->prev_cpu_nice =
++ kstat_cpu(j).cpustat.nice;
++ }
++
++ max_periods = max(DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS,
++ DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS);
++ dbs_tuners_ins.hotplug_load_history = kmalloc(
++ (sizeof(unsigned int) * max_periods),
++ GFP_KERNEL);
++ if (!dbs_tuners_ins.hotplug_load_history) {
++ WARN_ON(1);
++ return -ENOMEM;
++ }
++ for (i = 0; i < max_periods; i++)
++ dbs_tuners_ins.hotplug_load_history[i] = 50;
++ }
++ this_dbs_info->cpu = cpu;
++ this_dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
++ /*
++ * Start the timerschedule work, when this governor
++ * is used for first time
++ */
++ if (dbs_enable == 1) {
++ rc = sysfs_create_group(cpufreq_global_kobject,
++ &dbs_attr_group);
++ if (rc) {
++ mutex_unlock(&dbs_mutex);
++ return rc;
++ }
++ }
++ mutex_unlock(&dbs_mutex);
++
++ mutex_init(&this_dbs_info->timer_mutex);
++ dbs_timer_init(this_dbs_info);
++ break;
++
++ case CPUFREQ_GOV_STOP:
++ dbs_timer_exit(this_dbs_info);
++
++ mutex_lock(&dbs_mutex);
++ mutex_destroy(&this_dbs_info->timer_mutex);
++ dbs_enable--;
++ mutex_unlock(&dbs_mutex);
++ if (!dbs_enable)
++ sysfs_remove_group(cpufreq_global_kobject,
++ &dbs_attr_group);
++ kfree(dbs_tuners_ins.hotplug_load_history);
++ /*
++ * XXX BIG CAVEAT: Stopping the governor with CPU1 offline
++ * will result in it remaining offline until the user onlines
++ * it again. It is up to the user to do this (for now).
++ */
++ break;
++
++ case CPUFREQ_GOV_LIMITS:
++ mutex_lock(&this_dbs_info->timer_mutex);
++ if (policy->max < this_dbs_info->cur_policy->cur)
++ __cpufreq_driver_target(this_dbs_info->cur_policy,
++ policy->max, CPUFREQ_RELATION_H);
++ else if (policy->min > this_dbs_info->cur_policy->cur)
++ __cpufreq_driver_target(this_dbs_info->cur_policy,
++ policy->min, CPUFREQ_RELATION_L);
++ mutex_unlock(&this_dbs_info->timer_mutex);
++ break;
++ }
++ return 0;
++}
++
++static int __init cpufreq_gov_dbs_init(void)
++{
++ int err;
++ cputime64_t wall;
++ u64 idle_time;
++ int cpu = get_cpu();
++
++ idle_time = get_cpu_idle_time_us(cpu, &wall);
++ put_cpu();
++ if (idle_time != -1ULL) {
++ dbs_tuners_ins.up_threshold = DEFAULT_UP_FREQ_MIN_LOAD;
++ } else {
++ pr_err("cpufreq-hotplug: %s: assumes CONFIG_NO_HZ\n",
++ __func__);
++ return -EINVAL;
++ }
++
++ khotplug_wq = create_workqueue("khotplug");
++ if (!khotplug_wq) {
++ pr_err("Creation of khotplug failed\n");
++ return -EFAULT;
++ }
++ err = cpufreq_register_governor(&cpufreq_gov_hotplug);
++ if (err)
++ destroy_workqueue(khotplug_wq);
++
++ return err;
++}
++
++static void __exit cpufreq_gov_dbs_exit(void)
++{
++ cpufreq_unregister_governor(&cpufreq_gov_hotplug);
++ destroy_workqueue(khotplug_wq);
++}
++
++MODULE_AUTHOR("Mike Turquette <mturquette@ti.com>");
++MODULE_DESCRIPTION("'cpufreq_hotplug' - cpufreq governor for dynamic frequency scaling and CPU hotplugging");
++MODULE_LICENSE("GPL");
++
++#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG
++fs_initcall(cpufreq_gov_dbs_init);
++#else
++module_init(cpufreq_gov_dbs_init);
++#endif
++module_exit(cpufreq_gov_dbs_exit);
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index a38fca8..6cbc3df 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -355,6 +355,9 @@ extern struct cpufreq_governor cpufreq_gov_ondemand;
+ #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE)
+ extern struct cpufreq_governor cpufreq_gov_conservative;
+ #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative)
++#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG)
++extern struct cpufreq_governor cpufreq_gov_hotplug;
++#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_hotplug)
+ #endif
+
+
+--
+1.6.6.1
+
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 @@
+From 33668b07abd5e66a263cc8b4b88587646f38bed0 Mon Sep 17 00:00:00 2001
+From: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
+Date: Wed, 11 Aug 2010 17:02:43 -0700
+Subject: [PATCH 1/8] OMAP: CPUfreq: ensure driver initializes after cpufreq framework and governors
+
+Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+---
+ arch/arm/plat-omap/cpu-omap.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
+index da4f68d..cd09d4b 100644
+--- a/arch/arm/plat-omap/cpu-omap.c
++++ b/arch/arm/plat-omap/cpu-omap.c
+@@ -160,7 +160,7 @@ static int __init omap_cpufreq_init(void)
+ return cpufreq_register_driver(&omap_driver);
+ }
+
+-arch_initcall(omap_cpufreq_init);
++late_initcall(omap_cpufreq_init);
+
+ /*
+ * if ever we want to remove this, upon cleanup call:
+--
+1.6.6.1
+
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 @@
+From e89b1544450fb8410a44004e48d6b330bc39f0ce Mon Sep 17 00:00:00 2001
+From: Kevin Hilman <khilman@deeprootsystems.com>
+Date: Wed, 11 Aug 2010 17:05:38 -0700
+Subject: [PATCH 2/8] OMAP: CPUfreq: ensure policy is fully initialized
+
+Ensure policy min/max/cur values are initialized when OMAP
+CPUfreq driver starts.
+
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+---
+ arch/arm/plat-omap/cpu-omap.c | 4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
+index cd09d4b..1b36664 100644
+--- a/arch/arm/plat-omap/cpu-omap.c
++++ b/arch/arm/plat-omap/cpu-omap.c
+@@ -126,6 +126,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ VERY_HI_RATE) / 1000;
+ }
+
++ policy->min = policy->cpuinfo.min_freq;
++ policy->max = policy->cpuinfo.max_freq;
++ policy->cur = omap_getspeed(0);
++
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+--
+1.6.6.1
+
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 @@
+From 948b868e4a83b054e8a58362238bc6cd61c0aeab Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Mon, 10 Nov 2008 17:00:25 +0530
+Subject: [PATCH 3/8] OMAP3 PM: CPUFreq driver for OMAP3
+
+CPUFreq driver for OMAP3
+
+With additional fixes and cleanups from Tero Kristo:
+- Fix rate calculation bug in omap3_select_table_rate
+- Refreshed DVFS VDD1 control against latest clock fw
+
+Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+OMAP3: PM: CPUFreq: Fix omap_getspeed.
+
+Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
+
+Make sure omap cpufreq driver initializes after cpufreq framework and governors
+
+Signed-off-by: Peter 'p2' De Schrijver <peter.de-schrijver@nokia.com>
+
+merge: CPUFreq: remove obsolete funcs
+
+OMAP3 clock: Update cpufreq driver
+
+This patch removes all refrences to virtual clock
+nodes in CPUFreq driver.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
+Signed-off-by: Jean Pihet <jpihet@mvista.com>
+
+PM: Prevent direct cpufreq scaling during initialization
+
+It is seen that the OMAP specific cpufreq initialization code tries to
+scale the MPU frequency to the highest possible without taking care of
+the voltage level. On power on reset the power IC does not provide the
+necessary voltage for the highest available MPU frequency (that would
+satisfy all Si families). This potentially is an window of opportunity
+for things to go wrong.
+
+Signed-off-by: Romit Dasgupta <romit@ti.com>
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+
+OMAP3: PM: enable 600MHz (overdrive) OPP
+
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+
+omap3: introduce cpufreq
+
+OMAP OPP layer functions now have dependencies of CONFIG_CPU_FREQ only.
+
+With this patch, omap opp layer now has its compilation flags
+bound to CONFIG_CPU_FREQ. Also its code has been removed from pm34xx.c.
+
+A new file has been created to contain cpu freq code related to
+OMAP3: cpufreq34xx.c
+
+OMAP34xx and OMAP36xx family OPPs are made available
+
+Signed-off-by: Eduardo Valentin <eduardo.valentin@nokia.com>
+Signed-off-by: Paul Walmsley <paul@pwsan.com>
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+Signed-off-by: Romit Dasgupta <romit@ti.com>
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+
+omap3: cpufreq: allow default opp table init
+
+For board files which choose to override the defaults, the existing
+mechanism will work, for boards that would like to work with defaults,
+allow init_common_hw to call init_opp_table to initialize if not
+already initialized. this will allow all omap boards which have opp
+tables predefined for a silicon to use the same.
+
+Originally reported for overo:
+http://marc.info/?t=127265269400004&r=1&w=2
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Reported-by: Peter Tseng <tsenpet09@gmail.com>
+Cc: Cliff Brake <cliff.brake@gmail.com>
+Cc: Kevin Hilman <khilman@deeprootsystems.com>
+
+OMAP2: update OPP data to be device based
+
+Cc: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+
+OMAP3: CPUfreq: update to device-based OPP API
+
+Update usage of OPP API to use new device-based API. This requires
+getting the 'struct device' for the MPU and using that with the OPP
+API.
+
+Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
+
+omap3: opp: make independent of cpufreq
+
+Make opp3xx data which is registered with the opp layer
+dependent purely on CONFIG_PM as opp layer and pm.c users
+are CONFIG_PM dependent not cpufreq dependent.
+so we rename the data definition to opp3xxx_data.c (inline with what
+we have for omap2), also move the build definition to be under
+the existing CONFIG_PM build instead of CPUFREQ.
+
+Cc: Eduardo Valentin <eduardo.valentin@nokia.com>
+Cc: Kevin Hilman <khilman@deeprootsystems.com>
+Cc: Paul Walmsley <paul@pwsan.com>
+Cc: Rajendra Nayak <rnayak@ti.com>
+Cc: Sanjeev Premi <premi@ti.com>
+Cc: Thara Gopinath <thara@ti.com>
+Cc: Tony Lindgren <tony@atomide.com>
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+---
+ arch/arm/mach-omap2/clock.h | 14 +++++++++++++-
+ arch/arm/mach-omap2/clock34xx.c | 2 ++
+ arch/arm/plat-omap/cpu-omap.c | 34 +++++++++++++++++++++++++++++++---
+ 3 files changed, 46 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
+index e10ff2b..0a07e50 100644
+--- a/arch/arm/mach-omap2/clock.h
++++ b/arch/arm/mach-omap2/clock.h
+@@ -141,7 +141,9 @@ extern const struct clksel_rate gpt_sys_rates[];
+ extern const struct clksel_rate gfx_l3_rates[];
+ extern const struct clksel_rate dsp_ick_rates[];
+
+-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
++#ifdef CONFIG_CPU_FREQ
++
++#ifdef CONFIG_ARCH_OMAP2
+ extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+ #else
+@@ -149,6 +151,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+ #define omap2_clk_exit_cpufreq_table 0
+ #endif
+
++#ifdef CONFIG_ARCH_OMAP3
++extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
++extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
++#else
++#define omap3_clk_init_cpufreq_table 0
++#define omap3_clk_exit_cpufreq_table 0
++#endif
++
++#endif /* CONFIG_CPU_FREQ */
++
+ extern const struct clkops clkops_omap2_iclk_dflt_wait;
+ extern const struct clkops clkops_omap2_iclk_dflt;
+ extern const struct clkops clkops_omap2_iclk_idle_only;
+diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
+index 1fc96b9..119e135 100644
+--- a/arch/arm/mach-omap2/clock34xx.c
++++ b/arch/arm/mach-omap2/clock34xx.c
+@@ -20,6 +20,8 @@
+ #include <linux/kernel.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
++#include <linux/err.h>
++#include <linux/cpufreq.h>
+
+ #include <plat/clock.h>
+
+diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
+index 1b36664..f0f9430 100644
+--- a/arch/arm/plat-omap/cpu-omap.c
++++ b/arch/arm/plat-omap/cpu-omap.c
+@@ -8,6 +8,10 @@
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Updated to support OMAP3
++ * Rajendra Nayak <rnayak@ti.com>
++ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+@@ -26,12 +30,19 @@
+ #include <plat/clock.h>
+ #include <asm/system.h>
+
++#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
++#include <plat/omap-pm.h>
++#include <plat/opp.h>
++#endif
++
+ #define VERY_HI_RATE 900000000
+
+ static struct cpufreq_frequency_table *freq_table;
+
+ #ifdef CONFIG_ARCH_OMAP1
+ #define MPU_CLK "mpu"
++#elif CONFIG_ARCH_OMAP3
++#define MPU_CLK "arm_fck"
+ #else
+ #define MPU_CLK "virt_prcm_set"
+ #endif
+@@ -73,7 +84,13 @@ static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+ {
++#ifdef CONFIG_ARCH_OMAP1
+ struct cpufreq_freqs freqs;
++#endif
++#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
++ unsigned long freq;
++ struct device *mpu_dev = omap2_get_mpuss_device();
++#endif
+ int ret = 0;
+
+ /* Ensure desired rate is within allowed range. Some govenors
+@@ -83,13 +100,13 @@ static int omap_target(struct cpufreq_policy *policy,
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+
++#ifdef CONFIG_ARCH_OMAP1
+ freqs.old = omap_getspeed(0);
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+ freqs.cpu = 0;
+
+ if (freqs.old == freqs.new)
+ return ret;
+-
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ #ifdef CONFIG_CPU_FREQ_DEBUG
+ printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
+@@ -97,7 +114,11 @@ static int omap_target(struct cpufreq_policy *policy,
+ #endif
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+-
++#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
++ freq = target_freq * 1000;
++ if (opp_find_freq_ceil(mpu_dev, &freq))
++ omap_pm_cpu_set_freq(freq);
++#endif
+ return ret;
+ }
+
+@@ -114,7 +135,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+
+ policy->cur = policy->min = policy->max = omap_getspeed(0);
+
+- clk_init_cpufreq_table(&freq_table);
++ if (!cpu_is_omap34xx()) {
++ clk_init_cpufreq_table(&freq_table);
++ } else {
++ struct device *mpu_dev = omap2_get_mpuss_device();
++
++ opp_init_cpufreq_table(mpu_dev, &freq_table);
++ }
++
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+--
+1.6.6.1
+
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 @@
+From 86227f1eb341e571163464cb0a412ed2179f2541 Mon Sep 17 00:00:00 2001
+From: Silesh C V <silesh@ti.com>
+Date: Wed, 29 Sep 2010 14:52:54 +0530
+Subject: [PATCH 4/8] OMAP: PM: CPUFREQ: Fix conditional compilation
+
+Fix conditional compilation. A conditional expresiion
+should follow "#elif", in this case #elif clause should
+check whether CONFIG_ARCH_OMAP3 is defined or not
+(ie. defined(CONFIG_ARCH_OMAP3)) rather than checking for
+the value of the macro.
+
+Signed-off-by: Silesh C V <silesh@ti.com>
+---
+ arch/arm/plat-omap/cpu-omap.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
+index f0f9430..c3ac065 100644
+--- a/arch/arm/plat-omap/cpu-omap.c
++++ b/arch/arm/plat-omap/cpu-omap.c
+@@ -41,7 +41,7 @@ static struct cpufreq_frequency_table *freq_table;
+
+ #ifdef CONFIG_ARCH_OMAP1
+ #define MPU_CLK "mpu"
+-#elif CONFIG_ARCH_OMAP3
++#elif defined(CONFIG_ARCH_OMAP3)
+ #define MPU_CLK "arm_fck"
+ #else
+ #define MPU_CLK "virt_prcm_set"
+--
+1.6.6.1
+
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 @@
+From 4764137dd613362656726a15cb8184724aeb99bb Mon Sep 17 00:00:00 2001
+From: Kevin Hilman <khilman@deeprootsystems.com>
+Date: Tue, 16 Nov 2010 11:48:41 -0800
+Subject: [PATCH 5/8] cpufreq: fixup after new OPP layer merged
+
+---
+ arch/arm/plat-omap/cpu-omap.c | 3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
+index c3ac065..9cd2709 100644
+--- a/arch/arm/plat-omap/cpu-omap.c
++++ b/arch/arm/plat-omap/cpu-omap.c
+@@ -25,6 +25,7 @@
+ #include <linux/err.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
++#include <linux/opp.h>
+
+ #include <mach/hardware.h>
+ #include <plat/clock.h>
+@@ -32,7 +33,7 @@
+
+ #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+ #include <plat/omap-pm.h>
+-#include <plat/opp.h>
++#include <plat/common.h>
+ #endif
+
+ #define VERY_HI_RATE 900000000
+--
+1.6.6.1
+
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 @@
+From e16548716c5cbc3c9885d05f1654d83d5411a3a7 Mon Sep 17 00:00:00 2001
+From: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Date: Mon, 14 Mar 2011 17:08:48 +0530
+Subject: [PATCH 6/8] OMAP: cpufreq: Split OMAP1 and OMAP2PLUS CPUfreq drivers.
+
+This patch is an attempt to cleanup the #ifdeferry in the
+omap CPUfreq drivers.
+
+The split betwenn OMAP1 and OMAP2PLUS is logical because
+ - OMAP1 doesn't support opp layer.
+ - OMAP1 build is seperate from omap2plus.
+
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Cc: Kevin Hilman <khilman@ti.com>
+Cc: Vishwanath BS <vishwanath.bs@ti.com>
+---
+ arch/arm/mach-omap1/Makefile | 3 +
+ arch/arm/mach-omap1/omap1-cpufreq.c | 176 ++++++++++++++++++++++++++
+ arch/arm/mach-omap2/Makefile | 3 +
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 201 ++++++++++++++++++++++++++++++
+ arch/arm/plat-omap/Makefile | 1 -
+ arch/arm/plat-omap/cpu-omap.c | 204 -------------------------------
+ 6 files changed, 383 insertions(+), 205 deletions(-)
+ create mode 100644 arch/arm/mach-omap1/omap1-cpufreq.c
+ create mode 100644 arch/arm/mach-omap2/omap2plus-cpufreq.c
+ delete mode 100644 arch/arm/plat-omap/cpu-omap.c
+
+diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
+index af98117..e5082b0 100644
+--- a/arch/arm/mach-omap1/Makefile
++++ b/arch/arm/mach-omap1/Makefile
+@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+
+ obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
+
++# CPUFREQ driver
++obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o
++
+ # Power Management
+ obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
+
+diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c
+new file mode 100644
+index 0000000..682cdc8
+--- /dev/null
++++ b/arch/arm/mach-omap1/omap1-cpufreq.c
+@@ -0,0 +1,176 @@
++/*
++ * OMAP1 cpufreq driver
++ *
++ * CPU frequency scaling for OMAP
++ *
++ * Copyright (C) 2005 Nokia Corporation
++ * Written by Tony Lindgren <tony@atomide.com>
++ *
++ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Updated to support OMAP3
++ * Rajendra Nayak <rnayak@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/cpufreq.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/opp.h>
++
++#include <asm/system.h>
++
++#include <plat/clock.h>
++#include <plat/omap-pm.h>
++
++#include <mach/hardware.h>
++
++#define VERY_HI_RATE 900000000
++
++static struct cpufreq_frequency_table *freq_table;
++static struct clk *mpu_clk;
++
++static int omap_verify_speed(struct cpufreq_policy *policy)
++{
++ if (freq_table)
++ return cpufreq_frequency_table_verify(policy, freq_table);
++
++ if (policy->cpu)
++ return -EINVAL;
++
++ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
++ policy->cpuinfo.max_freq);
++
++ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
++ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
++ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
++ policy->cpuinfo.max_freq);
++ return 0;
++}
++
++static unsigned int omap_getspeed(unsigned int cpu)
++{
++ unsigned long rate;
++
++ if (cpu)
++ return 0;
++
++ rate = clk_get_rate(mpu_clk) / 1000;
++ return rate;
++}
++
++static int omap_target(struct cpufreq_policy *policy,
++ unsigned int target_freq,
++ unsigned int relation)
++{
++ struct cpufreq_freqs freqs;
++ int ret = 0;
++
++ /* Ensure desired rate is within allowed range. Some govenors
++ * (ondemand) will just pass target_freq=0 to get the minimum. */
++ if (target_freq < policy->min)
++ target_freq = policy->min;
++ if (target_freq > policy->max)
++ target_freq = policy->max;
++
++ freqs.old = omap_getspeed(0);
++ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
++ freqs.cpu = 0;
++
++ if (freqs.old == freqs.new)
++ return ret;
++
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++
++#ifdef CONFIG_CPU_FREQ_DEBUG
++ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
++#endif
++ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
++
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++
++ return ret;
++}
++
++static int __init omap_cpu_init(struct cpufreq_policy *policy)
++{
++ int result = 0;
++
++ mpu_clk = clk_get(NULL, "mpu");
++ if (IS_ERR(mpu_clk))
++ return PTR_ERR(mpu_clk);
++
++ if (policy->cpu != 0)
++ return -EINVAL;
++
++ policy->cur = policy->min = policy->max = omap_getspeed(0);
++
++ clk_init_cpufreq_table(&freq_table);
++
++ if (freq_table) {
++ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
++ if (!result)
++ cpufreq_frequency_table_get_attr(freq_table,
++ policy->cpu);
++ } else {
++ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
++ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
++ VERY_HI_RATE) / 1000;
++ }
++
++ policy->min = policy->cpuinfo.min_freq;
++ policy->max = policy->cpuinfo.max_freq;
++ policy->cur = omap_getspeed(0);
++
++ /* FIXME: what's the actual transition time? */
++ policy->cpuinfo.transition_latency = 300 * 1000;
++
++ return 0;
++}
++
++static int omap_cpu_exit(struct cpufreq_policy *policy)
++{
++ clk_exit_cpufreq_table(&freq_table);
++ clk_put(mpu_clk);
++ return 0;
++}
++
++static struct freq_attr *omap_cpufreq_attr[] = {
++ &cpufreq_freq_attr_scaling_available_freqs,
++ NULL,
++};
++
++static struct cpufreq_driver omap_driver = {
++ .flags = CPUFREQ_STICKY,
++ .verify = omap_verify_speed,
++ .target = omap_target,
++ .get = omap_getspeed,
++ .init = omap_cpu_init,
++ .exit = omap_cpu_exit,
++ .name = "omap1",
++ .attr = omap_cpufreq_attr,
++};
++
++static int __init omap_cpufreq_init(void)
++{
++ return cpufreq_register_driver(&omap_driver);
++}
++
++static void __exit omap_cpufreq_exit(void)
++{
++ cpufreq_unregister_driver(&omap_driver);
++}
++
++MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs");
++MODULE_LICENSE("GPL");
++module_init(omap_cpufreq_init);
++module_exit(omap_cpufreq_exit);
+diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
+index 05cd983..e9c2445 100644
+--- a/arch/arm/mach-omap2/Makefile
++++ b/arch/arm/mach-omap2/Makefile
+@@ -56,6 +56,9 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
+ obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
+ endif
+
++# CPUFREQ driver
++obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o
++
+ # Power Management
+ ifeq ($(CONFIG_PM),y)
+ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+new file mode 100644
+index 0000000..14f84cc
+--- /dev/null
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -0,0 +1,201 @@
++/*
++ * OMAP2PLUS cpufreq driver
++ *
++ * CPU frequency scaling for OMAP
++ *
++ * Copyright (C) 2005 Nokia Corporation
++ * Written by Tony Lindgren <tony@atomide.com>
++ *
++ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
++ *
++ * Copyright (C) 2007-2008 Texas Instruments, Inc.
++ * Updated to support OMAP3
++ * Rajendra Nayak <rnayak@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/cpufreq.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/opp.h>
++
++#include <asm/system.h>
++#include <asm/smp_plat.h>
++
++#include <plat/clock.h>
++#include <plat/omap-pm.h>
++#include <plat/common.h>
++
++#include <mach/hardware.h>
++
++#define VERY_HI_RATE 900000000
++
++static struct cpufreq_frequency_table *freq_table;
++static struct clk *mpu_clk;
++
++static int omap_verify_speed(struct cpufreq_policy *policy)
++{
++ if (freq_table)
++ return cpufreq_frequency_table_verify(policy, freq_table);
++
++ if (policy->cpu)
++ return -EINVAL;
++
++ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
++ policy->cpuinfo.max_freq);
++
++ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
++ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
++ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
++ policy->cpuinfo.max_freq);
++ return 0;
++}
++
++static unsigned int omap_getspeed(unsigned int cpu)
++{
++ unsigned long rate;
++
++ if (cpu)
++ return 0;
++
++ rate = clk_get_rate(mpu_clk) / 1000;
++ return rate;
++}
++
++static int omap_target(struct cpufreq_policy *policy,
++ unsigned int target_freq,
++ unsigned int relation)
++{
++ int ret = 0;
++ struct cpufreq_freqs freqs;
++
++ /* Ensure desired rate is within allowed range. Some govenors
++ * (ondemand) will just pass target_freq=0 to get the minimum. */
++ if (target_freq < policy->min)
++ target_freq = policy->min;
++ if (target_freq > policy->max)
++ target_freq = policy->max;
++
++ freqs.old = omap_getspeed(0);
++ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
++ freqs.cpu = 0;
++
++ if (freqs.old == freqs.new)
++ return ret;
++
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++
++#ifdef CONFIG_CPU_FREQ_DEBUG
++ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
++#endif
++
++ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
++
++ /*
++ * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies
++ * won't get updated when UP machine cpufreq build with
++ * CONFIG_SMP enabled. Below code is added only to manage that
++ * scenario
++ */
++ if (!is_smp())
++ loops_per_jiffy =
++ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
++
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++
++ return ret;
++}
++
++static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
++{
++ int result = 0;
++ struct device *mpu_dev;
++
++ if (cpu_is_omap24xx())
++ mpu_clk = clk_get(NULL, "virt_prcm_set");
++ else if (cpu_is_omap34xx())
++ mpu_clk = clk_get(NULL, "dpll1_ck");
++ else if (cpu_is_omap34xx())
++ mpu_clk = clk_get(NULL, "dpll_mpu_ck");
++
++ if (IS_ERR(mpu_clk))
++ return PTR_ERR(mpu_clk);
++
++ if (policy->cpu != 0)
++ return -EINVAL;
++
++ policy->cur = policy->min = policy->max = omap_getspeed(0);
++
++ mpu_dev = omap2_get_mpuss_device();
++ if (!mpu_dev) {
++ pr_warning("%s: unable to get the mpu device\n", __func__);
++ return -EINVAL;
++ }
++ opp_init_cpufreq_table(mpu_dev, &freq_table);
++
++ if (freq_table) {
++ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
++ if (!result)
++ cpufreq_frequency_table_get_attr(freq_table,
++ policy->cpu);
++ } else {
++ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
++ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
++ VERY_HI_RATE) / 1000;
++ }
++
++ policy->min = policy->cpuinfo.min_freq;
++ policy->max = policy->cpuinfo.max_freq;
++ policy->cur = omap_getspeed(0);
++
++ /* FIXME: what's the actual transition time? */
++ policy->cpuinfo.transition_latency = 300 * 1000;
++
++ return 0;
++}
++
++static int omap_cpu_exit(struct cpufreq_policy *policy)
++{
++ clk_exit_cpufreq_table(&freq_table);
++ clk_put(mpu_clk);
++ return 0;
++}
++
++static struct freq_attr *omap_cpufreq_attr[] = {
++ &cpufreq_freq_attr_scaling_available_freqs,
++ NULL,
++};
++
++static struct cpufreq_driver omap_driver = {
++ .flags = CPUFREQ_STICKY,
++ .verify = omap_verify_speed,
++ .target = omap_target,
++ .get = omap_getspeed,
++ .init = omap_cpu_init,
++ .exit = omap_cpu_exit,
++ .name = "omap2plus",
++ .attr = omap_cpufreq_attr,
++};
++
++static int __init omap_cpufreq_init(void)
++{
++ return cpufreq_register_driver(&omap_driver);
++}
++
++static void __exit omap_cpufreq_exit(void)
++{
++ cpufreq_unregister_driver(&omap_driver);
++}
++
++MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs");
++MODULE_LICENSE("GPL");
++module_init(omap_cpufreq_init);
++module_exit(omap_cpufreq_exit);
+diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
+index a4a1285..ec7862e 100644
+--- a/arch/arm/plat-omap/Makefile
++++ b/arch/arm/plat-omap/Makefile
+@@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+ obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
+ obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
+
+-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
+ obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
+ obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
+ obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
+diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
+deleted file mode 100644
+index 9cd2709..0000000
+--- a/arch/arm/plat-omap/cpu-omap.c
++++ /dev/null
+@@ -1,204 +0,0 @@
+-/*
+- * linux/arch/arm/plat-omap/cpu-omap.c
+- *
+- * CPU frequency scaling for OMAP
+- *
+- * Copyright (C) 2005 Nokia Corporation
+- * Written by Tony Lindgren <tony@atomide.com>
+- *
+- * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+- *
+- * Copyright (C) 2007-2008 Texas Instruments, Inc.
+- * Updated to support OMAP3
+- * Rajendra Nayak <rnayak@ti.com>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/cpufreq.h>
+-#include <linux/delay.h>
+-#include <linux/init.h>
+-#include <linux/err.h>
+-#include <linux/clk.h>
+-#include <linux/io.h>
+-#include <linux/opp.h>
+-
+-#include <mach/hardware.h>
+-#include <plat/clock.h>
+-#include <asm/system.h>
+-
+-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+-#include <plat/omap-pm.h>
+-#include <plat/common.h>
+-#endif
+-
+-#define VERY_HI_RATE 900000000
+-
+-static struct cpufreq_frequency_table *freq_table;
+-
+-#ifdef CONFIG_ARCH_OMAP1
+-#define MPU_CLK "mpu"
+-#elif defined(CONFIG_ARCH_OMAP3)
+-#define MPU_CLK "arm_fck"
+-#else
+-#define MPU_CLK "virt_prcm_set"
+-#endif
+-
+-static struct clk *mpu_clk;
+-
+-/* TODO: Add support for SDRAM timing changes */
+-
+-static int omap_verify_speed(struct cpufreq_policy *policy)
+-{
+- if (freq_table)
+- return cpufreq_frequency_table_verify(policy, freq_table);
+-
+- if (policy->cpu)
+- return -EINVAL;
+-
+- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+- policy->cpuinfo.max_freq);
+-
+- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
+- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
+- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+- policy->cpuinfo.max_freq);
+- return 0;
+-}
+-
+-static unsigned int omap_getspeed(unsigned int cpu)
+-{
+- unsigned long rate;
+-
+- if (cpu)
+- return 0;
+-
+- rate = clk_get_rate(mpu_clk) / 1000;
+- return rate;
+-}
+-
+-static int omap_target(struct cpufreq_policy *policy,
+- unsigned int target_freq,
+- unsigned int relation)
+-{
+-#ifdef CONFIG_ARCH_OMAP1
+- struct cpufreq_freqs freqs;
+-#endif
+-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+- unsigned long freq;
+- struct device *mpu_dev = omap2_get_mpuss_device();
+-#endif
+- int ret = 0;
+-
+- /* Ensure desired rate is within allowed range. Some govenors
+- * (ondemand) will just pass target_freq=0 to get the minimum. */
+- if (target_freq < policy->min)
+- target_freq = policy->min;
+- if (target_freq > policy->max)
+- target_freq = policy->max;
+-
+-#ifdef CONFIG_ARCH_OMAP1
+- freqs.old = omap_getspeed(0);
+- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+- freqs.cpu = 0;
+-
+- if (freqs.old == freqs.new)
+- return ret;
+- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+-#ifdef CONFIG_CPU_FREQ_DEBUG
+- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
+- freqs.old, freqs.new);
+-#endif
+- ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+-#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+- freq = target_freq * 1000;
+- if (opp_find_freq_ceil(mpu_dev, &freq))
+- omap_pm_cpu_set_freq(freq);
+-#endif
+- return ret;
+-}
+-
+-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+-{
+- int result = 0;
+-
+- mpu_clk = clk_get(NULL, MPU_CLK);
+- if (IS_ERR(mpu_clk))
+- return PTR_ERR(mpu_clk);
+-
+- if (policy->cpu != 0)
+- return -EINVAL;
+-
+- policy->cur = policy->min = policy->max = omap_getspeed(0);
+-
+- if (!cpu_is_omap34xx()) {
+- clk_init_cpufreq_table(&freq_table);
+- } else {
+- struct device *mpu_dev = omap2_get_mpuss_device();
+-
+- opp_init_cpufreq_table(mpu_dev, &freq_table);
+- }
+-
+- if (freq_table) {
+- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+- if (!result)
+- cpufreq_frequency_table_get_attr(freq_table,
+- policy->cpu);
+- } else {
+- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+- VERY_HI_RATE) / 1000;
+- }
+-
+- policy->min = policy->cpuinfo.min_freq;
+- policy->max = policy->cpuinfo.max_freq;
+- policy->cur = omap_getspeed(0);
+-
+- /* FIXME: what's the actual transition time? */
+- policy->cpuinfo.transition_latency = 300 * 1000;
+-
+- return 0;
+-}
+-
+-static int omap_cpu_exit(struct cpufreq_policy *policy)
+-{
+- clk_exit_cpufreq_table(&freq_table);
+- clk_put(mpu_clk);
+- return 0;
+-}
+-
+-static struct freq_attr *omap_cpufreq_attr[] = {
+- &cpufreq_freq_attr_scaling_available_freqs,
+- NULL,
+-};
+-
+-static struct cpufreq_driver omap_driver = {
+- .flags = CPUFREQ_STICKY,
+- .verify = omap_verify_speed,
+- .target = omap_target,
+- .get = omap_getspeed,
+- .init = omap_cpu_init,
+- .exit = omap_cpu_exit,
+- .name = "omap",
+- .attr = omap_cpufreq_attr,
+-};
+-
+-static int __init omap_cpufreq_init(void)
+-{
+- return cpufreq_register_driver(&omap_driver);
+-}
+-
+-late_initcall(omap_cpufreq_init);
+-
+-/*
+- * if ever we want to remove this, upon cleanup call:
+- *
+- * cpufreq_unregister_driver()
+- * cpufreq_frequency_table_put_attr()
+- */
+-
+--
+1.6.6.1
+
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 @@
+From f375d3c39d2835929d34c2a046b8c43cea6d1467 Mon Sep 17 00:00:00 2001
+From: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Date: Mon, 14 Mar 2011 17:08:49 +0530
+Subject: [PATCH 7/8] OMAP2PLUS: cpufreq: Add SMP support to cater OMAP4430
+
+On OMAP SMP configuartion, both processors share the voltage
+and clock. So both CPUs needs to be scaled together and hence
+needs software co-ordination.
+
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Cc: Kevin Hilman <khilman@ti.com>
+cc: Vishwanath BS <vishwanath.bs@ti.com>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 73 ++++++++++++++++++++++++++-----
+ 1 files changed, 62 insertions(+), 11 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index 14f84cc..8d472f6 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -26,9 +26,11 @@
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/opp.h>
++#include <linux/cpu.h>
+
+ #include <asm/system.h>
+ #include <asm/smp_plat.h>
++#include <asm/cpu.h>
+
+ #include <plat/clock.h>
+ #include <plat/omap-pm.h>
+@@ -63,7 +65,7 @@ static unsigned int omap_getspeed(unsigned int cpu)
+ {
+ unsigned long rate;
+
+- if (cpu)
++ if (cpu >= NR_CPUS)
+ return 0;
+
+ rate = clk_get_rate(mpu_clk) / 1000;
+@@ -74,9 +76,13 @@ static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+ {
+- int ret = 0;
++ int i, ret = 0;
+ struct cpufreq_freqs freqs;
+
++ /* Changes not allowed until all CPUs are online */
++ if (is_smp() && (num_online_cpus() < NR_CPUS))
++ return ret;
++
+ /* Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
+ if (target_freq < policy->min)
+@@ -84,15 +90,25 @@ static int omap_target(struct cpufreq_policy *policy,
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+
+- freqs.old = omap_getspeed(0);
++ freqs.old = omap_getspeed(policy->cpu);
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+- freqs.cpu = 0;
++ freqs.cpu = policy->cpu;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++ if (!is_smp()) {
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++ goto set_freq;
++ }
++
++ /* notifiers */
++ for_each_cpu(i, policy->cpus) {
++ freqs.cpu = i;
++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
++ }
+
++set_freq:
+ #ifdef CONFIG_CPU_FREQ_DEBUG
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
+ #endif
+@@ -105,12 +121,33 @@ static int omap_target(struct cpufreq_policy *policy,
+ * CONFIG_SMP enabled. Below code is added only to manage that
+ * scenario
+ */
+- if (!is_smp())
++ freqs.new = omap_getspeed(policy->cpu);
++ if (!is_smp()) {
+ loops_per_jiffy =
+ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++ goto skip_lpj;
++ }
+
+- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++#ifdef CONFIG_SMP
++ /*
++ * Note that loops_per_jiffy is not updated on SMP systems in
++ * cpufreq driver. So, update the per-CPU loops_per_jiffy value
++ * on frequency transition. We need to update all dependent CPUs.
++ */
++ for_each_cpu(i, policy->cpus)
++ per_cpu(cpu_data, i).loops_per_jiffy =
++ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
++ freqs.old, freqs.new);
++#endif
+
++ /* notifiers */
++ for_each_cpu(i, policy->cpus) {
++ freqs.cpu = i;
++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
++ }
++
++skip_lpj:
+ return ret;
+ }
+
+@@ -118,6 +155,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ {
+ int result = 0;
+ struct device *mpu_dev;
++ static cpumask_var_t cpumask;
+
+ if (cpu_is_omap24xx())
+ mpu_clk = clk_get(NULL, "virt_prcm_set");
+@@ -129,12 +167,12 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ if (IS_ERR(mpu_clk))
+ return PTR_ERR(mpu_clk);
+
+- if (policy->cpu != 0)
++ if (policy->cpu >= NR_CPUS)
+ return -EINVAL;
+
+- policy->cur = policy->min = policy->max = omap_getspeed(0);
+-
++ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
+ mpu_dev = omap2_get_mpuss_device();
++
+ if (!mpu_dev) {
+ pr_warning("%s: unable to get the mpu device\n", __func__);
+ return -EINVAL;
+@@ -154,7 +192,20 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+- policy->cur = omap_getspeed(0);
++ policy->cur = omap_getspeed(policy->cpu);
++
++ /*
++ * On OMAP SMP configuartion, both processors share the voltage
++ * and clock. So both CPUs needs to be scaled together and hence
++ * needs software co-ordination. Use cpufreq affected_cpus
++ * interface to handle this scenario. Additional is_smp() check
++ * is to keep SMP_ON_UP build working.
++ */
++ if (is_smp()) {
++ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
++ cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
++ cpumask_copy(policy->cpus, cpumask);
++ }
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+--
+1.6.6.1
+
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 @@
+From 6e101764a47cb6975a555e2237843ad391a542a4 Mon Sep 17 00:00:00 2001
+From: Jarkko Nikula <jhnikula@gmail.com>
+Date: Thu, 14 Apr 2011 16:21:58 +0300
+Subject: [PATCH 8/8] OMAP2PLUS: cpufreq: Fix typo when attempting to set mpu_clk for OMAP4
+
+Fix this typo as there is no dpll_mpu_ck for OMAP3 and code flow is clearly
+trying to set mpu_clk for OMAP4 for which this dpll_mpu_ck is available.
+
+Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
+---
+ arch/arm/mach-omap2/omap2plus-cpufreq.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+index 8d472f6..d53ce23 100644
+--- a/arch/arm/mach-omap2/omap2plus-cpufreq.c
++++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
+@@ -161,7 +161,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+ mpu_clk = clk_get(NULL, "virt_prcm_set");
+ else if (cpu_is_omap34xx())
+ mpu_clk = clk_get(NULL, "dpll1_ck");
+- else if (cpu_is_omap34xx())
++ else if (cpu_is_omap44xx())
+ mpu_clk = clk_get(NULL, "dpll_mpu_ck");
+
+ if (IS_ERR(mpu_clk))
+--
+1.6.6.1
+
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 @@
+From 988f50cb51d18e81ed2f7673a09694d28c9d086a Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Tue, 5 Apr 2011 15:22:31 +0530
+Subject: [PATCH 1/6] OMAP2+: clockdomain: Add an api to read idle mode
+
+Add a clockdomain api to check if hardware supervised
+idle transitions are enabled on a clockdomain.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+---
+ arch/arm/mach-omap2/clockdomain.c | 21 +++++++++++++++++++++
+ arch/arm/mach-omap2/clockdomain.h | 3 +++
+ 2 files changed, 24 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
+index 6cb6c03..2ab3686 100644
+--- a/arch/arm/mach-omap2/clockdomain.c
++++ b/arch/arm/mach-omap2/clockdomain.c
+@@ -795,6 +795,27 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
+ arch_clkdm->clkdm_deny_idle(clkdm);
+ }
+
++/**
++ * clkdm_is_idle - Check if the clkdm hwsup/autoidle is enabled
++ * @clkdm: struct clockdomain *
++ *
++ * Returns true if the clockdomain is in hardware-supervised
++ * idle mode, or 0 otherwise.
++ *
++ */
++int clkdm_is_idle(struct clockdomain *clkdm)
++{
++ if (!clkdm)
++ return -EINVAL;
++
++ if (!arch_clkdm || !arch_clkdm->clkdm_is_idle)
++ return -EINVAL;
++
++ pr_debug("clockdomain: reading idle state for %s\n", clkdm->name);
++
++ return arch_clkdm->clkdm_is_idle(clkdm);
++}
++
+
+ /* Clockdomain-to-clock framework interface code */
+
+diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
+index 5823584..085ed82 100644
+--- a/arch/arm/mach-omap2/clockdomain.h
++++ b/arch/arm/mach-omap2/clockdomain.h
+@@ -138,6 +138,7 @@ struct clockdomain {
+ * @clkdm_wakeup: Force a clockdomain to wakeup
+ * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain
+ * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
++ * @clkdm_is_idle: Check if hw supervised idle transitions are enabled
+ * @clkdm_clk_enable: Put the clkdm in right state for a clock enable
+ * @clkdm_clk_disable: Put the clkdm in right state for a clock disable
+ */
+@@ -154,6 +155,7 @@ struct clkdm_ops {
+ int (*clkdm_wakeup)(struct clockdomain *clkdm);
+ void (*clkdm_allow_idle)(struct clockdomain *clkdm);
+ void (*clkdm_deny_idle)(struct clockdomain *clkdm);
++ int (*clkdm_is_idle)(struct clockdomain *clkdm);
+ int (*clkdm_clk_enable)(struct clockdomain *clkdm);
+ int (*clkdm_clk_disable)(struct clockdomain *clkdm);
+ };
+@@ -177,6 +179,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
+
+ void clkdm_allow_idle(struct clockdomain *clkdm);
+ void clkdm_deny_idle(struct clockdomain *clkdm);
++int clkdm_is_idle(struct clockdomain *clkdm);
+
+ int clkdm_wakeup(struct clockdomain *clkdm);
+ int clkdm_sleep(struct clockdomain *clkdm);
+--
+1.6.6.1
+
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 @@
+From e3ba8d41bfafd782f3ee7f8930d9bf393986c662 Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Tue, 5 Apr 2011 15:22:36 +0530
+Subject: [PATCH 2/6] OMAP2+: clockdomain: Add SoC support for clkdm_is_idle
+
+Add the SoC specific implemenation for clkdm_is_idle
+for OMAP2/3 and OMAP4.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+---
+ arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 12 ++++++++++++
+ arch/arm/mach-omap2/clockdomain44xx.c | 7 +++++++
+ 2 files changed, 19 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+index 48d0db7..db49baa 100644
+--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
++++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+@@ -13,6 +13,7 @@
+ */
+
+ #include <linux/types.h>
++#include <linux/errno.h>
+ #include <plat/prcm.h>
+ #include "prm.h"
+ #include "prm2xxx_3xxx.h"
+@@ -146,6 +147,15 @@ static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+ _clkdm_del_autodeps(clkdm);
+ }
+
++static int omap2_clkdm_is_idle(struct clockdomain *clkdm)
++{
++ if (!clkdm->clktrctrl_mask)
++ return -1;
++
++ return omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
++ clkdm->clktrctrl_mask);
++}
++
+ static void _enable_hwsup(struct clockdomain *clkdm)
+ {
+ if (cpu_is_omap24xx())
+@@ -252,6 +262,7 @@ struct clkdm_ops omap2_clkdm_operations = {
+ .clkdm_wakeup = omap2_clkdm_wakeup,
+ .clkdm_allow_idle = omap2_clkdm_allow_idle,
+ .clkdm_deny_idle = omap2_clkdm_deny_idle,
++ .clkdm_is_idle = omap2_clkdm_is_idle,
+ .clkdm_clk_enable = omap2_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2_clkdm_clk_disable,
+ };
+@@ -269,6 +280,7 @@ struct clkdm_ops omap3_clkdm_operations = {
+ .clkdm_wakeup = omap3_clkdm_wakeup,
+ .clkdm_allow_idle = omap3_clkdm_allow_idle,
+ .clkdm_deny_idle = omap3_clkdm_deny_idle,
++ .clkdm_is_idle = omap2_clkdm_is_idle,
+ .clkdm_clk_enable = omap2_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2_clkdm_clk_disable,
+ };
+diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
+index a1a4ecd..4b10727 100644
+--- a/arch/arm/mach-omap2/clockdomain44xx.c
++++ b/arch/arm/mach-omap2/clockdomain44xx.c
+@@ -93,6 +93,12 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
+ clkdm->cm_inst, clkdm->clkdm_offs);
+ }
+
++static int omap4_clkdm_is_idle(struct clockdomain *clkdm)
++{
++ return omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
++ clkdm->cm_inst, clkdm->clkdm_offs);
++}
++
+ static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+ {
+ bool hwsup = false;
+@@ -132,6 +138,7 @@ struct clkdm_ops omap4_clkdm_operations = {
+ .clkdm_wakeup = omap4_clkdm_wakeup,
+ .clkdm_allow_idle = omap4_clkdm_allow_idle,
+ .clkdm_deny_idle = omap4_clkdm_deny_idle,
++ .clkdm_is_idle = omap4_clkdm_is_idle,
+ .clkdm_clk_enable = omap4_clkdm_clk_enable,
+ .clkdm_clk_disable = omap4_clkdm_clk_disable,
+ };
+--
+1.6.6.1
+
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 @@
+From 7cdc87071a4bb390ad5d7ddea210bd2b4d662114 Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Tue, 5 Apr 2011 15:22:41 +0530
+Subject: [PATCH 3/6] OMAP2+: PM: Initialise sleep_switch to a non-valid value
+
+sleep_switch which is initialised to 0 in omap_set_pwrdm_state
+happens to be a valid sleep_switch type (FORCEWAKEUP_SWITCH)
+which are defined as
+#define FORCEWAKEUP_SWITCH 0
+#define LOWPOWERSTATE_SWITCH 1
+
+This causes the function to wrongly program some clock domains
+even when the Powerdomain is in ON state.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+---
+ arch/arm/mach-omap2/pm.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
+index 49486f5..d48813f 100644
+--- a/arch/arm/mach-omap2/pm.c
++++ b/arch/arm/mach-omap2/pm.c
+@@ -106,7 +106,7 @@ static void omap2_init_processor_devices(void)
+ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+ {
+ u32 cur_state;
+- int sleep_switch = 0;
++ int sleep_switch = -1;
+ int ret = 0;
+
+ if (pwrdm == NULL || IS_ERR(pwrdm))
+--
+1.6.6.1
+
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 @@
+From cec133850aa42c03d912c764aaa441677e782eca Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Tue, 5 Apr 2011 15:22:48 +0530
+Subject: [PATCH 4/6] OMAP2+: PM: idle clkdms only if already in idle
+
+The omap_set_pwrdm_state function forces clockdomains
+to idle, without checking the existing idle state
+programmed, instead based solely on the HW capability
+of the clockdomain to support idle.
+This is wrong and the clockdomains should be idled
+post a state_switch *only* if idle transitions on the
+clockdomain were already enabled.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+---
+ arch/arm/mach-omap2/pm.c | 4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
+index d48813f..840b0e1 100644
+--- a/arch/arm/mach-omap2/pm.c
++++ b/arch/arm/mach-omap2/pm.c
+@@ -108,6 +108,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+ u32 cur_state;
+ int sleep_switch = -1;
+ int ret = 0;
++ int hwsup = 0;
+
+ if (pwrdm == NULL || IS_ERR(pwrdm))
+ return -EINVAL;
+@@ -127,6 +128,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+ (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+ sleep_switch = LOWPOWERSTATE_SWITCH;
+ } else {
++ hwsup = clkdm_is_idle(pwrdm->pwrdm_clkdms[0]);
+ clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+ pwrdm_wait_transition(pwrdm);
+ sleep_switch = FORCEWAKEUP_SWITCH;
+@@ -142,7 +144,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+
+ switch (sleep_switch) {
+ case FORCEWAKEUP_SWITCH:
+- if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
++ if (hwsup)
+ clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ else
+ clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+--
+1.6.6.1
+
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 @@
+From 8fb6b7c488b31fbff5b81bdeea5dbb236342458b Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Tue, 29 Mar 2011 22:37:43 +0530
+Subject: [PATCH 5/6] OMAP2+: hwmod: Follow the recomended PRCM sequence
+
+Follow the recomended PRCM sequence.
+This still does not take care of Optional clocks.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+---
+ arch/arm/mach-omap2/omap_hwmod.c | 9 ++++++++-
+ 1 files changed, 8 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
+index e034294..fc0db0c 100644
+--- a/arch/arm/mach-omap2/omap_hwmod.c
++++ b/arch/arm/mach-omap2/omap_hwmod.c
+@@ -1223,6 +1223,7 @@ static int _reset(struct omap_hwmod *oh)
+ static int _enable(struct omap_hwmod *oh)
+ {
+ int r;
++ int hwsup = 0;
+
+ if (oh->_state != _HWMOD_STATE_INITIALIZED &&
+ oh->_state != _HWMOD_STATE_IDLE &&
+@@ -1250,10 +1251,16 @@ static int _enable(struct omap_hwmod *oh)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
+
+ _add_initiator_dep(oh, mpu_oh);
++ if (oh->_clk && oh->_clk->clkdm) {
++ hwsup = clkdm_is_idle(oh->_clk->clkdm);
++ clkdm_wakeup(oh->_clk->clkdm);
++ }
+ _enable_clocks(oh);
+-
+ r = _wait_target_ready(oh);
+ if (!r) {
++ if (oh->_clk && oh->_clk->clkdm && hwsup)
++ clkdm_allow_idle(oh->_clk->clkdm);
++
+ oh->_state = _HWMOD_STATE_ENABLED;
+
+ /* Access the sysconfig only if the target is ready */
+--
+1.6.6.1
+
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 @@
+From 7b74888d198c260992349fab214cad3adf853ef9 Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Tue, 2 Mar 2010 17:25:30 +0530
+Subject: [PATCH 6/6] OMAP: Serial: Check wk_st only if present
+
+Uart on the resume path tries to read wk_st registers, even
+on architectures were its not present/populated.
+This patch fixes the issue.
+
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+---
+ arch/arm/mach-omap2/serial.c | 5 +++--
+ 1 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
+index 1ac361b..a0046ce 100644
+--- a/arch/arm/mach-omap2/serial.c
++++ b/arch/arm/mach-omap2/serial.c
+@@ -418,8 +418,9 @@ void omap_uart_resume_idle(int num)
+ }
+
+ /* Check for normal UART wakeup */
+- if (__raw_readl(uart->wk_st) & uart->wk_mask)
+- omap_uart_block_sleep(uart);
++ if (uart->wk_st && uart->wk_mask)
++ if (__raw_readl(uart->wk_st) & uart->wk_mask)
++ omap_uart_block_sleep(uart);
+ return;
+ }
+ }
+--
+1.6.6.1
+
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 @@
+From 4af697edf9d1d85d2735e86e86e1203c3509dcba Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Sat, 12 Feb 2011 17:27:14 +0530
+Subject: [PATCH 01/12] OMAP3+: voltage: remove spurious pr_notice for debugfs
+
+cat of debugfs entry for vp_volt provides voltage. The additional pr_notice
+is just spam on console and provides no additional information.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/voltage.c | 1 -
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
+index 0c1552d..9ef3789 100644
+--- a/arch/arm/mach-omap2/voltage.c
++++ b/arch/arm/mach-omap2/voltage.c
+@@ -148,7 +148,6 @@ static int vp_volt_debug_get(void *data, u64 *val)
+ }
+
+ vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
+- pr_notice("curr_vsel = %x\n", vsel);
+
+ if (!vdd->pmic_info->vsel_to_uv) {
+ pr_warning("PMIC function to convert vsel to voltage"
+--
+1.6.6.1
+
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 @@
+From 37fb1c8eeecd39542716d3d0c7c5e3ca0eb198f8 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Sun, 13 Mar 2011 09:07:23 +0530
+Subject: [PATCH 02/12] OMAP4: PM: remove redundant #ifdef CONFIG_PM
+
+pm44xx.c is built only when CONFIG_PM is setup,
+remove redundant CONFIG_PM check.
+
+This also fixes:
+https://bugzilla.kernel.org/show_bug.cgi?id=25022
+
+Reported-by: Martin Etti <ettl.martin@gmx.de>
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/pm44xx.c | 2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
+index 76cfff2..59a870b 100644
+--- a/arch/arm/mach-omap2/pm44xx.c
++++ b/arch/arm/mach-omap2/pm44xx.c
+@@ -105,13 +105,11 @@ static int __init omap4_pm_init(void)
+
+ pr_err("Power Management for TI OMAP4.\n");
+
+-#ifdef CONFIG_PM
+ ret = pwrdm_for_each(pwrdms_setup, NULL);
+ if (ret) {
+ pr_err("Failed to setup powerdomains\n");
+ goto err2;
+ }
+-#endif
+
+ #ifdef CONFIG_SUSPEND
+ suspend_set_ops(&omap_pm_ops);
+--
+1.6.6.1
+
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 @@
+From a22a0dcefe99c8ee260e0c489bc44e6e14bb1ccb Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@nokia.com>
+Date: Thu, 24 Mar 2011 18:35:31 +0200
+Subject: [PATCH 03/12] OMAP3+: smartreflex: fix sr_late_init() error path in probe
+
+sr_late_init() will take care of freeing the resources.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index 13e24f9..dbc4b6f 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -883,7 +883,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ ret = sr_late_init(sr_info);
+ if (ret) {
+ pr_warning("%s: Error in SR late init\n", __func__);
+- goto err_release_region;
++ return ret;
+ }
+ }
+
+--
+1.6.6.1
+
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 @@
+From db9c7da6a78be8584c96c83a3a2d1c8aeb623da8 Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@nokia.com>
+Date: Thu, 24 Mar 2011 18:35:32 +0200
+Subject: [PATCH 04/12] OMAP3+: smartreflex: request the memory region
+
+We are releasing the memory region, but never actually request it.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 8 ++++++++
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index dbc4b6f..703143a 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -847,6 +847,14 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ goto err_free_devinfo;
+ }
+
++ mem = request_mem_region(mem->start, resource_size(mem),
++ dev_name(&pdev->dev));
++ if (!mem) {
++ dev_err(&pdev->dev, "%s: no mem region\n", __func__);
++ ret = -EBUSY;
++ goto err_free_devinfo;
++ }
++
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ pm_runtime_enable(&pdev->dev);
+--
+1.6.6.1
+
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 @@
+From b3ca51ac09da7c260c28df396d4c830814697ff0 Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@nokia.com>
+Date: Thu, 24 Mar 2011 18:35:33 +0200
+Subject: [PATCH 05/12] OMAP3+: smartreflex: fix ioremap leak on probe error
+
+Add missing iounmap() to error paths.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 10 ++++++----
+ 1 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index 703143a..156807e 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -904,7 +904,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
+ if (!vdd_dbg_dir) {
+ ret = -EINVAL;
+- goto err_release_region;
++ goto err_iounmap;
+ }
+
+ sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
+@@ -912,7 +912,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
+ __func__);
+ ret = PTR_ERR(sr_info->dbg_dir);
+- goto err_release_region;
++ goto err_iounmap;
+ }
+
+ (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
+@@ -929,7 +929,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
+ "for n-values\n", __func__);
+ ret = PTR_ERR(nvalue_dir);
+- goto err_release_region;
++ goto err_iounmap;
+ }
+
+ omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
+@@ -939,7 +939,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ "entries for n-values\n",
+ __func__, sr_info->voltdm->name);
+ ret = -ENODATA;
+- goto err_release_region;
++ goto err_iounmap;
+ }
+
+ for (i = 0; i < sr_info->nvalue_count; i++) {
+@@ -953,6 +953,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+
+ return ret;
+
++err_iounmap:
++ iounmap(sr_info->base);
+ err_release_region:
+ release_mem_region(mem->start, resource_size(mem));
+ err_free_devinfo:
+--
+1.6.6.1
+
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 @@
+From 92e63a2f098ce344cfc51ec9a7420e1a5cf85c3e Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@nokia.com>
+Date: Thu, 24 Mar 2011 18:35:34 +0200
+Subject: [PATCH 06/12] OMAP3+: smartreflex: delete instance from sr_list on probe error
+
+If the probe fails, the node should be deleted from sr_list.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index 156807e..f0a488a 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -954,6 +954,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ return ret;
+
+ err_iounmap:
++ list_del(&sr_info->node);
+ iounmap(sr_info->base);
+ err_release_region:
+ release_mem_region(mem->start, resource_size(mem));
+--
+1.6.6.1
+
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 @@
+From c194377152df812bcb29fff8f217ffbde59089be Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@nokia.com>
+Date: Thu, 24 Mar 2011 18:35:35 +0200
+Subject: [PATCH 07/12] OMAP3+: smartreflex: delete debugfs entries on probe error
+
+Delete created debugfs entries if probe fails.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index f0a488a..fb7dc52 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -929,7 +929,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
+ "for n-values\n", __func__);
+ ret = PTR_ERR(nvalue_dir);
+- goto err_iounmap;
++ goto err_debugfs;
+ }
+
+ omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
+@@ -939,7 +939,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+ "entries for n-values\n",
+ __func__, sr_info->voltdm->name);
+ ret = -ENODATA;
+- goto err_iounmap;
++ goto err_debugfs;
+ }
+
+ for (i = 0; i < sr_info->nvalue_count; i++) {
+@@ -953,6 +953,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
+
+ return ret;
+
++err_debugfs:
++ debugfs_remove_recursive(sr_info->dbg_dir);
+ err_iounmap:
+ list_del(&sr_info->node);
+ iounmap(sr_info->base);
+--
+1.6.6.1
+
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 @@
+From 2b9e07516cc3853340b5e06e9ae7244ca5681466 Mon Sep 17 00:00:00 2001
+From: Jean Pihet <j-pihet@ti.com>
+Date: Fri, 29 Apr 2011 11:26:22 +0200
+Subject: [PATCH 08/12] OMAP3 cpuidle: remove useless SDP specific timings
+
+The cpuidle states settings can be overriden by some board-
+specific settings, by calling omap3_pm_init_cpuidle.
+Remove the 3430SDP specific states settings registration
+since the figures are identical to the default ones (in cpuidle34xx.c).
+
+Signed-off-by: Jean Pihet <j-pihet@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/board-3430sdp.c | 19 -------------------
+ 1 files changed, 0 insertions(+), 19 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
+index 9afd087..7ffad7b 100644
+--- a/arch/arm/mach-omap2/board-3430sdp.c
++++ b/arch/arm/mach-omap2/board-3430sdp.c
+@@ -59,24 +59,6 @@
+
+ #define TWL4030_MSECURE_GPIO 22
+
+-/* FIXME: These values need to be updated based on more profiling on 3430sdp*/
+-static struct cpuidle_params omap3_cpuidle_params_table[] = {
+- /* C1 */
+- {1, 2, 2, 5},
+- /* C2 */
+- {1, 10, 10, 30},
+- /* C3 */
+- {1, 50, 50, 300},
+- /* C4 */
+- {1, 1500, 1800, 4000},
+- /* C5 */
+- {1, 2500, 7500, 12000},
+- /* C6 */
+- {1, 3000, 8500, 15000},
+- /* C7 */
+- {1, 10000, 30000, 300000},
+-};
+-
+ static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+@@ -883,7 +865,6 @@ static void __init omap_3430sdp_init(void)
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_board_config = sdp3430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+- omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
+ omap3430_i2c_init();
+ omap_display_init(&sdp3430_dss_data);
+ if (omap_rev() > OMAP3430_REV_ES1_0)
+--
+1.6.6.1
+
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 @@
+From a0f28097b944930e479998780863b9e5a39e30b3 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Mon, 14 Feb 2011 12:16:36 +0530
+Subject: [PATCH 09/12] OMAP3+: SR: make notify independent of class
+
+Interrupt notification mechanism of SmartReflex can be used by the
+choice of implementation of the class driver. For example, Class 2 and
+Class 1.5 of SmartReflex can both use the interrupt notification to
+identify the transition of voltage or other events.
+
+Hence, the actual class does not matter for notifier. Let the class
+driver's handling decide how it should be used. SmartReflex driver
+should provide just the primitives.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 6 ++----
+ 1 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index fb7dc52..3ee7261 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -143,7 +143,7 @@ static irqreturn_t sr_interrupt(int irq, void *data)
+ sr_write_reg(sr_info, IRQSTATUS, status);
+ }
+
+- if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
++ if (sr_class->notify)
+ sr_class->notify(sr_info->voltdm, status);
+
+ return IRQ_HANDLED;
+@@ -258,9 +258,7 @@ static int sr_late_init(struct omap_sr *sr_info)
+ struct resource *mem;
+ int ret = 0;
+
+- if (sr_class->class_type == SR_CLASS2 &&
+- sr_class->notify_flags && sr_info->irq) {
+-
++ if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
+ name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
+ if (name == NULL) {
+ ret = -ENOMEM;
+--
+1.6.6.1
+
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 @@
+From ca5dc57538a566681731102e09a9d1865a4a7020 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Mon, 14 Feb 2011 12:41:10 +0530
+Subject: [PATCH 10/12] OMAP3+: SR: disable interrupt by default
+
+We will enable and disable interrupt on a need basis in the class
+driver. We need to keep the IRQ disabled by default else the
+forceupdate or vcbypass events could trigger events that we don't
+need/expect to handle.
+
+This is a preparation for SmartReflex AVS class drivers such as
+class 2 and class 1.5 which would need to use interrupts. Existing
+SmartReflex AVS class 3 driver does not require to use interrupts
+and is not impacted by this change.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index 3ee7261..616ef62 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -268,6 +268,7 @@ static int sr_late_init(struct omap_sr *sr_info)
+ 0, name, (void *)sr_info);
+ if (ret)
+ goto error;
++ disable_irq(sr_info->irq);
+ }
+
+ if (pdata && pdata->enable_on_init)
+--
+1.6.6.1
+
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 @@
+From 4aa67e94d6b13905abcf3e95cb66ea7be9c2e8dd Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Mon, 14 Feb 2011 21:14:17 +0530
+Subject: [PATCH 11/12] OMAP3+: SR: enable/disable SR only on need
+
+Since we already know the state of the autocomp enablement, we can
+see if the requested state is different from the current state and
+enable/disable SR only on the need basis.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 11 +++++++----
+ 1 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index 616ef62..3bd9fac 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -807,10 +807,13 @@ static int omap_sr_autocomp_store(void *data, u64 val)
+ return -EINVAL;
+ }
+
+- if (!val)
+- sr_stop_vddautocomp(sr_info);
+- else
+- sr_start_vddautocomp(sr_info);
++ /* control enable/disable only if there is a delta in value */
++ if (sr_info->autocomp_active != val) {
++ if (!val)
++ sr_stop_vddautocomp(sr_info);
++ else
++ sr_start_vddautocomp(sr_info);
++ }
+
+ return 0;
+ }
+--
+1.6.6.1
+
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 @@
+From 0c2089eecdfc3a85a376eddf9c77857f3d575be6 Mon Sep 17 00:00:00 2001
+From: Nishanth Menon <nm@ti.com>
+Date: Mon, 14 Feb 2011 12:33:13 +0530
+Subject: [PATCH 12/12] OMAP3+: SR: fix cosmetic indentation
+
+Error label case seems to have a 2 tab indentation when just 1 is
+necessary.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Kevin Hilman <khilman@ti.com>
+Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
+---
+ arch/arm/mach-omap2/smartreflex.c | 20 ++++++++++----------
+ 1 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
+index 3bd9fac..2ce2fb7 100644
+--- a/arch/arm/mach-omap2/smartreflex.c
++++ b/arch/arm/mach-omap2/smartreflex.c
+@@ -277,16 +277,16 @@ static int sr_late_init(struct omap_sr *sr_info)
+ return ret;
+
+ error:
+- iounmap(sr_info->base);
+- mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
+- release_mem_region(mem->start, resource_size(mem));
+- list_del(&sr_info->node);
+- dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
+- "interrupt handler. Smartreflex will"
+- "not function as desired\n", __func__);
+- kfree(name);
+- kfree(sr_info);
+- return ret;
++ iounmap(sr_info->base);
++ mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
++ release_mem_region(mem->start, resource_size(mem));
++ list_del(&sr_info->node);
++ dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
++ "interrupt handler. Smartreflex will"
++ "not function as desired\n", __func__);
++ kfree(name);
++ kfree(sr_info);
++ return ret;
+ }
+
+ static void sr_v1_disable(struct omap_sr *sr)
+--
+1.6.6.1
+