aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 20:43:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 20:43:53 -0400
commita5ebba6b54bc8038a38d3eacac3a79bbeaf3ee24 (patch)
treed36eb26a7efd4e00381bc9f6474ea3ec31340585
parente81218f5f0fd219bd75768d845159ba4810bdd48 (diff)
parent6b21a9ce0402e0c5fd2adfa3d41328fdd8f55a9a (diff)
Merge tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull arm-soc power management changes from Arnd Bergmann: "These are various power management related changes, mainly concerning cpuidle on i.MX and OMAP, as well as a the move of the omap smartreflex driver to live in the power subsystem." Fix up conflicts in arch/arm/mach-{imx/mach-imx6q.c,omap2/prm2xxx_3xxx.h} * tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (37 commits) ARM: OMAP2+: PM: fix IRQ_NOAUTOEN removal by mis-merge ARM: OMAP2+: do not allow SmartReflex to be built as a module ARM: OMAP2: Use hwmod to initialize mmc for 2420 ARM: OMAP3: PM: cpuidle: optimize the clkdm idle latency in C1 state ARM: OMAP3: PM: cpuidle: optimize the PER latency in C1 state ARM: OMAP3: PM: cpuidle: default to C1 in next_valid_state ARM: OMAP3: PM: cleanup cam_pwrdm leftovers ARM: OMAP3: PM: call pre/post transition per powerdomain ARM: OMAP2+: powerdomain: allow pre/post transtion to be per pwrdm ARM: OMAP3: PM: Remove IO Daisychain control from cpuidle ARM: OMAP3PLUS: hwmod: reconfigure IO Daisychain during hwmod mux ARM: OMAP3+: PRM: Enable IO wake up ARM: OMAP4: PRM: Add IO Daisychain support ARM: OMAP3: PM: Move IO Daisychain function to omap3 prm file ARM: OMAP3: PM: correct enable/disable of daisy io chain ARM: OMAP2+: PRM: fix compile for OMAP4-only build W1: OMAP HDQ1W: use runtime PM ARM: OMAP2+: HDQ1W: use omap_device W1: OMAP HDQ1W: use 32-bit register accesses W1: OMAP HDQ1W: allow driver to be built on all OMAP2+ ...
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c2
-rw-r--r--arch/arm/mach-imx/imx53-dt.c1
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c19
-rw-r--r--arch/arm/mach-imx/mach-mx53_ard.c1
-rw-r--r--arch/arm/mach-imx/mach-mx53_evk.c1
-rw-r--r--arch/arm/mach-imx/mach-mx53_loco.c1
-rw-r--r--arch/arm/mach-imx/mach-mx53_smd.c1
-rw-r--r--arch/arm/mach-imx/mm-imx5.c26
-rw-r--r--arch/arm/mach-imx/pm-imx5.c111
-rw-r--r--arch/arm/mach-omap2/Makefile5
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c71
-rw-r--r--arch/arm/mach-omap2/devices.c108
-rw-r--r--arch/arm/mach-omap2/hdq1w.c26
-rw-r--r--arch/arm/mach-omap2/msdi.c73
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c38
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c12
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c3
-rw-r--r--arch/arm/mach-omap2/pm.h2
-rw-r--r--arch/arm/mach-omap2/pm34xx.c63
-rw-r--r--arch/arm/mach-omap2/powerdomain.c16
-rw-r--r--arch/arm/mach-omap2/powerdomain.h4
-rw-r--r--arch/arm/mach-omap2/prcm-common.h8
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c48
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h5
-rw-r--r--arch/arm/mach-omap2/prm44xx.c63
-rw-r--r--arch/arm/mach-omap2/prm44xx.h2
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c29
-rw-r--r--arch/arm/mach-omap2/sr_device.c39
-rw-r--r--arch/arm/mach-omap2/voltage.h21
-rw-r--r--arch/arm/plat-mxc/Makefile1
-rw-r--r--arch/arm/plat-mxc/cpuidle.c80
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/cpuidle.h22
-rw-r--r--arch/arm/plat-mxc/include/mach/hardware.h25
-rw-r--r--arch/arm/plat-mxc/tzic.c4
-rw-r--r--arch/arm/plat-omap/Kconfig31
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h21
-rw-r--r--drivers/power/Kconfig2
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/avs/Kconfig12
-rw-r--r--drivers/power/avs/Makefile1
-rw-r--r--drivers/power/avs/smartreflex.c (renamed from arch/arm/mach-omap2/smartreflex.c)161
-rw-r--r--drivers/w1/masters/Kconfig2
-rw-r--r--drivers/w1/masters/omap_hdq.c86
-rw-r--r--include/linux/power/smartreflex.h (renamed from arch/arm/mach-omap2/smartreflex.h)74
46 files changed, 810 insertions, 522 deletions
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index a2200c77bf70..4b89fae14a5a 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -279,6 +279,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
279 clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); 279 clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
280 clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0"); 280 clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0");
281 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); 281 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
282 clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
282 283
283 /* Set SDHC parents to be PLL2 */ 284 /* Set SDHC parents to be PLL2 */
284 clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]); 285 clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]);
@@ -336,7 +337,6 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
336 clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL); 337 clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL);
337 clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0"); 338 clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0");
338 clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0"); 339 clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
339 clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
340 clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu"); 340 clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu");
341 clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu"); 341 clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu");
342 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu"); 342 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu");
diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c
index fdd90805d98e..1b7a2fc36591 100644
--- a/arch/arm/mach-imx/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
@@ -120,6 +120,7 @@ DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
120 .handle_irq = imx53_handle_irq, 120 .handle_irq = imx53_handle_irq,
121 .timer = &imx53_timer, 121 .timer = &imx53_timer,
122 .init_machine = imx53_dt_init, 122 .init_machine = imx53_dt_init,
123 .init_late = imx53_init_late,
123 .dt_compat = imx53_dt_board_compat, 124 .dt_compat = imx53_dt_board_compat,
124 .restart = mxc_restart, 125 .restart = mxc_restart,
125MACHINE_END 126MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 426d2087c460..5ec0608f2a76 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -12,7 +12,9 @@
12 12
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/clkdev.h> 14#include <linux/clkdev.h>
15#include <linux/cpuidle.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/export.h>
16#include <linux/init.h> 18#include <linux/init.h>
17#include <linux/io.h> 19#include <linux/io.h>
18#include <linux/irq.h> 20#include <linux/irq.h>
@@ -24,6 +26,7 @@
24#include <linux/phy.h> 26#include <linux/phy.h>
25#include <linux/micrel_phy.h> 27#include <linux/micrel_phy.h>
26#include <linux/mfd/anatop.h> 28#include <linux/mfd/anatop.h>
29#include <asm/cpuidle.h>
27#include <asm/smp_twd.h> 30#include <asm/smp_twd.h>
28#include <asm/hardware/cache-l2x0.h> 31#include <asm/hardware/cache-l2x0.h>
29#include <asm/hardware/gic.h> 32#include <asm/hardware/gic.h>
@@ -31,8 +34,10 @@
31#include <asm/mach/time.h> 34#include <asm/mach/time.h>
32#include <asm/system_misc.h> 35#include <asm/system_misc.h>
33#include <mach/common.h> 36#include <mach/common.h>
37#include <mach/cpuidle.h>
34#include <mach/hardware.h> 38#include <mach/hardware.h>
35 39
40
36void imx6q_restart(char mode, const char *cmd) 41void imx6q_restart(char mode, const char *cmd)
37{ 42{
38 struct device_node *np; 43 struct device_node *np;
@@ -169,6 +174,19 @@ static void __init imx6q_init_machine(void)
169 imx6q_usb_init(); 174 imx6q_usb_init();
170} 175}
171 176
177static struct cpuidle_driver imx6q_cpuidle_driver = {
178 .name = "imx6q_cpuidle",
179 .owner = THIS_MODULE,
180 .en_core_tk_irqen = 1,
181 .states[0] = ARM_CPUIDLE_WFI_STATE,
182 .state_count = 1,
183};
184
185static void __init imx6q_init_late(void)
186{
187 imx_cpuidle_init(&imx6q_cpuidle_driver);
188}
189
172static void __init imx6q_map_io(void) 190static void __init imx6q_map_io(void)
173{ 191{
174 imx_lluart_map_io(); 192 imx_lluart_map_io();
@@ -213,6 +231,7 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
213 .handle_irq = imx6q_handle_irq, 231 .handle_irq = imx6q_handle_irq,
214 .timer = &imx6q_timer, 232 .timer = &imx6q_timer,
215 .init_machine = imx6q_init_machine, 233 .init_machine = imx6q_init_machine,
234 .init_late = imx6q_init_late,
216 .dt_compat = imx6q_dt_compat, 235 .dt_compat = imx6q_dt_compat,
217 .restart = imx6q_restart, 236 .restart = imx6q_restart,
218MACHINE_END 237MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx53_ard.c b/arch/arm/mach-imx/mach-mx53_ard.c
index f641a1758691..6c28e65f424d 100644
--- a/arch/arm/mach-imx/mach-mx53_ard.c
+++ b/arch/arm/mach-imx/mach-mx53_ard.c
@@ -267,5 +267,6 @@ MACHINE_START(MX53_ARD, "Freescale MX53 ARD Board")
267 .handle_irq = imx53_handle_irq, 267 .handle_irq = imx53_handle_irq,
268 .timer = &mx53_ard_timer, 268 .timer = &mx53_ard_timer,
269 .init_machine = mx53_ard_board_init, 269 .init_machine = mx53_ard_board_init,
270 .init_late = imx53_init_late,
270 .restart = mxc_restart, 271 .restart = mxc_restart,
271MACHINE_END 272MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx53_evk.c b/arch/arm/mach-imx/mach-mx53_evk.c
index a1060b26fb23..09fe2197b491 100644
--- a/arch/arm/mach-imx/mach-mx53_evk.c
+++ b/arch/arm/mach-imx/mach-mx53_evk.c
@@ -174,5 +174,6 @@ MACHINE_START(MX53_EVK, "Freescale MX53 EVK Board")
174 .handle_irq = imx53_handle_irq, 174 .handle_irq = imx53_handle_irq,
175 .timer = &mx53_evk_timer, 175 .timer = &mx53_evk_timer,
176 .init_machine = mx53_evk_board_init, 176 .init_machine = mx53_evk_board_init,
177 .init_late = imx53_init_late,
177 .restart = mxc_restart, 178 .restart = mxc_restart,
178MACHINE_END 179MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx53_loco.c b/arch/arm/mach-imx/mach-mx53_loco.c
index 388c415d6b62..8abe23c1d3c8 100644
--- a/arch/arm/mach-imx/mach-mx53_loco.c
+++ b/arch/arm/mach-imx/mach-mx53_loco.c
@@ -316,5 +316,6 @@ MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board")
316 .handle_irq = imx53_handle_irq, 316 .handle_irq = imx53_handle_irq,
317 .timer = &mx53_loco_timer, 317 .timer = &mx53_loco_timer,
318 .init_machine = mx53_loco_board_init, 318 .init_machine = mx53_loco_board_init,
319 .init_late = imx53_init_late,
319 .restart = mxc_restart, 320 .restart = mxc_restart,
320MACHINE_END 321MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx53_smd.c b/arch/arm/mach-imx/mach-mx53_smd.c
index f297df7ccb39..b15d6a6d3b68 100644
--- a/arch/arm/mach-imx/mach-mx53_smd.c
+++ b/arch/arm/mach-imx/mach-mx53_smd.c
@@ -163,5 +163,6 @@ MACHINE_START(MX53_SMD, "Freescale MX53 SMD Board")
163 .handle_irq = imx53_handle_irq, 163 .handle_irq = imx53_handle_irq,
164 .timer = &mx53_smd_timer, 164 .timer = &mx53_smd_timer,
165 .init_machine = mx53_smd_board_init, 165 .init_machine = mx53_smd_board_init,
166 .init_late = imx53_init_late,
166 .restart = mxc_restart, 167 .restart = mxc_restart,
167MACHINE_END 168MACHINE_END
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index 1d003053d562..f19d604e1b2a 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -16,7 +16,6 @@
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/pinctrl/machine.h> 17#include <linux/pinctrl/machine.h>
18 18
19#include <asm/system_misc.h>
20#include <asm/mach/map.h> 19#include <asm/mach/map.h>
21 20
22#include <mach/hardware.h> 21#include <mach/hardware.h>
@@ -24,24 +23,6 @@
24#include <mach/devices-common.h> 23#include <mach/devices-common.h>
25#include <mach/iomux-v3.h> 24#include <mach/iomux-v3.h>
26 25
27static struct clk *gpc_dvfs_clk;
28
29static void imx5_idle(void)
30{
31 /* gpc clock is needed for SRPG */
32 if (gpc_dvfs_clk == NULL) {
33 gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
34 if (IS_ERR(gpc_dvfs_clk))
35 return;
36 clk_prepare(gpc_dvfs_clk);
37 }
38 clk_enable(gpc_dvfs_clk);
39 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
40 if (!tzic_enable_wake())
41 cpu_do_idle();
42 clk_disable(gpc_dvfs_clk);
43}
44
45/* 26/*
46 * Define the MX50 memory map. 27 * Define the MX50 memory map.
47 */ 28 */
@@ -105,7 +86,6 @@ void __init imx51_init_early(void)
105 mxc_set_cpu_type(MXC_CPU_MX51); 86 mxc_set_cpu_type(MXC_CPU_MX51);
106 mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR)); 87 mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
107 mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR)); 88 mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
108 arm_pm_idle = imx5_idle;
109} 89}
110 90
111void __init imx53_init_early(void) 91void __init imx53_init_early(void)
@@ -243,4 +223,10 @@ void __init imx53_soc_init(void)
243void __init imx51_init_late(void) 223void __init imx51_init_late(void)
244{ 224{
245 mx51_neon_fixup(); 225 mx51_neon_fixup();
226 imx51_pm_init();
227}
228
229void __init imx53_init_late(void)
230{
231 imx53_pm_init();
246} 232}
diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c
index e26a9cb05ed8..19621ed1ffa5 100644
--- a/arch/arm/mach-imx/pm-imx5.c
+++ b/arch/arm/mach-imx/pm-imx5.c
@@ -12,19 +12,30 @@
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/export.h>
15#include <asm/cacheflush.h> 16#include <asm/cacheflush.h>
17#include <asm/system_misc.h>
16#include <asm/tlbflush.h> 18#include <asm/tlbflush.h>
17#include <mach/common.h> 19#include <mach/common.h>
20#include <mach/cpuidle.h>
18#include <mach/hardware.h> 21#include <mach/hardware.h>
19#include "crm-regs-imx5.h" 22#include "crm-regs-imx5.h"
20 23
21static struct clk *gpc_dvfs_clk; 24/*
25 * The WAIT_UNCLOCKED_POWER_OFF state only requires <= 500ns to exit.
26 * This is also the lowest power state possible without affecting
27 * non-cpu parts of the system. For these reasons, imx5 should default
28 * to always using this state for cpu idling. The PM_SUSPEND_STANDBY also
29 * uses this state and needs to take no action when registers remain confgiured
30 * for this state.
31 */
32#define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF
22 33
23/* 34/*
24 * set cpu low power mode before WFI instruction. This function is called 35 * set cpu low power mode before WFI instruction. This function is called
25 * mx5 because it can be used for mx50, mx51, and mx53. 36 * mx5 because it can be used for mx50, mx51, and mx53.
26 */ 37 */
27void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) 38static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
28{ 39{
29 u32 plat_lpc, arm_srpgcr, ccm_clpcr; 40 u32 plat_lpc, arm_srpgcr, ccm_clpcr;
30 u32 empgc0, empgc1; 41 u32 empgc0, empgc1;
@@ -87,11 +98,6 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
87 } 98 }
88} 99}
89 100
90static int mx5_suspend_prepare(void)
91{
92 return clk_prepare_enable(gpc_dvfs_clk);
93}
94
95static int mx5_suspend_enter(suspend_state_t state) 101static int mx5_suspend_enter(suspend_state_t state)
96{ 102{
97 switch (state) { 103 switch (state) {
@@ -99,7 +105,7 @@ static int mx5_suspend_enter(suspend_state_t state)
99 mx5_cpu_lp_set(STOP_POWER_OFF); 105 mx5_cpu_lp_set(STOP_POWER_OFF);
100 break; 106 break;
101 case PM_SUSPEND_STANDBY: 107 case PM_SUSPEND_STANDBY:
102 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); 108 /* DEFAULT_IDLE_STATE already configured */
103 break; 109 break;
104 default: 110 default:
105 return -EINVAL; 111 return -EINVAL;
@@ -114,12 +120,10 @@ static int mx5_suspend_enter(suspend_state_t state)
114 __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); 120 __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
115 } 121 }
116 cpu_do_idle(); 122 cpu_do_idle();
117 return 0;
118}
119 123
120static void mx5_suspend_finish(void) 124 /* return registers to default idle state */
121{ 125 mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
122 clk_disable_unprepare(gpc_dvfs_clk); 126 return 0;
123} 127}
124 128
125static int mx5_pm_valid(suspend_state_t state) 129static int mx5_pm_valid(suspend_state_t state)
@@ -129,25 +133,80 @@ static int mx5_pm_valid(suspend_state_t state)
129 133
130static const struct platform_suspend_ops mx5_suspend_ops = { 134static const struct platform_suspend_ops mx5_suspend_ops = {
131 .valid = mx5_pm_valid, 135 .valid = mx5_pm_valid,
132 .prepare = mx5_suspend_prepare,
133 .enter = mx5_suspend_enter, 136 .enter = mx5_suspend_enter,
134 .finish = mx5_suspend_finish,
135}; 137};
136 138
137static int __init mx5_pm_init(void) 139static inline int imx5_cpu_do_idle(void)
140{
141 int ret = tzic_enable_wake();
142
143 if (likely(!ret))
144 cpu_do_idle();
145
146 return ret;
147}
148
149static void imx5_pm_idle(void)
150{
151 imx5_cpu_do_idle();
152}
153
154static int imx5_cpuidle_enter(struct cpuidle_device *dev,
155 struct cpuidle_driver *drv, int idx)
156{
157 int ret;
158
159 ret = imx5_cpu_do_idle();
160 if (ret < 0)
161 return ret;
162
163 return idx;
164}
165
166static struct cpuidle_driver imx5_cpuidle_driver = {
167 .name = "imx5_cpuidle",
168 .owner = THIS_MODULE,
169 .en_core_tk_irqen = 1,
170 .states[0] = {
171 .enter = imx5_cpuidle_enter,
172 .exit_latency = 2,
173 .target_residency = 1,
174 .flags = CPUIDLE_FLAG_TIME_VALID,
175 .name = "IMX5 SRPG",
176 .desc = "CPU state retained,powered off",
177 },
178 .state_count = 1,
179};
180
181static int __init imx5_pm_common_init(void)
138{ 182{
139 if (!cpu_is_mx51() && !cpu_is_mx53()) 183 int ret;
140 return 0; 184 struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
141 185
142 if (gpc_dvfs_clk == NULL) 186 if (IS_ERR(gpc_dvfs_clk))
143 gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); 187 return PTR_ERR(gpc_dvfs_clk);
144 188
145 if (!IS_ERR(gpc_dvfs_clk)) { 189 ret = clk_prepare_enable(gpc_dvfs_clk);
146 if (cpu_is_mx51()) 190 if (ret)
147 suspend_set_ops(&mx5_suspend_ops); 191 return ret;
148 } else
149 return -EPERM;
150 192
193 arm_pm_idle = imx5_pm_idle;
194
195 /* Set the registers to the default cpu idle state. */
196 mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
197
198 imx_cpuidle_init(&imx5_cpuidle_driver);
151 return 0; 199 return 0;
152} 200}
153device_initcall(mx5_pm_init); 201
202void __init imx51_pm_init(void)
203{
204 int ret = imx5_pm_common_init();
205 if (!ret)
206 suspend_set_ops(&mx5_suspend_ops);
207}
208
209void __init imx53_pm_init(void)
210{
211 imx5_pm_common_init();
212}
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 19b771d0c0d7..b7a4ab65faca 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -74,8 +74,9 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
74obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o 74obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o
75obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o 75obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o
76obj-$(CONFIG_PM_DEBUG) += pm-debug.o 76obj-$(CONFIG_PM_DEBUG) += pm-debug.o
77obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o 77
78obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o 78obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o
79obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
79 80
80AFLAGS_sleep24xx.o :=-Wa,-march=armv6 81AFLAGS_sleep24xx.o :=-Wa,-march=armv6
81AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) 82AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 31344528eb54..f2a49a48ef59 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -75,20 +75,6 @@ static struct omap3_idle_statedata omap3_idle_data[] = {
75 75
76static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; 76static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
77 77
78static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
79 struct clockdomain *clkdm)
80{
81 clkdm_allow_idle(clkdm);
82 return 0;
83}
84
85static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
86 struct clockdomain *clkdm)
87{
88 clkdm_deny_idle(clkdm);
89 return 0;
90}
91
92static int __omap3_enter_idle(struct cpuidle_device *dev, 78static int __omap3_enter_idle(struct cpuidle_device *dev,
93 struct cpuidle_driver *drv, 79 struct cpuidle_driver *drv,
94 int index) 80 int index)
@@ -106,8 +92,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
106 92
107 /* Deny idle for C1 */ 93 /* Deny idle for C1 */
108 if (index == 0) { 94 if (index == 0) {
109 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); 95 clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]);
110 pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); 96 clkdm_deny_idle(core_pd->pwrdm_clkdms[0]);
111 } 97 }
112 98
113 /* 99 /*
@@ -129,8 +115,8 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,
129 115
130 /* Re-allow idle for C1 */ 116 /* Re-allow idle for C1 */
131 if (index == 0) { 117 if (index == 0) {
132 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); 118 clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]);
133 pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); 119 clkdm_allow_idle(core_pd->pwrdm_clkdms[0]);
134 } 120 }
135 121
136return_sleep_time: 122return_sleep_time:
@@ -176,7 +162,7 @@ static int next_valid_state(struct cpuidle_device *dev,
176 u32 mpu_deepest_state = PWRDM_POWER_RET; 162 u32 mpu_deepest_state = PWRDM_POWER_RET;
177 u32 core_deepest_state = PWRDM_POWER_RET; 163 u32 core_deepest_state = PWRDM_POWER_RET;
178 int idx; 164 int idx;
179 int next_index = -1; 165 int next_index = 0; /* C1 is the default value */
180 166
181 if (enable_off_mode) { 167 if (enable_off_mode) {
182 mpu_deepest_state = PWRDM_POWER_OFF; 168 mpu_deepest_state = PWRDM_POWER_OFF;
@@ -207,12 +193,6 @@ static int next_valid_state(struct cpuidle_device *dev,
207 } 193 }
208 } 194 }
209 195
210 /*
211 * C1 is always valid.
212 * So, no need to check for 'next_index == -1' outside
213 * this loop.
214 */
215
216 return next_index; 196 return next_index;
217} 197}
218 198
@@ -226,23 +206,22 @@ static int next_valid_state(struct cpuidle_device *dev,
226 * the device to the specified or a safer state. 206 * the device to the specified or a safer state.
227 */ 207 */
228static int omap3_enter_idle_bm(struct cpuidle_device *dev, 208static int omap3_enter_idle_bm(struct cpuidle_device *dev,
229 struct cpuidle_driver *drv, 209 struct cpuidle_driver *drv,
230 int index) 210 int index)
231{ 211{
232 int new_state_idx; 212 int new_state_idx;
233 u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state; 213 u32 core_next_state, per_next_state = 0, per_saved_state = 0;
234 struct omap3_idle_statedata *cx; 214 struct omap3_idle_statedata *cx;
235 int ret; 215 int ret;
236 216
237 /* 217 /*
238 * Prevent idle completely if CAM is active. 218 * Use only C1 if CAM is active.
239 * CAM does not have wakeup capability in OMAP3. 219 * CAM does not have wakeup capability in OMAP3.
240 */ 220 */
241 cam_state = pwrdm_read_pwrst(cam_pd); 221 if (pwrdm_read_pwrst(cam_pd) == PWRDM_POWER_ON)
242 if (cam_state == PWRDM_POWER_ON) {
243 new_state_idx = drv->safe_state_index; 222 new_state_idx = drv->safe_state_index;
244 goto select_state; 223 else
245 } 224 new_state_idx = next_valid_state(dev, drv, index);
246 225
247 /* 226 /*
248 * FIXME: we currently manage device-specific idle states 227 * FIXME: we currently manage device-specific idle states
@@ -252,24 +231,28 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
252 * its own code. 231 * its own code.
253 */ 232 */
254 233
255 /* 234 /* Program PER state */
256 * Prevent PER off if CORE is not in retention or off as this 235 cx = &omap3_idle_data[new_state_idx];
257 * would disable PER wakeups completely.
258 */
259 cx = &omap3_idle_data[index];
260 core_next_state = cx->core_state; 236 core_next_state = cx->core_state;
261 per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); 237 per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
262 if ((per_next_state == PWRDM_POWER_OFF) && 238 if (new_state_idx == 0) {
263 (core_next_state > PWRDM_POWER_RET)) 239 /* In C1 do not allow PER state lower than CORE state */
264 per_next_state = PWRDM_POWER_RET; 240 if (per_next_state < core_next_state)
241 per_next_state = core_next_state;
242 } else {
243 /*
244 * Prevent PER OFF if CORE is not in RETention or OFF as this
245 * would disable PER wakeups completely.
246 */
247 if ((per_next_state == PWRDM_POWER_OFF) &&
248 (core_next_state > PWRDM_POWER_RET))
249 per_next_state = PWRDM_POWER_RET;
250 }
265 251
266 /* Are we changing PER target state? */ 252 /* Are we changing PER target state? */
267 if (per_next_state != per_saved_state) 253 if (per_next_state != per_saved_state)
268 pwrdm_set_next_pwrst(per_pd, per_next_state); 254 pwrdm_set_next_pwrst(per_pd, per_next_state);
269 255
270 new_state_idx = next_valid_state(dev, drv, index);
271
272select_state:
273 ret = omap3_enter_idle(dev, drv, new_state_idx); 256 ret = omap3_enter_idle(dev, drv, new_state_idx);
274 257
275 /* Restore original PER state if it was modified */ 258 /* Restore original PER state if it was modified */
@@ -286,7 +269,7 @@ struct cpuidle_driver omap3_idle_driver = {
286 .owner = THIS_MODULE, 269 .owner = THIS_MODULE,
287 .states = { 270 .states = {
288 { 271 {
289 .enter = omap3_enter_idle, 272 .enter = omap3_enter_idle_bm,
290 .exit_latency = 2 + 2, 273 .exit_latency = 2 + 2,
291 .target_residency = 5, 274 .target_residency = 5,
292 .flags = CPUIDLE_FLAG_TIME_VALID, 275 .flags = CPUIDLE_FLAG_TIME_VALID,
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 71651e20a43e..c00c68961bb8 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -27,7 +27,6 @@
27 27
28#include "iomap.h" 28#include "iomap.h"
29#include <plat/board.h> 29#include <plat/board.h>
30#include <plat/mmc.h>
31#include <plat/dma.h> 30#include <plat/dma.h>
32#include <plat/omap_hwmod.h> 31#include <plat/omap_hwmod.h>
33#include <plat/omap_device.h> 32#include <plat/omap_device.h>
@@ -603,112 +602,6 @@ static inline void omap_init_aes(void) { }
603 602
604/*-------------------------------------------------------------------------*/ 603/*-------------------------------------------------------------------------*/
605 604
606#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
607
608static inline void omap242x_mmc_mux(struct omap_mmc_platform_data
609 *mmc_controller)
610{
611 if ((mmc_controller->slots[0].switch_pin > 0) && \
612 (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
613 omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
614 OMAP_PIN_INPUT_PULLUP);
615 if ((mmc_controller->slots[0].gpio_wp > 0) && \
616 (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
617 omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
618 OMAP_PIN_INPUT_PULLUP);
619
620 omap_mux_init_signal("sdmmc_cmd", 0);
621 omap_mux_init_signal("sdmmc_clki", 0);
622 omap_mux_init_signal("sdmmc_clko", 0);
623 omap_mux_init_signal("sdmmc_dat0", 0);
624 omap_mux_init_signal("sdmmc_dat_dir0", 0);
625 omap_mux_init_signal("sdmmc_cmd_dir", 0);
626 if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
627 omap_mux_init_signal("sdmmc_dat1", 0);
628 omap_mux_init_signal("sdmmc_dat2", 0);
629 omap_mux_init_signal("sdmmc_dat3", 0);
630 omap_mux_init_signal("sdmmc_dat_dir1", 0);
631 omap_mux_init_signal("sdmmc_dat_dir2", 0);
632 omap_mux_init_signal("sdmmc_dat_dir3", 0);
633 }
634
635 /*
636 * Use internal loop-back in MMC/SDIO Module Input Clock
637 * selection
638 */
639 if (mmc_controller->slots[0].internal_clock) {
640 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
641 v |= (1 << 24);
642 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
643 }
644}
645
646void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
647{
648 struct platform_device *pdev;
649 struct omap_hwmod *oh;
650 int id = 0;
651 char *oh_name = "msdi1";
652 char *dev_name = "mmci-omap";
653
654 if (!mmc_data[0]) {
655 pr_err("%s fails: Incomplete platform data\n", __func__);
656 return;
657 }
658
659 omap242x_mmc_mux(mmc_data[0]);
660
661 oh = omap_hwmod_lookup(oh_name);
662 if (!oh) {
663 pr_err("Could not look up %s\n", oh_name);
664 return;
665 }
666 pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
667 sizeof(struct omap_mmc_platform_data), NULL, 0, 0);
668 if (IS_ERR(pdev))
669 WARN(1, "Can'd build omap_device for %s:%s.\n",
670 dev_name, oh->name);
671}
672
673#endif
674
675/*-------------------------------------------------------------------------*/
676
677#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
678#define OMAP_HDQ_BASE 0x480B2000
679static struct resource omap_hdq_resources[] = {
680 {
681 .start = OMAP_HDQ_BASE,
682 .end = OMAP_HDQ_BASE + 0x1C,
683 .flags = IORESOURCE_MEM,
684 },
685 {
686 .start = INT_24XX_HDQ_IRQ,
687 .flags = IORESOURCE_IRQ,
688 },
689};
690static struct platform_device omap_hdq_dev = {
691 .name = "omap_hdq",
692 .id = 0,
693 .dev = {
694 .platform_data = NULL,
695 },
696 .num_resources = ARRAY_SIZE(omap_hdq_resources),
697 .resource = omap_hdq_resources,
698};
699static inline void omap_hdq_init(void)
700{
701 if (cpu_is_omap2420())
702 return;
703
704 platform_device_register(&omap_hdq_dev);
705}
706#else
707static inline void omap_hdq_init(void) {}
708#endif
709
710/*---------------------------------------------------------------------------*/
711
712#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \ 605#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
713 defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE) 606 defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
714#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) 607#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
@@ -753,7 +646,6 @@ static int __init omap2_init_devices(void)
753 omap_init_mcspi(); 646 omap_init_mcspi();
754 } 647 }
755 omap_init_pmu(); 648 omap_init_pmu();
756 omap_hdq_init();
757 omap_init_sti(); 649 omap_init_sti();
758 omap_init_sham(); 650 omap_init_sham();
759 omap_init_aes(); 651 omap_init_aes();
diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c
index 297ebe03f09c..cdd6dda03828 100644
--- a/arch/arm/mach-omap2/hdq1w.c
+++ b/arch/arm/mach-omap2/hdq1w.c
@@ -22,7 +22,13 @@
22 * 02110-1301 USA 22 * 02110-1301 USA
23 */ 23 */
24 24
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/err.h>
28#include <linux/platform_device.h>
29
25#include <plat/omap_hwmod.h> 30#include <plat/omap_hwmod.h>
31#include <plat/omap_device.h>
26#include <plat/hdq1w.h> 32#include <plat/hdq1w.h>
27 33
28#include "common.h" 34#include "common.h"
@@ -70,3 +76,23 @@ int omap_hdq1w_reset(struct omap_hwmod *oh)
70 76
71 return 0; 77 return 0;
72} 78}
79
80static int __init omap_init_hdq(void)
81{
82 int id = -1;
83 struct platform_device *pdev;
84 struct omap_hwmod *oh;
85 char *oh_name = "hdq1w";
86 char *devname = "omap_hdq";
87
88 oh = omap_hwmod_lookup(oh_name);
89 if (!oh)
90 return 0;
91
92 pdev = omap_device_build(devname, id, oh, NULL, 0, NULL, 0, 0);
93 WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
94 devname, oh->name);
95
96 return 0;
97}
98arch_initcall(omap_init_hdq);
diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c
index ef2a6924731a..fb5bc6cf3773 100644
--- a/arch/arm/mach-omap2/msdi.c
+++ b/arch/arm/mach-omap2/msdi.c
@@ -22,11 +22,15 @@
22 */ 22 */
23 23
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/err.h>
25 26
26#include <plat/omap_hwmod.h> 27#include <plat/omap_hwmod.h>
28#include <plat/omap_device.h>
27#include <plat/mmc.h> 29#include <plat/mmc.h>
28 30
29#include "common.h" 31#include "common.h"
32#include "control.h"
33#include "mux.h"
30 34
31/* 35/*
32 * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register 36 * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register
@@ -86,3 +90,72 @@ int omap_msdi_reset(struct omap_hwmod *oh)
86 90
87 return 0; 91 return 0;
88} 92}
93
94#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
95
96static inline void omap242x_mmc_mux(struct omap_mmc_platform_data
97 *mmc_controller)
98{
99 if ((mmc_controller->slots[0].switch_pin > 0) && \
100 (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
101 omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
102 OMAP_PIN_INPUT_PULLUP);
103 if ((mmc_controller->slots[0].gpio_wp > 0) && \
104 (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
105 omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
106 OMAP_PIN_INPUT_PULLUP);
107
108 omap_mux_init_signal("sdmmc_cmd", 0);
109 omap_mux_init_signal("sdmmc_clki", 0);
110 omap_mux_init_signal("sdmmc_clko", 0);
111 omap_mux_init_signal("sdmmc_dat0", 0);
112 omap_mux_init_signal("sdmmc_dat_dir0", 0);
113 omap_mux_init_signal("sdmmc_cmd_dir", 0);
114 if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
115 omap_mux_init_signal("sdmmc_dat1", 0);
116 omap_mux_init_signal("sdmmc_dat2", 0);
117 omap_mux_init_signal("sdmmc_dat3", 0);
118 omap_mux_init_signal("sdmmc_dat_dir1", 0);
119 omap_mux_init_signal("sdmmc_dat_dir2", 0);
120 omap_mux_init_signal("sdmmc_dat_dir3", 0);
121 }
122
123 /*
124 * Use internal loop-back in MMC/SDIO Module Input Clock
125 * selection
126 */
127 if (mmc_controller->slots[0].internal_clock) {
128 u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
129 v |= (1 << 24);
130 omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
131 }
132}
133
134void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
135{
136 struct platform_device *pdev;
137 struct omap_hwmod *oh;
138 int id = 0;
139 char *oh_name = "msdi1";
140 char *dev_name = "mmci-omap";
141
142 if (!mmc_data[0]) {
143 pr_err("%s fails: Incomplete platform data\n", __func__);
144 return;
145 }
146
147 omap242x_mmc_mux(mmc_data[0]);
148
149 oh = omap_hwmod_lookup(oh_name);
150 if (!oh) {
151 pr_err("Could not look up %s\n", oh_name);
152 return;
153 }
154 pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
155 sizeof(struct omap_mmc_platform_data), NULL, 0, 0);
156 if (IS_ERR(pdev))
157 WARN(1, "Can'd build omap_device for %s:%s.\n",
158 dev_name, oh->name);
159}
160
161#endif
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 13670aa84e58..e35a86bf4e1d 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -255,7 +255,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
255 return -ENXIO; 255 return -ENXIO;
256 } 256 }
257 257
258 pwrdm_pre_transition(); 258 pwrdm_pre_transition(NULL);
259 259
260 /* 260 /*
261 * Check MPUSS next state and save interrupt controller if needed. 261 * Check MPUSS next state and save interrupt controller if needed.
@@ -287,7 +287,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
287 wakeup_cpu = smp_processor_id(); 287 wakeup_cpu = smp_processor_id();
288 set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); 288 set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
289 289
290 pwrdm_post_transition(); 290 pwrdm_post_transition(NULL);
291 291
292 return 0; 292 return 0;
293} 293}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 3f21568f1753..6ca8e519968d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -153,6 +153,7 @@
153#include "prm44xx.h" 153#include "prm44xx.h"
154#include "prminst44xx.h" 154#include "prminst44xx.h"
155#include "mux.h" 155#include "mux.h"
156#include "pm.h"
156 157
157/* Maximum microseconds to wait for OMAP module to softreset */ 158/* Maximum microseconds to wait for OMAP module to softreset */
158#define MAX_MODULE_SOFTRESET_WAIT 10000 159#define MAX_MODULE_SOFTRESET_WAIT 10000
@@ -197,6 +198,9 @@ static LIST_HEAD(omap_hwmod_list);
197/* mpu_oh: used to add/remove MPU initiator from sleepdep list */ 198/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
198static struct omap_hwmod *mpu_oh; 199static struct omap_hwmod *mpu_oh;
199 200
201/* io_chain_lock: used to serialize reconfigurations of the I/O chain */
202static DEFINE_SPINLOCK(io_chain_lock);
203
200/* 204/*
201 * linkspace: ptr to a buffer that struct omap_hwmod_link records are 205 * linkspace: ptr to a buffer that struct omap_hwmod_link records are
202 * allocated from - used to reduce the number of small memory 206 * allocated from - used to reduce the number of small memory
@@ -1759,6 +1763,32 @@ static int _reset(struct omap_hwmod *oh)
1759} 1763}
1760 1764
1761/** 1765/**
1766 * _reconfigure_io_chain - clear any I/O chain wakeups and reconfigure chain
1767 *
1768 * Call the appropriate PRM function to clear any logged I/O chain
1769 * wakeups and to reconfigure the chain. This apparently needs to be
1770 * done upon every mux change. Since hwmods can be concurrently
1771 * enabled and idled, hold a spinlock around the I/O chain
1772 * reconfiguration sequence. No return value.
1773 *
1774 * XXX When the PRM code is moved to drivers, this function can be removed,
1775 * as the PRM infrastructure should abstract this.
1776 */
1777static void _reconfigure_io_chain(void)
1778{
1779 unsigned long flags;
1780
1781 spin_lock_irqsave(&io_chain_lock, flags);
1782
1783 if (cpu_is_omap34xx() && omap3_has_io_chain_ctrl())
1784 omap3xxx_prm_reconfigure_io_chain();
1785 else if (cpu_is_omap44xx())
1786 omap44xx_prm_reconfigure_io_chain();
1787
1788 spin_unlock_irqrestore(&io_chain_lock, flags);
1789}
1790
1791/**
1762 * _enable - enable an omap_hwmod 1792 * _enable - enable an omap_hwmod
1763 * @oh: struct omap_hwmod * 1793 * @oh: struct omap_hwmod *
1764 * 1794 *
@@ -1814,8 +1844,10 @@ static int _enable(struct omap_hwmod *oh)
1814 /* Mux pins for device runtime if populated */ 1844 /* Mux pins for device runtime if populated */
1815 if (oh->mux && (!oh->mux->enabled || 1845 if (oh->mux && (!oh->mux->enabled ||
1816 ((oh->_state == _HWMOD_STATE_IDLE) && 1846 ((oh->_state == _HWMOD_STATE_IDLE) &&
1817 oh->mux->pads_dynamic))) 1847 oh->mux->pads_dynamic))) {
1818 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); 1848 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
1849 _reconfigure_io_chain();
1850 }
1819 1851
1820 _add_initiator_dep(oh, mpu_oh); 1852 _add_initiator_dep(oh, mpu_oh);
1821 1853
@@ -1907,8 +1939,10 @@ static int _idle(struct omap_hwmod *oh)
1907 clkdm_hwmod_disable(oh->clkdm, oh); 1939 clkdm_hwmod_disable(oh->clkdm, oh);
1908 1940
1909 /* Mux pins for device idle if populated */ 1941 /* Mux pins for device idle if populated */
1910 if (oh->mux && oh->mux->pads_dynamic) 1942 if (oh->mux && oh->mux->pads_dynamic) {
1911 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); 1943 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
1944 _reconfigure_io_chain();
1945 }
1912 1946
1913 oh->_state = _HWMOD_STATE_IDLE; 1947 oh->_state = _HWMOD_STATE_IDLE;
1914 1948
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index cdb9637aab19..c9e38200216b 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -14,6 +14,8 @@
14 * 14 *
15 * XXX these should be marked initdata for multi-OMAP kernels 15 * XXX these should be marked initdata for multi-OMAP kernels
16 */ 16 */
17#include <linux/power/smartreflex.h>
18
17#include <plat/omap_hwmod.h> 19#include <plat/omap_hwmod.h>
18#include <mach/irqs.h> 20#include <mach/irqs.h>
19#include <plat/cpu.h> 21#include <plat/cpu.h>
@@ -29,8 +31,6 @@
29#include <plat/dmtimer.h> 31#include <plat/dmtimer.h>
30 32
31#include "omap_hwmod_common_data.h" 33#include "omap_hwmod_common_data.h"
32
33#include "smartreflex.h"
34#include "prm-regbits-34xx.h" 34#include "prm-regbits-34xx.h"
35#include "cm-regbits-34xx.h" 35#include "cm-regbits-34xx.h"
36#include "wd_timer.h" 36#include "wd_timer.h"
@@ -1357,7 +1357,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_mpu_irqs[] = {
1357}; 1357};
1358 1358
1359static struct omap_hwmod omap34xx_sr1_hwmod = { 1359static struct omap_hwmod omap34xx_sr1_hwmod = {
1360 .name = "sr1", 1360 .name = "smartreflex_mpu_iva",
1361 .class = &omap34xx_smartreflex_hwmod_class, 1361 .class = &omap34xx_smartreflex_hwmod_class,
1362 .main_clk = "sr1_fck", 1362 .main_clk = "sr1_fck",
1363 .prcm = { 1363 .prcm = {
@@ -1375,7 +1375,7 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
1375}; 1375};
1376 1376
1377static struct omap_hwmod omap36xx_sr1_hwmod = { 1377static struct omap_hwmod omap36xx_sr1_hwmod = {
1378 .name = "sr1", 1378 .name = "smartreflex_mpu_iva",
1379 .class = &omap36xx_smartreflex_hwmod_class, 1379 .class = &omap36xx_smartreflex_hwmod_class,
1380 .main_clk = "sr1_fck", 1380 .main_clk = "sr1_fck",
1381 .prcm = { 1381 .prcm = {
@@ -1402,7 +1402,7 @@ static struct omap_hwmod_irq_info omap3_smartreflex_core_irqs[] = {
1402}; 1402};
1403 1403
1404static struct omap_hwmod omap34xx_sr2_hwmod = { 1404static struct omap_hwmod omap34xx_sr2_hwmod = {
1405 .name = "sr2", 1405 .name = "smartreflex_core",
1406 .class = &omap34xx_smartreflex_hwmod_class, 1406 .class = &omap34xx_smartreflex_hwmod_class,
1407 .main_clk = "sr2_fck", 1407 .main_clk = "sr2_fck",
1408 .prcm = { 1408 .prcm = {
@@ -1420,7 +1420,7 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
1420}; 1420};
1421 1421
1422static struct omap_hwmod omap36xx_sr2_hwmod = { 1422static struct omap_hwmod omap36xx_sr2_hwmod = {
1423 .name = "sr2", 1423 .name = "smartreflex_core",
1424 .class = &omap36xx_smartreflex_hwmod_class, 1424 .class = &omap36xx_smartreflex_hwmod_class,
1425 .main_clk = "sr2_fck", 1425 .main_clk = "sr2_fck",
1426 .prcm = { 1426 .prcm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 5c2ce7e77838..242aee498ceb 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/power/smartreflex.h>
22 23
23#include <plat/omap_hwmod.h> 24#include <plat/omap_hwmod.h>
24#include <plat/cpu.h> 25#include <plat/cpu.h>
@@ -32,8 +33,6 @@
32#include <plat/common.h> 33#include <plat/common.h>
33 34
34#include "omap_hwmod_common_data.h" 35#include "omap_hwmod_common_data.h"
35
36#include "smartreflex.h"
37#include "cm1_44xx.h" 36#include "cm1_44xx.h"
38#include "cm2_44xx.h" 37#include "cm2_44xx.h"
39#include "prm44xx.h" 38#include "prm44xx.h"
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index ab04d3bba2e7..686137d164da 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -101,7 +101,7 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
101static inline void enable_omap3630_toggle_l2_on_restore(void) { } 101static inline void enable_omap3630_toggle_l2_on_restore(void) { }
102#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ 102#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
103 103
104#ifdef CONFIG_OMAP_SMARTREFLEX 104#ifdef CONFIG_POWER_AVS_OMAP
105extern int omap_devinit_smartreflex(void); 105extern int omap_devinit_smartreflex(void);
106extern void omap_enable_smartreflex_on_init(void); 106extern void omap_enable_smartreflex_on_init(void);
107#else 107#else
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 9b463c987508..e4fc88c65dbd 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -70,34 +70,6 @@ void (*omap3_do_wfi_sram)(void);
70 70
71static struct powerdomain *mpu_pwrdm, *neon_pwrdm; 71static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
72static struct powerdomain *core_pwrdm, *per_pwrdm; 72static struct powerdomain *core_pwrdm, *per_pwrdm;
73static struct powerdomain *cam_pwrdm;
74
75static void omap3_enable_io_chain(void)
76{
77 int timeout = 0;
78
79 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
80 PM_WKEN);
81 /* Do a readback to assure write has been done */
82 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
83
84 while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
85 OMAP3430_ST_IO_CHAIN_MASK)) {
86 timeout++;
87 if (timeout > 1000) {
88 pr_err("Wake up daisy chain activation failed.\n");
89 return;
90 }
91 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
92 WKUP_MOD, PM_WKEN);
93 }
94}
95
96static void omap3_disable_io_chain(void)
97{
98 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
99 PM_WKEN);
100}
101 73
102static void omap3_core_save_context(void) 74static void omap3_core_save_context(void)
103{ 75{
@@ -299,24 +271,22 @@ void omap_sram_idle(void)
299 /* Enable IO-PAD and IO-CHAIN wakeups */ 271 /* Enable IO-PAD and IO-CHAIN wakeups */
300 per_next_state = pwrdm_read_next_pwrst(per_pwrdm); 272 per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
301 core_next_state = pwrdm_read_next_pwrst(core_pwrdm); 273 core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
302 if (omap3_has_io_wakeup() &&
303 (per_next_state < PWRDM_POWER_ON ||
304 core_next_state < PWRDM_POWER_ON)) {
305 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
306 if (omap3_has_io_chain_ctrl())
307 omap3_enable_io_chain();
308 }
309 274
310 pwrdm_pre_transition(); 275 if (mpu_next_state < PWRDM_POWER_ON) {
276 pwrdm_pre_transition(mpu_pwrdm);
277 pwrdm_pre_transition(neon_pwrdm);
278 }
311 279
312 /* PER */ 280 /* PER */
313 if (per_next_state < PWRDM_POWER_ON) { 281 if (per_next_state < PWRDM_POWER_ON) {
282 pwrdm_pre_transition(per_pwrdm);
314 per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; 283 per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
315 omap2_gpio_prepare_for_idle(per_going_off); 284 omap2_gpio_prepare_for_idle(per_going_off);
316 } 285 }
317 286
318 /* CORE */ 287 /* CORE */
319 if (core_next_state < PWRDM_POWER_ON) { 288 if (core_next_state < PWRDM_POWER_ON) {
289 pwrdm_pre_transition(core_pwrdm);
320 if (core_next_state == PWRDM_POWER_OFF) { 290 if (core_next_state == PWRDM_POWER_OFF) {
321 omap3_core_save_context(); 291 omap3_core_save_context();
322 omap3_cm_save_context(); 292 omap3_cm_save_context();
@@ -369,26 +339,20 @@ void omap_sram_idle(void)
369 omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, 339 omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
370 OMAP3430_GR_MOD, 340 OMAP3430_GR_MOD,
371 OMAP3_PRM_VOLTCTRL_OFFSET); 341 OMAP3_PRM_VOLTCTRL_OFFSET);
342 pwrdm_post_transition(core_pwrdm);
372 } 343 }
373 omap3_intc_resume_idle(); 344 omap3_intc_resume_idle();
374 345
375 pwrdm_post_transition();
376
377 /* PER */ 346 /* PER */
378 if (per_next_state < PWRDM_POWER_ON) 347 if (per_next_state < PWRDM_POWER_ON) {
379 omap2_gpio_resume_after_idle(); 348 omap2_gpio_resume_after_idle();
380 349 pwrdm_post_transition(per_pwrdm);
381 /* Disable IO-PAD and IO-CHAIN wakeup */
382 if (omap3_has_io_wakeup() &&
383 (per_next_state < PWRDM_POWER_ON ||
384 core_next_state < PWRDM_POWER_ON)) {
385 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
386 PM_WKEN);
387 if (omap3_has_io_chain_ctrl())
388 omap3_disable_io_chain();
389 } 350 }
390 351
391 clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); 352 if (mpu_next_state < PWRDM_POWER_ON) {
353 pwrdm_post_transition(mpu_pwrdm);
354 pwrdm_post_transition(neon_pwrdm);
355 }
392} 356}
393 357
394static void omap3_pm_idle(void) 358static void omap3_pm_idle(void)
@@ -754,7 +718,6 @@ int __init omap3_pm_init(void)
754 neon_pwrdm = pwrdm_lookup("neon_pwrdm"); 718 neon_pwrdm = pwrdm_lookup("neon_pwrdm");
755 per_pwrdm = pwrdm_lookup("per_pwrdm"); 719 per_pwrdm = pwrdm_lookup("per_pwrdm");
756 core_pwrdm = pwrdm_lookup("core_pwrdm"); 720 core_pwrdm = pwrdm_lookup("core_pwrdm");
757 cam_pwrdm = pwrdm_lookup("cam_pwrdm");
758 721
759 neon_clkdm = clkdm_lookup("neon_clkdm"); 722 neon_clkdm = clkdm_lookup("neon_clkdm");
760 mpu_clkdm = clkdm_lookup("mpu_clkdm"); 723 mpu_clkdm = clkdm_lookup("mpu_clkdm");
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 2f963f702a05..69b36e185e9b 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -985,15 +985,23 @@ int pwrdm_state_switch(struct powerdomain *pwrdm)
985 return ret; 985 return ret;
986} 986}
987 987
988int pwrdm_pre_transition(void) 988int pwrdm_pre_transition(struct powerdomain *pwrdm)
989{ 989{
990 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); 990 if (pwrdm)
991 _pwrdm_pre_transition_cb(pwrdm, NULL);
992 else
993 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
994
991 return 0; 995 return 0;
992} 996}
993 997
994int pwrdm_post_transition(void) 998int pwrdm_post_transition(struct powerdomain *pwrdm)
995{ 999{
996 pwrdm_for_each(_pwrdm_post_transition_cb, NULL); 1000 if (pwrdm)
1001 _pwrdm_post_transition_cb(pwrdm, NULL);
1002 else
1003 pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
1004
997 return 0; 1005 return 0;
998} 1006}
999 1007
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index a8a95184243d..baee90608d11 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -230,8 +230,8 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
230int pwrdm_wait_transition(struct powerdomain *pwrdm); 230int pwrdm_wait_transition(struct powerdomain *pwrdm);
231 231
232int pwrdm_state_switch(struct powerdomain *pwrdm); 232int pwrdm_state_switch(struct powerdomain *pwrdm);
233int pwrdm_pre_transition(void); 233int pwrdm_pre_transition(struct powerdomain *pwrdm);
234int pwrdm_post_transition(void); 234int pwrdm_post_transition(struct powerdomain *pwrdm);
235int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm); 235int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
236int pwrdm_get_context_loss_count(struct powerdomain *pwrdm); 236int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
237bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); 237bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index d5ae4e234bbc..e5f0503a68b0 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -410,6 +410,14 @@
410 */ 410 */
411#define MAX_MODULE_HARDRESET_WAIT 10000 411#define MAX_MODULE_HARDRESET_WAIT 10000
412 412
413/*
414 * Maximum time(us) it takes to output the signal WUCLKOUT of the last
415 * pad of the I/O ring after asserting WUCLKIN high. Tero measured
416 * the actual time at 7 to 8 microseconds on OMAP3 and 2 to 4
417 * microseconds on OMAP4, so this timeout may be too high.
418 */
419#define MAX_IOPAD_LATCH_TIME 100
420
413# ifndef __ASSEMBLER__ 421# ifndef __ASSEMBLER__
414extern void __iomem *prm_base; 422extern void __iomem *prm_base;
415extern void __iomem *cm_base; 423extern void __iomem *cm_base;
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 21cb74003a56..a0309dea6794 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -302,11 +302,59 @@ void omap3xxx_prm_restore_irqen(u32 *saved_mask)
302 OMAP3_PRM_IRQENABLE_MPU_OFFSET); 302 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
303} 303}
304 304
305/**
306 * omap3xxx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
307 *
308 * Clear any previously-latched I/O wakeup events and ensure that the
309 * I/O wakeup gates are aligned with the current mux settings. Works
310 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
311 * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
312 * return value.
313 */
314void omap3xxx_prm_reconfigure_io_chain(void)
315{
316 int i = 0;
317
318 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
319 PM_WKEN);
320
321 omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
322 OMAP3430_ST_IO_CHAIN_MASK,
323 MAX_IOPAD_LATCH_TIME, i);
324 if (i == MAX_IOPAD_LATCH_TIME)
325 pr_warn("PRM: I/O chain clock line assertion timed out\n");
326
327 omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
328 PM_WKEN);
329
330 omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
331 PM_WKST);
332
333 omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
334}
335
336/**
337 * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
338 *
339 * Activates the I/O wakeup event latches and allows events logged by
340 * those latches to signal a wakeup event to the PRCM. For I/O
341 * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
342 * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
343 * No return value.
344 */
345static void __init omap3xxx_prm_enable_io_wakeup(void)
346{
347 if (omap3_has_io_wakeup())
348 omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
349 PM_WKEN);
350}
351
305static int __init omap3xxx_prcm_init(void) 352static int __init omap3xxx_prcm_init(void)
306{ 353{
307 int ret = 0; 354 int ret = 0;
308 355
309 if (cpu_is_omap34xx()) { 356 if (cpu_is_omap34xx()) {
357 omap3xxx_prm_enable_io_wakeup();
310 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); 358 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
311 if (!ret) 359 if (!ret)
312 irq_set_status_flags(omap_prcm_event_to_irq("io"), 360 irq_set_status_flags(omap_prcm_event_to_irq("io"),
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index f7bb57fff416..c19d249b4816 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -253,12 +253,15 @@ extern u32 omap3_prm_vcvp_read(u8 offset);
253extern void omap3_prm_vcvp_write(u32 val, u8 offset); 253extern void omap3_prm_vcvp_write(u32 val, u8 offset);
254extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 254extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
255 255
256extern void omap3xxx_prm_reconfigure_io_chain(void);
257
256/* PRM interrupt-related functions */ 258/* PRM interrupt-related functions */
257extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); 259extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
258extern void omap3xxx_prm_ocp_barrier(void); 260extern void omap3xxx_prm_ocp_barrier(void);
259extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); 261extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
260extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); 262extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
261#endif 263
264#endif /* __ASSEMBLER */
262 265
263/* 266/*
264 * Bits common to specific registers 267 * Bits common to specific registers
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index f106d21ff581..bb727c2d9337 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -233,10 +233,71 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask)
233 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); 233 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
234} 234}
235 235
236/**
237 * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
238 *
239 * Clear any previously-latched I/O wakeup events and ensure that the
240 * I/O wakeup gates are aligned with the current mux settings. Works
241 * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
242 * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
243 * No return value. XXX Are the final two steps necessary?
244 */
245void omap44xx_prm_reconfigure_io_chain(void)
246{
247 int i = 0;
248
249 /* Trigger WUCLKIN enable */
250 omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
251 OMAP4430_WUCLK_CTRL_MASK,
252 OMAP4430_PRM_DEVICE_INST,
253 OMAP4_PRM_IO_PMCTRL_OFFSET);
254 omap_test_timeout(
255 (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
256 OMAP4_PRM_IO_PMCTRL_OFFSET) &
257 OMAP4430_WUCLK_STATUS_MASK) >>
258 OMAP4430_WUCLK_STATUS_SHIFT) == 1),
259 MAX_IOPAD_LATCH_TIME, i);
260 if (i == MAX_IOPAD_LATCH_TIME)
261 pr_warn("PRM: I/O chain clock line assertion timed out\n");
262
263 /* Trigger WUCLKIN disable */
264 omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
265 OMAP4430_PRM_DEVICE_INST,
266 OMAP4_PRM_IO_PMCTRL_OFFSET);
267 omap_test_timeout(
268 (((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
269 OMAP4_PRM_IO_PMCTRL_OFFSET) &
270 OMAP4430_WUCLK_STATUS_MASK) >>
271 OMAP4430_WUCLK_STATUS_SHIFT) == 0),
272 MAX_IOPAD_LATCH_TIME, i);
273 if (i == MAX_IOPAD_LATCH_TIME)
274 pr_warn("PRM: I/O chain clock line deassertion timed out\n");
275
276 return;
277}
278
279/**
280 * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
281 *
282 * Activates the I/O wakeup event latches and allows events logged by
283 * those latches to signal a wakeup event to the PRCM. For I/O wakeups
284 * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
285 * omap44xx_prm_reconfigure_io_chain() must be called. No return value.
286 */
287static void __init omap44xx_prm_enable_io_wakeup(void)
288{
289 omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
290 OMAP4430_GLOBAL_WUEN_MASK,
291 OMAP4430_PRM_DEVICE_INST,
292 OMAP4_PRM_IO_PMCTRL_OFFSET);
293}
294
236static int __init omap4xxx_prcm_init(void) 295static int __init omap4xxx_prcm_init(void)
237{ 296{
238 if (cpu_is_omap44xx()) 297 if (cpu_is_omap44xx()) {
298 omap44xx_prm_enable_io_wakeup();
239 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); 299 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
300 }
240 return 0; 301 return 0;
241} 302}
242subsys_initcall(omap4xxx_prcm_init); 303subsys_initcall(omap4xxx_prcm_init);
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 7978092946db..ee72ae6bd8c9 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -763,6 +763,8 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
763extern void omap4_prm_vcvp_write(u32 val, u8 offset); 763extern void omap4_prm_vcvp_write(u32 val, u8 offset);
764extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 764extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
765 765
766extern void omap44xx_prm_reconfigure_io_chain(void);
767
766/* PRM interrupt-related functions */ 768/* PRM interrupt-related functions */
767extern void omap44xx_prm_read_pending_irqs(unsigned long *events); 769extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
768extern void omap44xx_prm_ocp_barrier(void); 770extern void omap44xx_prm_ocp_barrier(void);
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index 955566eefac4..1da8f03c479e 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -11,36 +11,37 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include "smartreflex.h" 14#include <linux/power/smartreflex.h>
15#include "voltage.h"
15 16
16static int sr_class3_enable(struct voltagedomain *voltdm) 17static int sr_class3_enable(struct omap_sr *sr)
17{ 18{
18 unsigned long volt = voltdm_get_voltage(voltdm); 19 unsigned long volt = voltdm_get_voltage(sr->voltdm);
19 20
20 if (!volt) { 21 if (!volt) {
21 pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n", 22 pr_warning("%s: Curr voltage unknown. Cannot enable %s\n",
22 __func__, voltdm->name); 23 __func__, sr->name);
23 return -ENODATA; 24 return -ENODATA;
24 } 25 }
25 26
26 omap_vp_enable(voltdm); 27 omap_vp_enable(sr->voltdm);
27 return sr_enable(voltdm, volt); 28 return sr_enable(sr->voltdm, volt);
28} 29}
29 30
30static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset) 31static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
31{ 32{
32 sr_disable_errgen(voltdm); 33 sr_disable_errgen(sr->voltdm);
33 omap_vp_disable(voltdm); 34 omap_vp_disable(sr->voltdm);
34 sr_disable(voltdm); 35 sr_disable(sr->voltdm);
35 if (is_volt_reset) 36 if (is_volt_reset)
36 voltdm_reset(voltdm); 37 voltdm_reset(sr->voltdm);
37 38
38 return 0; 39 return 0;
39} 40}
40 41
41static int sr_class3_configure(struct voltagedomain *voltdm) 42static int sr_class3_configure(struct omap_sr *sr)
42{ 43{
43 return sr_configure_errgen(voltdm); 44 return sr_configure_errgen(sr->voltdm);
44} 45}
45 46
46/* SR class3 structure */ 47/* SR class3 structure */
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index a503e1e8358c..e107e3915a8a 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -17,6 +17,7 @@
17 * it under the terms of the GNU General Public License version 2 as 17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation. 18 * published by the Free Software Foundation.
19 */ 19 */
20#include <linux/power/smartreflex.h>
20 21
21#include <linux/err.h> 22#include <linux/err.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
@@ -24,7 +25,6 @@
24 25
25#include <plat/omap_device.h> 26#include <plat/omap_device.h>
26 27
27#include "smartreflex.h"
28#include "voltage.h" 28#include "voltage.h"
29#include "control.h" 29#include "control.h"
30#include "pm.h" 30#include "pm.h"
@@ -36,7 +36,10 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
36 struct omap_sr_data *sr_data) 36 struct omap_sr_data *sr_data)
37{ 37{
38 struct omap_sr_nvalue_table *nvalue_table; 38 struct omap_sr_nvalue_table *nvalue_table;
39 int i, count = 0; 39 int i, j, count = 0;
40
41 sr_data->nvalue_count = 0;
42 sr_data->nvalue_table = NULL;
40 43
41 while (volt_data[count].volt_nominal) 44 while (volt_data[count].volt_nominal)
42 count++; 45 count++;
@@ -44,8 +47,14 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
44 nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, 47 nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,
45 GFP_KERNEL); 48 GFP_KERNEL);
46 49
47 for (i = 0; i < count; i++) { 50 if (!nvalue_table) {
51 pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n");
52 return;
53 }
54
55 for (i = 0, j = 0; i < count; i++) {
48 u32 v; 56 u32 v;
57
49 /* 58 /*
50 * In OMAP4 the efuse registers are 24 bit aligned. 59 * In OMAP4 the efuse registers are 24 bit aligned.
51 * A __raw_readl will fail for non-32 bit aligned address 60 * A __raw_readl will fail for non-32 bit aligned address
@@ -58,15 +67,30 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
58 omap_ctrl_readb(offset + 1) << 8 | 67 omap_ctrl_readb(offset + 1) << 8 |
59 omap_ctrl_readb(offset + 2) << 16; 68 omap_ctrl_readb(offset + 2) << 16;
60 } else { 69 } else {
61 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs); 70 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs);
62 } 71 }
63 72
64 nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs; 73 /*
65 nvalue_table[i].nvalue = v; 74 * Many OMAP SoCs don't have the eFuse values set.
75 * For example, pretty much all OMAP3xxx before
76 * ES3.something.
77 *
78 * XXX There needs to be some way for board files or
79 * userspace to add these in.
80 */
81 if (v == 0)
82 continue;
83
84 nvalue_table[j].nvalue = v;
85 nvalue_table[j].efuse_offs = volt_data[i].sr_efuse_offs;
86 nvalue_table[j].errminlimit = volt_data[i].sr_errminlimit;
87 nvalue_table[j].volt_nominal = volt_data[i].volt_nominal;
88
89 j++;
66 } 90 }
67 91
68 sr_data->nvalue_table = nvalue_table; 92 sr_data->nvalue_table = nvalue_table;
69 sr_data->nvalue_count = count; 93 sr_data->nvalue_count = j;
70} 94}
71 95
72static int __init sr_dev_init(struct omap_hwmod *oh, void *user) 96static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
@@ -93,6 +117,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
93 goto exit; 117 goto exit;
94 } 118 }
95 119
120 sr_data->name = oh->name;
96 sr_data->ip_type = oh->class->rev; 121 sr_data->ip_type = oh->class->rev;
97 sr_data->senn_mod = 0x1; 122 sr_data->senn_mod = 0x1;
98 sr_data->senp_mod = 0x1; 123 sr_data->senp_mod = 0x1;
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index a7c43c1042be..0ac2caf15941 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -16,6 +16,8 @@
16 16
17#include <linux/err.h> 17#include <linux/err.h>
18 18
19#include <plat/voltage.h>
20
19#include "vc.h" 21#include "vc.h"
20#include "vp.h" 22#include "vp.h"
21 23
@@ -91,25 +93,6 @@ struct voltagedomain {
91}; 93};
92 94
93/** 95/**
94 * struct omap_volt_data - Omap voltage specific data.
95 * @voltage_nominal: The possible voltage value in uV
96 * @sr_efuse_offs: The offset of the efuse register(from system
97 * control module base address) from where to read
98 * the n-target value for the smartreflex module.
99 * @sr_errminlimit: Error min limit value for smartreflex. This value
100 * differs at differnet opp and thus is linked
101 * with voltage.
102 * @vp_errorgain: Error gain value for the voltage processor. This
103 * field also differs according to the voltage/opp.
104 */
105struct omap_volt_data {
106 u32 volt_nominal;
107 u32 sr_efuse_offs;
108 u8 sr_errminlimit;
109 u8 vp_errgain;
110};
111
112/**
113 * struct omap_voltdm_pmic - PMIC specific data required by voltage driver. 96 * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
114 * @slew_rate: PMIC slew rate (in uv/us) 97 * @slew_rate: PMIC slew rate (in uv/us)
115 * @step_size: PMIC voltage step size (in uv) 98 * @step_size: PMIC voltage step size (in uv)
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index e81290c27c65..63b064b5c1d5 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MXC_ULPI) += ulpi.o
16obj-$(CONFIG_MXC_USE_EPIT) += epit.o 16obj-$(CONFIG_MXC_USE_EPIT) += epit.o
17obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o 17obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
18obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o 18obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
19obj-$(CONFIG_CPU_IDLE) += cpuidle.o
19ifdef CONFIG_SND_IMX_SOC 20ifdef CONFIG_SND_IMX_SOC
20obj-y += ssi-fiq.o 21obj-y += ssi-fiq.o
21obj-y += ssi-fiq-ksym.o 22obj-y += ssi-fiq-ksym.o
diff --git a/arch/arm/plat-mxc/cpuidle.c b/arch/arm/plat-mxc/cpuidle.c
new file mode 100644
index 000000000000..d4cb511a44a8
--- /dev/null
+++ b/arch/arm/plat-mxc/cpuidle.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/cpuidle.h>
14#include <linux/err.h>
15#include <linux/hrtimer.h>
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <linux/slab.h>
19
20static struct cpuidle_device __percpu * imx_cpuidle_devices;
21
22static void __init imx_cpuidle_devices_uninit(void)
23{
24 int cpu_id;
25 struct cpuidle_device *dev;
26
27 for_each_possible_cpu(cpu_id) {
28 dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id);
29 cpuidle_unregister_device(dev);
30 }
31
32 free_percpu(imx_cpuidle_devices);
33}
34
35int __init imx_cpuidle_init(struct cpuidle_driver *drv)
36{
37 struct cpuidle_device *dev;
38 int cpu_id, ret;
39
40 if (drv->state_count > CPUIDLE_STATE_MAX) {
41 pr_err("%s: state_count exceeds maximum\n", __func__);
42 return -EINVAL;
43 }
44
45 ret = cpuidle_register_driver(drv);
46 if (ret) {
47 pr_err("%s: Failed to register cpuidle driver with error: %d\n",
48 __func__, ret);
49 return ret;
50 }
51
52 imx_cpuidle_devices = alloc_percpu(struct cpuidle_device);
53 if (imx_cpuidle_devices == NULL) {
54 ret = -ENOMEM;
55 goto unregister_drv;
56 }
57
58 /* initialize state data for each cpuidle_device */
59 for_each_possible_cpu(cpu_id) {
60 dev = per_cpu_ptr(imx_cpuidle_devices, cpu_id);
61 dev->cpu = cpu_id;
62 dev->state_count = drv->state_count;
63
64 ret = cpuidle_register_device(dev);
65 if (ret) {
66 pr_err("%s: Failed to register cpu %u, error: %d\n",
67 __func__, cpu_id, ret);
68 goto uninit;
69 }
70 }
71
72 return 0;
73
74uninit:
75 imx_cpuidle_devices_uninit();
76
77unregister_drv:
78 cpuidle_unregister_driver(drv);
79 return ret;
80}
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 7cfcc44537f0..7128e9710417 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -54,6 +54,7 @@ extern void imx50_soc_init(void);
54extern void imx51_soc_init(void); 54extern void imx51_soc_init(void);
55extern void imx53_soc_init(void); 55extern void imx53_soc_init(void);
56extern void imx51_init_late(void); 56extern void imx51_init_late(void);
57extern void imx53_init_late(void);
57extern void epit_timer_init(void __iomem *base, int irq); 58extern void epit_timer_init(void __iomem *base, int irq);
58extern void mxc_timer_init(void __iomem *, int); 59extern void mxc_timer_init(void __iomem *, int);
59extern int mx1_clocks_init(unsigned long fref); 60extern int mx1_clocks_init(unsigned long fref);
@@ -96,7 +97,6 @@ enum mx3_cpu_pwr_mode {
96}; 97};
97 98
98extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); 99extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
99extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
100extern void imx_print_silicon_rev(const char *cpu, int srev); 100extern void imx_print_silicon_rev(const char *cpu, int srev);
101 101
102void avic_handle_irq(struct pt_regs *); 102void avic_handle_irq(struct pt_regs *);
@@ -147,8 +147,12 @@ extern void imx6q_clock_map_io(void);
147 147
148#ifdef CONFIG_PM 148#ifdef CONFIG_PM
149extern void imx6q_pm_init(void); 149extern void imx6q_pm_init(void);
150extern void imx51_pm_init(void);
151extern void imx53_pm_init(void);
150#else 152#else
151static inline void imx6q_pm_init(void) {} 153static inline void imx6q_pm_init(void) {}
154static inline void imx51_pm_init(void) {}
155static inline void imx53_pm_init(void) {}
152#endif 156#endif
153 157
154#ifdef CONFIG_NEON 158#ifdef CONFIG_NEON
diff --git a/arch/arm/plat-mxc/include/mach/cpuidle.h b/arch/arm/plat-mxc/include/mach/cpuidle.h
new file mode 100644
index 000000000000..bc932d1af372
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/cpuidle.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/cpuidle.h>
14
15#ifdef CONFIG_CPU_IDLE
16extern int imx_cpuidle_init(struct cpuidle_driver *drv);
17#else
18static inline int imx_cpuidle_init(struct cpuidle_driver *drv)
19{
20 return -ENODEV;
21}
22#endif
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 1d432a75e409..ebf10654bb42 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -50,7 +50,7 @@
50 * IO 0x00200000+0x100000 -> 0xf4000000+0x100000 50 * IO 0x00200000+0x100000 -> 0xf4000000+0x100000
51 * mx21: 51 * mx21:
52 * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000 52 * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
53 * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000 53 * SAHB1 0x80000000+0x100000 -> 0xf5000000+0x100000
54 * X_MEMC 0xdf000000+0x004000 -> 0xf5f00000+0x004000 54 * X_MEMC 0xdf000000+0x004000 -> 0xf5f00000+0x004000
55 * mx25: 55 * mx25:
56 * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000 56 * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
@@ -58,47 +58,50 @@
58 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 58 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
59 * mx27: 59 * mx27:
60 * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000 60 * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
61 * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000 61 * SAHB1 0x80000000+0x100000 -> 0xf5000000+0x100000
62 * X_MEMC 0xd8000000+0x100000 -> 0xf5c00000+0x100000 62 * X_MEMC 0xd8000000+0x100000 -> 0xf5c00000+0x100000
63 * mx31: 63 * mx31:
64 * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000 64 * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
65 * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000 65 * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
66 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 66 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
67 * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000 67 * X_MEMC 0xb8000000+0x010000 -> 0xf5c00000+0x010000
68 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 68 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
69 * mx35: 69 * mx35:
70 * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000 70 * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
71 * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000 71 * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
72 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000 72 * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
73 * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000 73 * X_MEMC 0xb8000000+0x010000 -> 0xf5c00000+0x010000
74 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 74 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
75 * mx50: 75 * mx50:
76 * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 76 * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000
77 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
78 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000 77 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000
78 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
79 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000 79 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000
80 * mx51: 80 * mx51:
81 * TZIC 0xe0000000+0x004000 -> 0xf5000000+0x004000 81 * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000
82 * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000 82 * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000
83 * DEBUG 0x60000000+0x100000 -> 0xf5000000+0x100000
83 * SPBA0 0x70000000+0x100000 -> 0xf5400000+0x100000 84 * SPBA0 0x70000000+0x100000 -> 0xf5400000+0x100000
84 * AIPS1 0x73f00000+0x100000 -> 0xf5700000+0x100000 85 * AIPS1 0x73f00000+0x100000 -> 0xf5700000+0x100000
85 * AIPS2 0x83f00000+0x100000 -> 0xf4300000+0x100000 86 * AIPS2 0x83f00000+0x100000 -> 0xf5300000+0x100000
86 * mx53: 87 * mx53:
87 * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000 88 * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000
89 * DEBUG 0x40000000+0x100000 -> 0xf5000000+0x100000
88 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000 90 * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
89 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000 91 * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000
90 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000 92 * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000
91 * mx6q: 93 * mx6q:
92 * SCU 0x00a00000+0x001000 -> 0xf4000000+0x001000 94 * SCU 0x00a00000+0x004000 -> 0xf4000000+0x004000
93 * CCM 0x020c4000+0x004000 -> 0xf42c4000+0x004000 95 * CCM 0x020c4000+0x004000 -> 0xf42c4000+0x004000
94 * ANATOP 0x020c8000+0x001000 -> 0xf42c8000+0x001000 96 * ANATOP 0x020c8000+0x004000 -> 0xf42c8000+0x004000
95 * UART4 0x021f0000+0x004000 -> 0xf42f0000+0x004000 97 * UART4 0x021f0000+0x004000 -> 0xf42f0000+0x004000
96 */ 98 */
97#define IMX_IO_P2V(x) ( \ 99#define IMX_IO_P2V(x) ( \
98 0xf4000000 + \ 100 (((x) & 0x80000000) >> 7) | \
101 (0xf4000000 + \
99 (((x) & 0x50000000) >> 6) + \ 102 (((x) & 0x50000000) >> 6) + \
100 (((x) & 0x0b000000) >> 4) + \ 103 (((x) & 0x0b000000) >> 4) + \
101 (((x) & 0x000fffff))) 104 (((x) & 0x000fffff))))
102 105
103#define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x)) 106#define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x))
104 107
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index c60a7e416385..c2193178210b 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -202,6 +202,10 @@ void __init tzic_init_irq(void __iomem *irqbase)
202 * tzic_enable_wake() - enable wakeup interrupt 202 * tzic_enable_wake() - enable wakeup interrupt
203 * 203 *
204 * @return 0 if successful; non-zero otherwise 204 * @return 0 if successful; non-zero otherwise
205 *
206 * This function provides an interrupt synchronization point that is required
207 * by tzic enabled platforms before entering imx specific low power modes (ie,
208 * those low power modes beyond the WAIT_CLOCKED basic ARM WFI only mode).
205 */ 209 */
206int tzic_enable_wake(void) 210int tzic_enable_wake(void)
207{ 211{
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index dcfb506a592e..dd36eba9506c 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -45,31 +45,30 @@ config OMAP_DEBUG_LEDS
45 depends on OMAP_DEBUG_DEVICES 45 depends on OMAP_DEBUG_DEVICES
46 default y if LEDS_CLASS 46 default y if LEDS_CLASS
47 47
48config OMAP_SMARTREFLEX 48config POWER_AVS_OMAP
49 bool "SmartReflex support" 49 bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
50 depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM 50 depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
51 help 51 help
52 Say Y if you want to enable SmartReflex. 52 Say Y to enable AVS(Adaptive Voltage Scaling)
53 53 support on OMAP containing the version 1 or
54 SmartReflex can perform continuous dynamic voltage 54 version 2 of the SmartReflex IP.
55 scaling around the nominal operating point voltage 55 V1 is the 65nm version used in OMAP3430.
56 according to silicon characteristics and operating 56 V2 is the update for the 45nm version of the IP used in OMAP3630
57 conditions. Enabling SmartReflex reduces power 57 and OMAP4430
58 consumption.
59 58
60 Please note, that by default SmartReflex is only 59 Please note, that by default SmartReflex is only
61 initialized. To enable the automatic voltage 60 initialized and not enabled. To enable the automatic voltage
62 compensation for vdd mpu and vdd core from user space, 61 compensation for vdd mpu and vdd core from user space,
63 user must write 1 to 62 user must write 1 to
64 /debug/voltage/vdd_<X>/smartreflex/autocomp, 63 /debug/smartreflex/sr_<X>/autocomp,
65 where X is mpu or core for OMAP3. 64 where X is mpu_iva or core for OMAP3.
66 Optionally autocompensation can be enabled in the kernel 65 Optionally autocompensation can be enabled in the kernel
67 by default during system init via the enable_on_init flag 66 by default during system init via the enable_on_init flag
68 which an be passed as platform data to the smartreflex driver. 67 which an be passed as platform data to the smartreflex driver.
69 68
70config OMAP_SMARTREFLEX_CLASS3 69config POWER_AVS_OMAP_CLASS3
71 bool "Class 3 mode of Smartreflex Implementation" 70 bool "Class 3 mode of Smartreflex Implementation"
72 depends on OMAP_SMARTREFLEX && TWL4030_CORE 71 depends on POWER_AVS_OMAP && TWL4030_CORE
73 help 72 help
74 Say Y to enable Class 3 implementation of Smartreflex 73 Say Y to enable Class 3 implementation of Smartreflex
75 74
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 0a6a482ec014..5be4d5def427 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -11,10 +11,29 @@
11#ifndef __ARCH_ARM_OMAP_VOLTAGE_H 11#ifndef __ARCH_ARM_OMAP_VOLTAGE_H
12#define __ARCH_ARM_OMAP_VOLTAGE_H 12#define __ARCH_ARM_OMAP_VOLTAGE_H
13 13
14/**
15 * struct omap_volt_data - Omap voltage specific data.
16 * @voltage_nominal: The possible voltage value in uV
17 * @sr_efuse_offs: The offset of the efuse register(from system
18 * control module base address) from where to read
19 * the n-target value for the smartreflex module.
20 * @sr_errminlimit: Error min limit value for smartreflex. This value
21 * differs at differnet opp and thus is linked
22 * with voltage.
23 * @vp_errorgain: Error gain value for the voltage processor. This
24 * field also differs according to the voltage/opp.
25 */
26struct omap_volt_data {
27 u32 volt_nominal;
28 u32 sr_efuse_offs;
29 u8 sr_errminlimit;
30 u8 vp_errgain;
31};
14struct voltagedomain; 32struct voltagedomain;
15 33
16struct voltagedomain *voltdm_lookup(const char *name); 34struct voltagedomain *voltdm_lookup(const char *name);
17int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt); 35int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
18unsigned long voltdm_get_voltage(struct voltagedomain *voltdm); 36unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
19 37struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
38 unsigned long volt);
20#endif 39#endif
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index e3a3b4956f08..70b4a979a6ff 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -310,3 +310,5 @@ config AB8500_BATTERY_THERM_ON_BATCTRL
310 Say Y to enable battery temperature measurements using 310 Say Y to enable battery temperature measurements using
311 thermistor connected on BATCTRL ADC. 311 thermistor connected on BATCTRL ADC.
312endif # POWER_SUPPLY 312endif # POWER_SUPPLY
313
314source "drivers/power/avs/Kconfig"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b6b243416c0e..ee58afb1e71f 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -43,4 +43,5 @@ obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
43obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o 43obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
44obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o 44obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
45obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o 45obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
46obj-$(CONFIG_POWER_AVS) += avs/
46obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o 47obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
diff --git a/drivers/power/avs/Kconfig b/drivers/power/avs/Kconfig
new file mode 100644
index 000000000000..2a1008b61121
--- /dev/null
+++ b/drivers/power/avs/Kconfig
@@ -0,0 +1,12 @@
1menuconfig POWER_AVS
2 bool "Adaptive Voltage Scaling class support"
3 help
4 AVS is a power management technique which finely controls the
5 operating voltage of a device in order to optimize (i.e. reduce)
6 its power consumption.
7 At a given operating point the voltage is adapted depending on
8 static factors (chip manufacturing process) and dynamic factors
9 (temperature depending performance).
10 AVS is also called SmartReflex on OMAP devices.
11
12 Say Y here to enable Adaptive Voltage Scaling class support.
diff --git a/drivers/power/avs/Makefile b/drivers/power/avs/Makefile
new file mode 100644
index 000000000000..0843386a6c19
--- /dev/null
+++ b/drivers/power/avs/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_POWER_AVS_OMAP) += smartreflex.o
diff --git a/arch/arm/mach-omap2/smartreflex.c b/drivers/power/avs/smartreflex.c
index 008fbd7b9352..44efc6e202af 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Thara Gopinath <thara@ti.com> 4 * Author: Thara Gopinath <thara@ti.com>
5 * 5 *
6 * Copyright (C) 2010 Texas Instruments, Inc. 6 * Copyright (C) 2012 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com> 7 * Thara Gopinath <thara@ti.com>
8 * 8 *
9 * Copyright (C) 2008 Nokia Corporation 9 * Copyright (C) 2008 Nokia Corporation
@@ -25,39 +25,12 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/pm_runtime.h> 27#include <linux/pm_runtime.h>
28 28#include <linux/power/smartreflex.h>
29#include "common.h"
30
31#include "pm.h"
32#include "smartreflex.h"
33 29
34#define SMARTREFLEX_NAME_LEN 16 30#define SMARTREFLEX_NAME_LEN 16
35#define NVALUE_NAME_LEN 40 31#define NVALUE_NAME_LEN 40
36#define SR_DISABLE_TIMEOUT 200 32#define SR_DISABLE_TIMEOUT 200
37 33
38struct omap_sr {
39 struct list_head node;
40 struct platform_device *pdev;
41 struct omap_sr_nvalue_table *nvalue_table;
42 struct voltagedomain *voltdm;
43 struct dentry *dbg_dir;
44 unsigned int irq;
45 int srid;
46 int ip_type;
47 int nvalue_count;
48 bool autocomp_active;
49 u32 clk_length;
50 u32 err_weight;
51 u32 err_minlimit;
52 u32 err_maxlimit;
53 u32 accum_data;
54 u32 senn_avgweight;
55 u32 senp_avgweight;
56 u32 senp_mod;
57 u32 senn_mod;
58 void __iomem *base;
59};
60
61/* sr_list contains all the instances of smartreflex module */ 34/* sr_list contains all the instances of smartreflex module */
62static LIST_HEAD(sr_list); 35static LIST_HEAD(sr_list);
63 36
@@ -148,7 +121,7 @@ static irqreturn_t sr_interrupt(int irq, void *data)
148 } 121 }
149 122
150 if (sr_class->notify) 123 if (sr_class->notify)
151 sr_class->notify(sr_info->voltdm, status); 124 sr_class->notify(sr_info, status);
152 125
153 return IRQ_HANDLED; 126 return IRQ_HANDLED;
154} 127}
@@ -207,7 +180,7 @@ static void sr_set_regfields(struct omap_sr *sr)
207 sr->err_weight = OMAP3430_SR_ERRWEIGHT; 180 sr->err_weight = OMAP3430_SR_ERRWEIGHT;
208 sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT; 181 sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
209 sr->accum_data = OMAP3430_SR_ACCUMDATA; 182 sr->accum_data = OMAP3430_SR_ACCUMDATA;
210 if (!(strcmp(sr->voltdm->name, "mpu"))) { 183 if (!(strcmp(sr->name, "smartreflex_mpu_iva"))) {
211 sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT; 184 sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
212 sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT; 185 sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
213 } else { 186 } else {
@@ -226,7 +199,7 @@ static void sr_start_vddautocomp(struct omap_sr *sr)
226 return; 199 return;
227 } 200 }
228 201
229 if (!sr_class->enable(sr->voltdm)) 202 if (!sr_class->enable(sr))
230 sr->autocomp_active = true; 203 sr->autocomp_active = true;
231} 204}
232 205
@@ -240,7 +213,7 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
240 } 213 }
241 214
242 if (sr->autocomp_active) { 215 if (sr->autocomp_active) {
243 sr_class->disable(sr->voltdm, 1); 216 sr_class->disable(sr, 1);
244 sr->autocomp_active = false; 217 sr->autocomp_active = false;
245 } 218 }
246} 219}
@@ -258,19 +231,13 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
258 */ 231 */
259static int sr_late_init(struct omap_sr *sr_info) 232static int sr_late_init(struct omap_sr *sr_info)
260{ 233{
261 char *name;
262 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data; 234 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
263 struct resource *mem; 235 struct resource *mem;
264 int ret = 0; 236 int ret = 0;
265 237
266 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { 238 if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
267 name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
268 if (name == NULL) {
269 ret = -ENOMEM;
270 goto error;
271 }
272 ret = request_irq(sr_info->irq, sr_interrupt, 239 ret = request_irq(sr_info->irq, sr_interrupt,
273 0, name, sr_info); 240 0, sr_info->name, sr_info);
274 if (ret) 241 if (ret)
275 goto error; 242 goto error;
276 disable_irq(sr_info->irq); 243 disable_irq(sr_info->irq);
@@ -289,7 +256,6 @@ error:
289 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" 256 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
290 "interrupt handler. Smartreflex will" 257 "interrupt handler. Smartreflex will"
291 "not function as desired\n", __func__); 258 "not function as desired\n", __func__);
292 kfree(name);
293 kfree(sr_info); 259 kfree(sr_info);
294 260
295 return ret; 261 return ret;
@@ -320,9 +286,9 @@ static void sr_v1_disable(struct omap_sr *sr)
320 * Wait for SR to be disabled. 286 * Wait for SR to be disabled.
321 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us. 287 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
322 */ 288 */
323 omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) & 289 sr_test_cond_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
324 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT, 290 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
325 timeout); 291 timeout);
326 292
327 if (timeout >= SR_DISABLE_TIMEOUT) 293 if (timeout >= SR_DISABLE_TIMEOUT)
328 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", 294 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
@@ -365,9 +331,9 @@ static void sr_v2_disable(struct omap_sr *sr)
365 * Wait for SR to be disabled. 331 * Wait for SR to be disabled.
366 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us. 332 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
367 */ 333 */
368 omap_test_timeout((sr_read_reg(sr, IRQSTATUS) & 334 sr_test_cond_timeout((sr_read_reg(sr, IRQSTATUS) &
369 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT, 335 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
370 timeout); 336 timeout);
371 337
372 if (timeout >= SR_DISABLE_TIMEOUT) 338 if (timeout >= SR_DISABLE_TIMEOUT)
373 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n", 339 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
@@ -378,22 +344,23 @@ static void sr_v2_disable(struct omap_sr *sr)
378 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT); 344 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
379} 345}
380 346
381static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs) 347static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row(
348 struct omap_sr *sr, u32 efuse_offs)
382{ 349{
383 int i; 350 int i;
384 351
385 if (!sr->nvalue_table) { 352 if (!sr->nvalue_table) {
386 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n", 353 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n",
387 __func__); 354 __func__);
388 return 0; 355 return NULL;
389 } 356 }
390 357
391 for (i = 0; i < sr->nvalue_count; i++) { 358 for (i = 0; i < sr->nvalue_count; i++) {
392 if (sr->nvalue_table[i].efuse_offs == efuse_offs) 359 if (sr->nvalue_table[i].efuse_offs == efuse_offs)
393 return sr->nvalue_table[i].nvalue; 360 return &sr->nvalue_table[i];
394 } 361 }
395 362
396 return 0; 363 return NULL;
397} 364}
398 365
399/* Public Functions */ 366/* Public Functions */
@@ -419,8 +386,7 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
419 struct omap_sr *sr = _sr_lookup(voltdm); 386 struct omap_sr *sr = _sr_lookup(voltdm);
420 387
421 if (IS_ERR(sr)) { 388 if (IS_ERR(sr)) {
422 pr_warning("%s: omap_sr struct for sr_%s not found\n", 389 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
423 __func__, voltdm->name);
424 return PTR_ERR(sr); 390 return PTR_ERR(sr);
425 } 391 }
426 392
@@ -487,8 +453,7 @@ int sr_disable_errgen(struct voltagedomain *voltdm)
487 struct omap_sr *sr = _sr_lookup(voltdm); 453 struct omap_sr *sr = _sr_lookup(voltdm);
488 454
489 if (IS_ERR(sr)) { 455 if (IS_ERR(sr)) {
490 pr_warning("%s: omap_sr struct for sr_%s not found\n", 456 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
491 __func__, voltdm->name);
492 return PTR_ERR(sr); 457 return PTR_ERR(sr);
493 } 458 }
494 459
@@ -538,8 +503,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
538 struct omap_sr *sr = _sr_lookup(voltdm); 503 struct omap_sr *sr = _sr_lookup(voltdm);
539 504
540 if (IS_ERR(sr)) { 505 if (IS_ERR(sr)) {
541 pr_warning("%s: omap_sr struct for sr_%s not found\n", 506 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
542 __func__, voltdm->name);
543 return PTR_ERR(sr); 507 return PTR_ERR(sr);
544 } 508 }
545 509
@@ -620,12 +584,11 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
620{ 584{
621 struct omap_volt_data *volt_data; 585 struct omap_volt_data *volt_data;
622 struct omap_sr *sr = _sr_lookup(voltdm); 586 struct omap_sr *sr = _sr_lookup(voltdm);
623 u32 nvalue_reciprocal; 587 struct omap_sr_nvalue_table *nvalue_row;
624 int ret; 588 int ret;
625 589
626 if (IS_ERR(sr)) { 590 if (IS_ERR(sr)) {
627 pr_warning("%s: omap_sr struct for sr_%s not found\n", 591 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
628 __func__, voltdm->name);
629 return PTR_ERR(sr); 592 return PTR_ERR(sr);
630 } 593 }
631 594
@@ -637,16 +600,16 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
637 return PTR_ERR(volt_data); 600 return PTR_ERR(volt_data);
638 } 601 }
639 602
640 nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs); 603 nvalue_row = sr_retrieve_nvalue_row(sr, volt_data->sr_efuse_offs);
641 604
642 if (!nvalue_reciprocal) { 605 if (!nvalue_row) {
643 dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n", 606 dev_warn(&sr->pdev->dev, "%s: failure getting SR data for this voltage %ld\n",
644 __func__, volt); 607 __func__, volt);
645 return -ENODATA; 608 return -ENODATA;
646 } 609 }
647 610
648 /* errminlimit is opp dependent and hence linked to voltage */ 611 /* errminlimit is opp dependent and hence linked to voltage */
649 sr->err_minlimit = volt_data->sr_errminlimit; 612 sr->err_minlimit = nvalue_row->errminlimit;
650 613
651 pm_runtime_get_sync(&sr->pdev->dev); 614 pm_runtime_get_sync(&sr->pdev->dev);
652 615
@@ -655,11 +618,11 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
655 return 0; 618 return 0;
656 619
657 /* Configure SR */ 620 /* Configure SR */
658 ret = sr_class->configure(voltdm); 621 ret = sr_class->configure(sr);
659 if (ret) 622 if (ret)
660 return ret; 623 return ret;
661 624
662 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal); 625 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_row->nvalue);
663 626
664 /* SRCONFIG - enable SR */ 627 /* SRCONFIG - enable SR */
665 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE); 628 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
@@ -678,8 +641,7 @@ void sr_disable(struct voltagedomain *voltdm)
678 struct omap_sr *sr = _sr_lookup(voltdm); 641 struct omap_sr *sr = _sr_lookup(voltdm);
679 642
680 if (IS_ERR(sr)) { 643 if (IS_ERR(sr)) {
681 pr_warning("%s: omap_sr struct for sr_%s not found\n", 644 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
682 __func__, voltdm->name);
683 return; 645 return;
684 } 646 }
685 647
@@ -759,8 +721,7 @@ void omap_sr_enable(struct voltagedomain *voltdm)
759 struct omap_sr *sr = _sr_lookup(voltdm); 721 struct omap_sr *sr = _sr_lookup(voltdm);
760 722
761 if (IS_ERR(sr)) { 723 if (IS_ERR(sr)) {
762 pr_warning("%s: omap_sr struct for sr_%s not found\n", 724 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
763 __func__, voltdm->name);
764 return; 725 return;
765 } 726 }
766 727
@@ -773,7 +734,7 @@ void omap_sr_enable(struct voltagedomain *voltdm)
773 return; 734 return;
774 } 735 }
775 736
776 sr_class->enable(voltdm); 737 sr_class->enable(sr);
777} 738}
778 739
779/** 740/**
@@ -792,8 +753,7 @@ void omap_sr_disable(struct voltagedomain *voltdm)
792 struct omap_sr *sr = _sr_lookup(voltdm); 753 struct omap_sr *sr = _sr_lookup(voltdm);
793 754
794 if (IS_ERR(sr)) { 755 if (IS_ERR(sr)) {
795 pr_warning("%s: omap_sr struct for sr_%s not found\n", 756 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
796 __func__, voltdm->name);
797 return; 757 return;
798 } 758 }
799 759
@@ -806,7 +766,7 @@ void omap_sr_disable(struct voltagedomain *voltdm)
806 return; 766 return;
807 } 767 }
808 768
809 sr_class->disable(voltdm, 0); 769 sr_class->disable(sr, 0);
810} 770}
811 771
812/** 772/**
@@ -825,8 +785,7 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
825 struct omap_sr *sr = _sr_lookup(voltdm); 785 struct omap_sr *sr = _sr_lookup(voltdm);
826 786
827 if (IS_ERR(sr)) { 787 if (IS_ERR(sr)) {
828 pr_warning("%s: omap_sr struct for sr_%s not found\n", 788 pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
829 __func__, voltdm->name);
830 return; 789 return;
831 } 790 }
832 791
@@ -839,7 +798,7 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
839 return; 798 return;
840 } 799 }
841 800
842 sr_class->disable(voltdm, 1); 801 sr_class->disable(sr, 1);
843} 802}
844 803
845/** 804/**
@@ -911,9 +870,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
911 struct omap_sr_data *pdata = pdev->dev.platform_data; 870 struct omap_sr_data *pdata = pdev->dev.platform_data;
912 struct resource *mem, *irq; 871 struct resource *mem, *irq;
913 struct dentry *nvalue_dir; 872 struct dentry *nvalue_dir;
914 struct omap_volt_data *volt_data;
915 int i, ret = 0; 873 int i, ret = 0;
916 char *name;
917 874
918 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL); 875 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
919 if (!sr_info) { 876 if (!sr_info) {
@@ -950,6 +907,14 @@ static int __init omap_sr_probe(struct platform_device *pdev)
950 pm_runtime_enable(&pdev->dev); 907 pm_runtime_enable(&pdev->dev);
951 pm_runtime_irq_safe(&pdev->dev); 908 pm_runtime_irq_safe(&pdev->dev);
952 909
910 sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name);
911 if (!sr_info->name) {
912 dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n",
913 __func__);
914 ret = -ENOMEM;
915 goto err_release_region;
916 }
917
953 sr_info->pdev = pdev; 918 sr_info->pdev = pdev;
954 sr_info->srid = pdev->id; 919 sr_info->srid = pdev->id;
955 sr_info->voltdm = pdata->voltdm; 920 sr_info->voltdm = pdata->voltdm;
@@ -997,20 +962,12 @@ static int __init omap_sr_probe(struct platform_device *pdev)
997 } 962 }
998 } 963 }
999 964
1000 name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); 965 sr_info->dbg_dir = debugfs_create_dir(sr_info->name, sr_dbg_dir);
1001 if (!name) {
1002 dev_err(&pdev->dev, "%s: Unable to alloc debugfs name\n",
1003 __func__);
1004 ret = -ENOMEM;
1005 goto err_iounmap;
1006 }
1007 sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir);
1008 kfree(name);
1009 if (IS_ERR_OR_NULL(sr_info->dbg_dir)) { 966 if (IS_ERR_OR_NULL(sr_info->dbg_dir)) {
1010 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", 967 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
1011 __func__); 968 __func__);
1012 ret = PTR_ERR(sr_info->dbg_dir); 969 ret = PTR_ERR(sr_info->dbg_dir);
1013 goto err_iounmap; 970 goto err_free_name;
1014 } 971 }
1015 972
1016 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, 973 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
@@ -1019,8 +976,6 @@ static int __init omap_sr_probe(struct platform_device *pdev)
1019 &sr_info->err_weight); 976 &sr_info->err_weight);
1020 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir, 977 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir,
1021 &sr_info->err_maxlimit); 978 &sr_info->err_maxlimit);
1022 (void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir,
1023 &sr_info->err_minlimit);
1024 979
1025 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir); 980 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
1026 if (IS_ERR_OR_NULL(nvalue_dir)) { 981 if (IS_ERR_OR_NULL(nvalue_dir)) {
@@ -1030,12 +985,10 @@ static int __init omap_sr_probe(struct platform_device *pdev)
1030 goto err_debugfs; 985 goto err_debugfs;
1031 } 986 }
1032 987
1033 omap_voltage_get_volttable(sr_info->voltdm, &volt_data); 988 if (sr_info->nvalue_count == 0 || !sr_info->nvalue_table) {
1034 if (!volt_data) { 989 dev_warn(&pdev->dev, "%s: %s: No Voltage table for the corresponding vdd. Cannot create debugfs entries for n-values\n",
1035 dev_warn(&pdev->dev, "%s: No Voltage table for the" 990 __func__, sr_info->name);
1036 " corresponding vdd vdd_%s. Cannot create debugfs" 991
1037 "entries for n-values\n",
1038 __func__, sr_info->voltdm->name);
1039 ret = -ENODATA; 992 ret = -ENODATA;
1040 goto err_debugfs; 993 goto err_debugfs;
1041 } 994 }
@@ -1043,16 +996,23 @@ static int __init omap_sr_probe(struct platform_device *pdev)
1043 for (i = 0; i < sr_info->nvalue_count; i++) { 996 for (i = 0; i < sr_info->nvalue_count; i++) {
1044 char name[NVALUE_NAME_LEN + 1]; 997 char name[NVALUE_NAME_LEN + 1];
1045 998
1046 snprintf(name, sizeof(name), "volt_%d", 999 snprintf(name, sizeof(name), "volt_%lu",
1047 volt_data[i].volt_nominal); 1000 sr_info->nvalue_table[i].volt_nominal);
1048 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir, 1001 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
1049 &(sr_info->nvalue_table[i].nvalue)); 1002 &(sr_info->nvalue_table[i].nvalue));
1003 snprintf(name, sizeof(name), "errminlimit_%lu",
1004 sr_info->nvalue_table[i].volt_nominal);
1005 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
1006 &(sr_info->nvalue_table[i].errminlimit));
1007
1050 } 1008 }
1051 1009
1052 return ret; 1010 return ret;
1053 1011
1054err_debugfs: 1012err_debugfs:
1055 debugfs_remove_recursive(sr_info->dbg_dir); 1013 debugfs_remove_recursive(sr_info->dbg_dir);
1014err_free_name:
1015 kfree(sr_info->name);
1056err_iounmap: 1016err_iounmap:
1057 list_del(&sr_info->node); 1017 list_del(&sr_info->node);
1058 iounmap(sr_info->base); 1018 iounmap(sr_info->base);
@@ -1089,6 +1049,7 @@ static int __devexit omap_sr_remove(struct platform_device *pdev)
1089 1049
1090 list_del(&sr_info->node); 1050 list_del(&sr_info->node);
1091 iounmap(sr_info->base); 1051 iounmap(sr_info->base);
1052 kfree(sr_info->name);
1092 kfree(sr_info); 1053 kfree(sr_info);
1093 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1054 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1094 release_mem_region(mem->start, resource_size(mem)); 1055 release_mem_region(mem->start, resource_size(mem));
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 979d6eed9a0f..5ceb1cd50195 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -60,7 +60,7 @@ config W1_MASTER_GPIO
60 60
61config HDQ_MASTER_OMAP 61config HDQ_MASTER_OMAP
62 tristate "OMAP HDQ driver" 62 tristate "OMAP HDQ driver"
63 depends on SOC_OMAP2430 || ARCH_OMAP3 63 depends on ARCH_OMAP2PLUS
64 help 64 help
65 Say Y here if you want support for the 1-wire or HDQ Interface 65 Say Y here if you want support for the 1-wire or HDQ Interface
66 on an OMAP processor. 66 on an OMAP processor.
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c
index 5ef385bfed18..291897c881be 100644
--- a/drivers/w1/masters/omap_hdq.c
+++ b/drivers/w1/masters/omap_hdq.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/w1/masters/omap_hdq.c 2 * drivers/w1/masters/omap_hdq.c
3 * 3 *
4 * Copyright (C) 2007 Texas Instruments, Inc. 4 * Copyright (C) 2007,2012 Texas Instruments, Inc.
5 * 5 *
6 * This file is licensed under the terms of the GNU General Public License 6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any 7 * version 2. This program is licensed "as is" without any warranty of any
@@ -14,9 +14,9 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/clk.h>
18#include <linux/io.h> 17#include <linux/io.h>
19#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/pm_runtime.h>
20 20
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <mach/hardware.h> 22#include <mach/hardware.h>
@@ -61,8 +61,6 @@ struct hdq_data {
61 /* lock status update */ 61 /* lock status update */
62 struct mutex hdq_mutex; 62 struct mutex hdq_mutex;
63 int hdq_usecount; 63 int hdq_usecount;
64 struct clk *hdq_ick;
65 struct clk *hdq_fck;
66 u8 hdq_irqstatus; 64 u8 hdq_irqstatus;
67 /* device lock */ 65 /* device lock */
68 spinlock_t hdq_spinlock; 66 spinlock_t hdq_spinlock;
@@ -102,20 +100,20 @@ static struct w1_bus_master omap_w1_master = {
102/* HDQ register I/O routines */ 100/* HDQ register I/O routines */
103static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset) 101static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset)
104{ 102{
105 return __raw_readb(hdq_data->hdq_base + offset); 103 return __raw_readl(hdq_data->hdq_base + offset);
106} 104}
107 105
108static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val) 106static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val)
109{ 107{
110 __raw_writeb(val, hdq_data->hdq_base + offset); 108 __raw_writel(val, hdq_data->hdq_base + offset);
111} 109}
112 110
113static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset, 111static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset,
114 u8 val, u8 mask) 112 u8 val, u8 mask)
115{ 113{
116 u8 new_val = (__raw_readb(hdq_data->hdq_base + offset) & ~mask) 114 u8 new_val = (__raw_readl(hdq_data->hdq_base + offset) & ~mask)
117 | (val & mask); 115 | (val & mask);
118 __raw_writeb(new_val, hdq_data->hdq_base + offset); 116 __raw_writel(new_val, hdq_data->hdq_base + offset);
119 117
120 return new_val; 118 return new_val;
121} 119}
@@ -419,17 +417,8 @@ static int omap_hdq_get(struct hdq_data *hdq_data)
419 hdq_data->hdq_usecount++; 417 hdq_data->hdq_usecount++;
420 try_module_get(THIS_MODULE); 418 try_module_get(THIS_MODULE);
421 if (1 == hdq_data->hdq_usecount) { 419 if (1 == hdq_data->hdq_usecount) {
422 if (clk_enable(hdq_data->hdq_ick)) { 420
423 dev_dbg(hdq_data->dev, "Can not enable ick\n"); 421 pm_runtime_get_sync(hdq_data->dev);
424 ret = -ENODEV;
425 goto clk_err;
426 }
427 if (clk_enable(hdq_data->hdq_fck)) {
428 dev_dbg(hdq_data->dev, "Can not enable fck\n");
429 clk_disable(hdq_data->hdq_ick);
430 ret = -ENODEV;
431 goto clk_err;
432 }
433 422
434 /* make sure HDQ is out of reset */ 423 /* make sure HDQ is out of reset */
435 if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) & 424 if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) &
@@ -450,9 +439,6 @@ static int omap_hdq_get(struct hdq_data *hdq_data)
450 } 439 }
451 } 440 }
452 441
453clk_err:
454 clk_put(hdq_data->hdq_ick);
455 clk_put(hdq_data->hdq_fck);
456out: 442out:
457 mutex_unlock(&hdq_data->hdq_mutex); 443 mutex_unlock(&hdq_data->hdq_mutex);
458rtn: 444rtn:
@@ -475,10 +461,8 @@ static int omap_hdq_put(struct hdq_data *hdq_data)
475 } else { 461 } else {
476 hdq_data->hdq_usecount--; 462 hdq_data->hdq_usecount--;
477 module_put(THIS_MODULE); 463 module_put(THIS_MODULE);
478 if (0 == hdq_data->hdq_usecount) { 464 if (0 == hdq_data->hdq_usecount)
479 clk_disable(hdq_data->hdq_ick); 465 pm_runtime_put_sync(hdq_data->dev);
480 clk_disable(hdq_data->hdq_fck);
481 }
482 } 466 }
483 mutex_unlock(&hdq_data->hdq_mutex); 467 mutex_unlock(&hdq_data->hdq_mutex);
484 468
@@ -591,35 +575,11 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
591 goto err_ioremap; 575 goto err_ioremap;
592 } 576 }
593 577
594 /* get interface & functional clock objects */
595 hdq_data->hdq_ick = clk_get(&pdev->dev, "ick");
596 if (IS_ERR(hdq_data->hdq_ick)) {
597 dev_dbg(&pdev->dev, "Can't get HDQ ick clock object\n");
598 ret = PTR_ERR(hdq_data->hdq_ick);
599 goto err_ick;
600 }
601
602 hdq_data->hdq_fck = clk_get(&pdev->dev, "fck");
603 if (IS_ERR(hdq_data->hdq_fck)) {
604 dev_dbg(&pdev->dev, "Can't get HDQ fck clock object\n");
605 ret = PTR_ERR(hdq_data->hdq_fck);
606 goto err_fck;
607 }
608
609 hdq_data->hdq_usecount = 0; 578 hdq_data->hdq_usecount = 0;
610 mutex_init(&hdq_data->hdq_mutex); 579 mutex_init(&hdq_data->hdq_mutex);
611 580
612 if (clk_enable(hdq_data->hdq_ick)) { 581 pm_runtime_enable(&pdev->dev);
613 dev_dbg(&pdev->dev, "Can not enable ick\n"); 582 pm_runtime_get_sync(&pdev->dev);
614 ret = -ENODEV;
615 goto err_intfclk;
616 }
617
618 if (clk_enable(hdq_data->hdq_fck)) {
619 dev_dbg(&pdev->dev, "Can not enable fck\n");
620 ret = -ENODEV;
621 goto err_fnclk;
622 }
623 583
624 rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION); 584 rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION);
625 dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n", 585 dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n",
@@ -641,9 +601,7 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
641 601
642 omap_hdq_break(hdq_data); 602 omap_hdq_break(hdq_data);
643 603
644 /* don't clock the HDQ until it is needed */ 604 pm_runtime_put_sync(&pdev->dev);
645 clk_disable(hdq_data->hdq_ick);
646 clk_disable(hdq_data->hdq_fck);
647 605
648 omap_w1_master.data = hdq_data; 606 omap_w1_master.data = hdq_data;
649 607
@@ -655,20 +613,11 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
655 613
656 return 0; 614 return 0;
657 615
658err_w1:
659err_irq: 616err_irq:
660 clk_disable(hdq_data->hdq_fck); 617 pm_runtime_put_sync(&pdev->dev);
661 618err_w1:
662err_fnclk: 619 pm_runtime_disable(&pdev->dev);
663 clk_disable(hdq_data->hdq_ick);
664
665err_intfclk:
666 clk_put(hdq_data->hdq_fck);
667
668err_fck:
669 clk_put(hdq_data->hdq_ick);
670 620
671err_ick:
672 iounmap(hdq_data->hdq_base); 621 iounmap(hdq_data->hdq_base);
673 622
674err_ioremap: 623err_ioremap:
@@ -696,8 +645,7 @@ static int omap_hdq_remove(struct platform_device *pdev)
696 mutex_unlock(&hdq_data->hdq_mutex); 645 mutex_unlock(&hdq_data->hdq_mutex);
697 646
698 /* remove module dependency */ 647 /* remove module dependency */
699 clk_put(hdq_data->hdq_ick); 648 pm_runtime_disable(&pdev->dev);
700 clk_put(hdq_data->hdq_fck);
701 free_irq(INT_24XX_HDQ_IRQ, hdq_data); 649 free_irq(INT_24XX_HDQ_IRQ, hdq_data);
702 platform_set_drvdata(pdev, NULL); 650 platform_set_drvdata(pdev, NULL);
703 iounmap(hdq_data->hdq_base); 651 iounmap(hdq_data->hdq_base);
diff --git a/arch/arm/mach-omap2/smartreflex.h b/include/linux/power/smartreflex.h
index 5809141171f8..3101e62a1213 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/include/linux/power/smartreflex.h
@@ -17,12 +17,13 @@
17 * published by the Free Software Foundation. 17 * published by the Free Software Foundation.
18 */ 18 */
19 19
20#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H 20#ifndef __POWER_SMARTREFLEX_H
21#define __ASM_ARM_OMAP_SMARTREFLEX_H 21#define __POWER_SMARTREFLEX_H
22 22
23#include <linux/types.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24 25#include <linux/delay.h>
25#include "voltage.h" 26#include <plat/voltage.h>
26 27
27/* 28/*
28 * Different Smartreflex IPs version. The v1 is the 65nm version used in 29 * Different Smartreflex IPs version. The v1 is the 65nm version used in
@@ -142,6 +143,51 @@
142#define OMAP3430_SR_ERRWEIGHT 0x04 143#define OMAP3430_SR_ERRWEIGHT 0x04
143#define OMAP3430_SR_ERRMAXLIMIT 0x02 144#define OMAP3430_SR_ERRMAXLIMIT 0x02
144 145
146struct omap_sr {
147 char *name;
148 struct list_head node;
149 struct platform_device *pdev;
150 struct omap_sr_nvalue_table *nvalue_table;
151 struct voltagedomain *voltdm;
152 struct dentry *dbg_dir;
153 unsigned int irq;
154 int srid;
155 int ip_type;
156 int nvalue_count;
157 bool autocomp_active;
158 u32 clk_length;
159 u32 err_weight;
160 u32 err_minlimit;
161 u32 err_maxlimit;
162 u32 accum_data;
163 u32 senn_avgweight;
164 u32 senp_avgweight;
165 u32 senp_mod;
166 u32 senn_mod;
167 void __iomem *base;
168};
169
170/**
171 * test_cond_timeout - busy-loop, testing a condition
172 * @cond: condition to test until it evaluates to true
173 * @timeout: maximum number of microseconds in the timeout
174 * @index: loop index (integer)
175 *
176 * Loop waiting for @cond to become true or until at least @timeout
177 * microseconds have passed. To use, define some integer @index in the
178 * calling code. After running, if @index == @timeout, then the loop has
179 * timed out.
180 *
181 * Copied from omap_test_timeout */
182#define sr_test_cond_timeout(cond, timeout, index) \
183({ \
184 for (index = 0; index < timeout; index++) { \
185 if (cond) \
186 break; \
187 udelay(1); \
188 } \
189})
190
145/** 191/**
146 * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass 192 * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
147 * pmic specific info to smartreflex driver 193 * pmic specific info to smartreflex driver
@@ -161,7 +207,7 @@ struct omap_smartreflex_dev_attr {
161 const char *sensor_voltdm_name; 207 const char *sensor_voltdm_name;
162}; 208};
163 209
164#ifdef CONFIG_OMAP_SMARTREFLEX 210#ifdef CONFIG_POWER_AVS_OMAP
165/* 211/*
166 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. 212 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
167 * The smartreflex class driver should pass the class type. 213 * The smartreflex class driver should pass the class type.
@@ -186,10 +232,10 @@ struct omap_smartreflex_dev_attr {
186 * based decisions. 232 * based decisions.
187 */ 233 */
188struct omap_sr_class_data { 234struct omap_sr_class_data {
189 int (*enable)(struct voltagedomain *voltdm); 235 int (*enable)(struct omap_sr *sr);
190 int (*disable)(struct voltagedomain *voltdm, int is_volt_reset); 236 int (*disable)(struct omap_sr *sr, int is_volt_reset);
191 int (*configure)(struct voltagedomain *voltdm); 237 int (*configure)(struct omap_sr *sr);
192 int (*notify)(struct voltagedomain *voltdm, u32 status); 238 int (*notify)(struct omap_sr *sr, u32 status);
193 u8 notify_flags; 239 u8 notify_flags;
194 u8 class_type; 240 u8 class_type;
195}; 241};
@@ -197,17 +243,22 @@ struct omap_sr_class_data {
197/** 243/**
198 * struct omap_sr_nvalue_table - Smartreflex n-target value info 244 * struct omap_sr_nvalue_table - Smartreflex n-target value info
199 * 245 *
200 * @efuse_offs: The offset of the efuse where n-target values are stored. 246 * @efuse_offs: The offset of the efuse where n-target values are stored.
201 * @nvalue: The n-target value. 247 * @nvalue: The n-target value.
248 * @errminlimit: The value of the ERRMINLIMIT bitfield for this n-target
249 * @volt_nominal: microvolts DC that the VDD is initially programmed to
202 */ 250 */
203struct omap_sr_nvalue_table { 251struct omap_sr_nvalue_table {
204 u32 efuse_offs; 252 u32 efuse_offs;
205 u32 nvalue; 253 u32 nvalue;
254 u32 errminlimit;
255 unsigned long volt_nominal;
206}; 256};
207 257
208/** 258/**
209 * struct omap_sr_data - Smartreflex platform data. 259 * struct omap_sr_data - Smartreflex platform data.
210 * 260 *
261 * @name: instance name
211 * @ip_type: Smartreflex IP type. 262 * @ip_type: Smartreflex IP type.
212 * @senp_mod: SENPENABLE value for the sr 263 * @senp_mod: SENPENABLE value for the sr
213 * @senn_mod: SENNENABLE value for sr 264 * @senn_mod: SENNENABLE value for sr
@@ -219,6 +270,7 @@ struct omap_sr_nvalue_table {
219 * @voltdm: Pointer to the voltage domain associated with the SR 270 * @voltdm: Pointer to the voltage domain associated with the SR
220 */ 271 */
221struct omap_sr_data { 272struct omap_sr_data {
273 const char *name;
222 int ip_type; 274 int ip_type;
223 u32 senp_mod; 275 u32 senp_mod;
224 u32 senn_mod; 276 u32 senn_mod;