aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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/smartreflex.c1165
-rw-r--r--arch/arm/mach-omap2/smartreflex.h256
-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
40 files changed, 652 insertions, 1762 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/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
deleted file mode 100644
index 008fbd7b9352..000000000000
--- a/arch/arm/mach-omap2/smartreflex.c
+++ /dev/null
@@ -1,1165 +0,0 @@
1/*
2 * OMAP SmartReflex Voltage Control
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2010 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com>
8 *
9 * Copyright (C) 2008 Nokia Corporation
10 * Kalle Jokiniemi
11 *
12 * Copyright (C) 2007 Texas Instruments, Inc.
13 * Lesly A M <x0080970@ti.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
19
20#include <linux/module.h>
21#include <linux/interrupt.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/debugfs.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <linux/pm_runtime.h>
28
29#include "common.h"
30
31#include "pm.h"
32#include "smartreflex.h"
33
34#define SMARTREFLEX_NAME_LEN 16
35#define NVALUE_NAME_LEN 40
36#define SR_DISABLE_TIMEOUT 200
37
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 */
62static LIST_HEAD(sr_list);
63
64static struct omap_sr_class_data *sr_class;
65static struct omap_sr_pmic_data *sr_pmic_data;
66static struct dentry *sr_dbg_dir;
67
68static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
69{
70 __raw_writel(value, (sr->base + offset));
71}
72
73static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
74 u32 value)
75{
76 u32 reg_val;
77
78 /*
79 * Smartreflex error config register is special as it contains
80 * certain status bits which if written a 1 into means a clear
81 * of those bits. So in order to make sure no accidental write of
82 * 1 happens to those status bits, do a clear of them in the read
83 * value. This mean this API doesn't rewrite values in these bits
84 * if they are currently set, but does allow the caller to write
85 * those bits.
86 */
87 if (sr->ip_type == SR_TYPE_V1 && offset == ERRCONFIG_V1)
88 mask |= ERRCONFIG_STATUS_V1_MASK;
89 else if (sr->ip_type == SR_TYPE_V2 && offset == ERRCONFIG_V2)
90 mask |= ERRCONFIG_VPBOUNDINTST_V2;
91
92 reg_val = __raw_readl(sr->base + offset);
93 reg_val &= ~mask;
94
95 value &= mask;
96
97 reg_val |= value;
98
99 __raw_writel(reg_val, (sr->base + offset));
100}
101
102static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
103{
104 return __raw_readl(sr->base + offset);
105}
106
107static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm)
108{
109 struct omap_sr *sr_info;
110
111 if (!voltdm) {
112 pr_err("%s: Null voltage domain passed!\n", __func__);
113 return ERR_PTR(-EINVAL);
114 }
115
116 list_for_each_entry(sr_info, &sr_list, node) {
117 if (voltdm == sr_info->voltdm)
118 return sr_info;
119 }
120
121 return ERR_PTR(-ENODATA);
122}
123
124static irqreturn_t sr_interrupt(int irq, void *data)
125{
126 struct omap_sr *sr_info = data;
127 u32 status = 0;
128
129 switch (sr_info->ip_type) {
130 case SR_TYPE_V1:
131 /* Read the status bits */
132 status = sr_read_reg(sr_info, ERRCONFIG_V1);
133
134 /* Clear them by writing back */
135 sr_write_reg(sr_info, ERRCONFIG_V1, status);
136 break;
137 case SR_TYPE_V2:
138 /* Read the status bits */
139 status = sr_read_reg(sr_info, IRQSTATUS);
140
141 /* Clear them by writing back */
142 sr_write_reg(sr_info, IRQSTATUS, status);
143 break;
144 default:
145 dev_err(&sr_info->pdev->dev, "UNKNOWN IP type %d\n",
146 sr_info->ip_type);
147 return IRQ_NONE;
148 }
149
150 if (sr_class->notify)
151 sr_class->notify(sr_info->voltdm, status);
152
153 return IRQ_HANDLED;
154}
155
156static void sr_set_clk_length(struct omap_sr *sr)
157{
158 struct clk *sys_ck;
159 u32 sys_clk_speed;
160
161 if (cpu_is_omap34xx())
162 sys_ck = clk_get(NULL, "sys_ck");
163 else
164 sys_ck = clk_get(NULL, "sys_clkin_ck");
165
166 if (IS_ERR(sys_ck)) {
167 dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n",
168 __func__);
169 return;
170 }
171
172 sys_clk_speed = clk_get_rate(sys_ck);
173 clk_put(sys_ck);
174
175 switch (sys_clk_speed) {
176 case 12000000:
177 sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
178 break;
179 case 13000000:
180 sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
181 break;
182 case 19200000:
183 sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
184 break;
185 case 26000000:
186 sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
187 break;
188 case 38400000:
189 sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
190 break;
191 default:
192 dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n",
193 __func__, sys_clk_speed);
194 break;
195 }
196}
197
198static void sr_set_regfields(struct omap_sr *sr)
199{
200 /*
201 * For time being these values are defined in smartreflex.h
202 * and populated during init. May be they can be moved to board
203 * file or pmic specific data structure. In that case these structure
204 * fields will have to be populated using the pdata or pmic structure.
205 */
206 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
207 sr->err_weight = OMAP3430_SR_ERRWEIGHT;
208 sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
209 sr->accum_data = OMAP3430_SR_ACCUMDATA;
210 if (!(strcmp(sr->voltdm->name, "mpu"))) {
211 sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
212 sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
213 } else {
214 sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
215 sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
216 }
217 }
218}
219
220static void sr_start_vddautocomp(struct omap_sr *sr)
221{
222 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
223 dev_warn(&sr->pdev->dev,
224 "%s: smartreflex class driver not registered\n",
225 __func__);
226 return;
227 }
228
229 if (!sr_class->enable(sr->voltdm))
230 sr->autocomp_active = true;
231}
232
233static void sr_stop_vddautocomp(struct omap_sr *sr)
234{
235 if (!sr_class || !(sr_class->disable)) {
236 dev_warn(&sr->pdev->dev,
237 "%s: smartreflex class driver not registered\n",
238 __func__);
239 return;
240 }
241
242 if (sr->autocomp_active) {
243 sr_class->disable(sr->voltdm, 1);
244 sr->autocomp_active = false;
245 }
246}
247
248/*
249 * This function handles the intializations which have to be done
250 * only when both sr device and class driver regiter has
251 * completed. This will be attempted to be called from both sr class
252 * driver register and sr device intializtion API's. Only one call
253 * will ultimately succeed.
254 *
255 * Currently this function registers interrupt handler for a particular SR
256 * if smartreflex class driver is already registered and has
257 * requested for interrupts and the SR interrupt line in present.
258 */
259static int sr_late_init(struct omap_sr *sr_info)
260{
261 char *name;
262 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
263 struct resource *mem;
264 int ret = 0;
265
266 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,
273 0, name, sr_info);
274 if (ret)
275 goto error;
276 disable_irq(sr_info->irq);
277 }
278
279 if (pdata && pdata->enable_on_init)
280 sr_start_vddautocomp(sr_info);
281
282 return ret;
283
284error:
285 iounmap(sr_info->base);
286 mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
287 release_mem_region(mem->start, resource_size(mem));
288 list_del(&sr_info->node);
289 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
290 "interrupt handler. Smartreflex will"
291 "not function as desired\n", __func__);
292 kfree(name);
293 kfree(sr_info);
294
295 return ret;
296}
297
298static void sr_v1_disable(struct omap_sr *sr)
299{
300 int timeout = 0;
301 int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
302 ERRCONFIG_MCUBOUNDINTST;
303
304 /* Enable MCUDisableAcknowledge interrupt */
305 sr_modify_reg(sr, ERRCONFIG_V1,
306 ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
307
308 /* SRCONFIG - disable SR */
309 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
310
311 /* Disable all other SR interrupts and clear the status as needed */
312 if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1)
313 errconf_val |= ERRCONFIG_VPBOUNDINTST_V1;
314 sr_modify_reg(sr, ERRCONFIG_V1,
315 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
316 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
317 errconf_val);
318
319 /*
320 * Wait for SR to be disabled.
321 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
322 */
323 omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
324 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
325 timeout);
326
327 if (timeout >= SR_DISABLE_TIMEOUT)
328 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
329 __func__);
330
331 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
332 sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN,
333 ERRCONFIG_MCUDISACKINTST);
334}
335
336static void sr_v2_disable(struct omap_sr *sr)
337{
338 int timeout = 0;
339
340 /* Enable MCUDisableAcknowledge interrupt */
341 sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT);
342
343 /* SRCONFIG - disable SR */
344 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
345
346 /*
347 * Disable all other SR interrupts and clear the status
348 * write to status register ONLY on need basis - only if status
349 * is set.
350 */
351 if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2)
352 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
353 ERRCONFIG_VPBOUNDINTST_V2);
354 else
355 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
356 0x0);
357 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
358 IRQENABLE_MCUVALIDINT |
359 IRQENABLE_MCUBOUNDSINT));
360 sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT |
361 IRQSTATUS_MCVALIDINT |
362 IRQSTATUS_MCBOUNDSINT));
363
364 /*
365 * Wait for SR to be disabled.
366 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
367 */
368 omap_test_timeout((sr_read_reg(sr, IRQSTATUS) &
369 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
370 timeout);
371
372 if (timeout >= SR_DISABLE_TIMEOUT)
373 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
374 __func__);
375
376 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
377 sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT);
378 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
379}
380
381static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs)
382{
383 int i;
384
385 if (!sr->nvalue_table) {
386 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n",
387 __func__);
388 return 0;
389 }
390
391 for (i = 0; i < sr->nvalue_count; i++) {
392 if (sr->nvalue_table[i].efuse_offs == efuse_offs)
393 return sr->nvalue_table[i].nvalue;
394 }
395
396 return 0;
397}
398
399/* Public Functions */
400
401/**
402 * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
403 * error generator module.
404 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
405 *
406 * This API is to be called from the smartreflex class driver to
407 * configure the error generator module inside the smartreflex module.
408 * SR settings if using the ERROR module inside Smartreflex.
409 * SR CLASS 3 by default uses only the ERROR module where as
410 * SR CLASS 2 can choose between ERROR module and MINMAXAVG
411 * module. Returns 0 on success and error value in case of failure.
412 */
413int sr_configure_errgen(struct voltagedomain *voltdm)
414{
415 u32 sr_config, sr_errconfig, errconfig_offs;
416 u32 vpboundint_en, vpboundint_st;
417 u32 senp_en = 0, senn_en = 0;
418 u8 senp_shift, senn_shift;
419 struct omap_sr *sr = _sr_lookup(voltdm);
420
421 if (IS_ERR(sr)) {
422 pr_warning("%s: omap_sr struct for sr_%s not found\n",
423 __func__, voltdm->name);
424 return PTR_ERR(sr);
425 }
426
427 if (!sr->clk_length)
428 sr_set_clk_length(sr);
429
430 senp_en = sr->senp_mod;
431 senn_en = sr->senn_mod;
432
433 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
434 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN;
435
436 switch (sr->ip_type) {
437 case SR_TYPE_V1:
438 sr_config |= SRCONFIG_DELAYCTRL;
439 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
440 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
441 errconfig_offs = ERRCONFIG_V1;
442 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
443 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
444 break;
445 case SR_TYPE_V2:
446 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
447 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
448 errconfig_offs = ERRCONFIG_V2;
449 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
450 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
451 break;
452 default:
453 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
454 "module without specifying the ip\n", __func__);
455 return -EINVAL;
456 }
457
458 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
459 sr_write_reg(sr, SRCONFIG, sr_config);
460 sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) |
461 (sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) |
462 (sr->err_minlimit << ERRCONFIG_ERRMINLIMIT_SHIFT);
463 sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK |
464 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
465 sr_errconfig);
466
467 /* Enabling the interrupts if the ERROR module is used */
468 sr_modify_reg(sr, errconfig_offs, (vpboundint_en | vpboundint_st),
469 vpboundint_en);
470
471 return 0;
472}
473
474/**
475 * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component
476 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
477 *
478 * This API is to be called from the smartreflex class driver to
479 * disable the error generator module inside the smartreflex module.
480 *
481 * Returns 0 on success and error value in case of failure.
482 */
483int sr_disable_errgen(struct voltagedomain *voltdm)
484{
485 u32 errconfig_offs;
486 u32 vpboundint_en, vpboundint_st;
487 struct omap_sr *sr = _sr_lookup(voltdm);
488
489 if (IS_ERR(sr)) {
490 pr_warning("%s: omap_sr struct for sr_%s not found\n",
491 __func__, voltdm->name);
492 return PTR_ERR(sr);
493 }
494
495 switch (sr->ip_type) {
496 case SR_TYPE_V1:
497 errconfig_offs = ERRCONFIG_V1;
498 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
499 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
500 break;
501 case SR_TYPE_V2:
502 errconfig_offs = ERRCONFIG_V2;
503 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
504 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
505 break;
506 default:
507 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
508 "module without specifying the ip\n", __func__);
509 return -EINVAL;
510 }
511
512 /* Disable the interrupts of ERROR module */
513 sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
514
515 /* Disable the Sensor and errorgen */
516 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0);
517
518 return 0;
519}
520
521/**
522 * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
523 * minmaxavg module.
524 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
525 *
526 * This API is to be called from the smartreflex class driver to
527 * configure the minmaxavg module inside the smartreflex module.
528 * SR settings if using the ERROR module inside Smartreflex.
529 * SR CLASS 3 by default uses only the ERROR module where as
530 * SR CLASS 2 can choose between ERROR module and MINMAXAVG
531 * module. Returns 0 on success and error value in case of failure.
532 */
533int sr_configure_minmax(struct voltagedomain *voltdm)
534{
535 u32 sr_config, sr_avgwt;
536 u32 senp_en = 0, senn_en = 0;
537 u8 senp_shift, senn_shift;
538 struct omap_sr *sr = _sr_lookup(voltdm);
539
540 if (IS_ERR(sr)) {
541 pr_warning("%s: omap_sr struct for sr_%s not found\n",
542 __func__, voltdm->name);
543 return PTR_ERR(sr);
544 }
545
546 if (!sr->clk_length)
547 sr_set_clk_length(sr);
548
549 senp_en = sr->senp_mod;
550 senn_en = sr->senn_mod;
551
552 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
553 SRCONFIG_SENENABLE |
554 (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT);
555
556 switch (sr->ip_type) {
557 case SR_TYPE_V1:
558 sr_config |= SRCONFIG_DELAYCTRL;
559 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
560 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
561 break;
562 case SR_TYPE_V2:
563 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
564 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
565 break;
566 default:
567 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
568 "module without specifying the ip\n", __func__);
569 return -EINVAL;
570 }
571
572 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
573 sr_write_reg(sr, SRCONFIG, sr_config);
574 sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) |
575 (sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT);
576 sr_write_reg(sr, AVGWEIGHT, sr_avgwt);
577
578 /*
579 * Enabling the interrupts if MINMAXAVG module is used.
580 * TODO: check if all the interrupts are mandatory
581 */
582 switch (sr->ip_type) {
583 case SR_TYPE_V1:
584 sr_modify_reg(sr, ERRCONFIG_V1,
585 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
586 ERRCONFIG_MCUBOUNDINTEN),
587 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
588 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
589 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
590 break;
591 case SR_TYPE_V2:
592 sr_write_reg(sr, IRQSTATUS,
593 IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
594 IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT);
595 sr_write_reg(sr, IRQENABLE_SET,
596 IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
597 IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT);
598 break;
599 default:
600 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
601 "module without specifying the ip\n", __func__);
602 return -EINVAL;
603 }
604
605 return 0;
606}
607
608/**
609 * sr_enable() - Enables the smartreflex module.
610 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
611 * @volt: The voltage at which the Voltage domain associated with
612 * the smartreflex module is operating at.
613 * This is required only to program the correct Ntarget value.
614 *
615 * This API is to be called from the smartreflex class driver to
616 * enable a smartreflex module. Returns 0 on success. Returns error
617 * value if the voltage passed is wrong or if ntarget value is wrong.
618 */
619int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
620{
621 struct omap_volt_data *volt_data;
622 struct omap_sr *sr = _sr_lookup(voltdm);
623 u32 nvalue_reciprocal;
624 int ret;
625
626 if (IS_ERR(sr)) {
627 pr_warning("%s: omap_sr struct for sr_%s not found\n",
628 __func__, voltdm->name);
629 return PTR_ERR(sr);
630 }
631
632 volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
633
634 if (IS_ERR(volt_data)) {
635 dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table"
636 "for nominal voltage %ld\n", __func__, volt);
637 return PTR_ERR(volt_data);
638 }
639
640 nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs);
641
642 if (!nvalue_reciprocal) {
643 dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n",
644 __func__, volt);
645 return -ENODATA;
646 }
647
648 /* errminlimit is opp dependent and hence linked to voltage */
649 sr->err_minlimit = volt_data->sr_errminlimit;
650
651 pm_runtime_get_sync(&sr->pdev->dev);
652
653 /* Check if SR is already enabled. If yes do nothing */
654 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE)
655 return 0;
656
657 /* Configure SR */
658 ret = sr_class->configure(voltdm);
659 if (ret)
660 return ret;
661
662 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
663
664 /* SRCONFIG - enable SR */
665 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
666 return 0;
667}
668
669/**
670 * sr_disable() - Disables the smartreflex module.
671 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
672 *
673 * This API is to be called from the smartreflex class driver to
674 * disable a smartreflex module.
675 */
676void sr_disable(struct voltagedomain *voltdm)
677{
678 struct omap_sr *sr = _sr_lookup(voltdm);
679
680 if (IS_ERR(sr)) {
681 pr_warning("%s: omap_sr struct for sr_%s not found\n",
682 __func__, voltdm->name);
683 return;
684 }
685
686 /* Check if SR clocks are already disabled. If yes do nothing */
687 if (pm_runtime_suspended(&sr->pdev->dev))
688 return;
689
690 /*
691 * Disable SR if only it is indeed enabled. Else just
692 * disable the clocks.
693 */
694 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) {
695 switch (sr->ip_type) {
696 case SR_TYPE_V1:
697 sr_v1_disable(sr);
698 break;
699 case SR_TYPE_V2:
700 sr_v2_disable(sr);
701 break;
702 default:
703 dev_err(&sr->pdev->dev, "UNKNOWN IP type %d\n",
704 sr->ip_type);
705 }
706 }
707
708 pm_runtime_put_sync_suspend(&sr->pdev->dev);
709}
710
711/**
712 * sr_register_class() - API to register a smartreflex class parameters.
713 * @class_data: The structure containing various sr class specific data.
714 *
715 * This API is to be called by the smartreflex class driver to register itself
716 * with the smartreflex driver during init. Returns 0 on success else the
717 * error value.
718 */
719int sr_register_class(struct omap_sr_class_data *class_data)
720{
721 struct omap_sr *sr_info;
722
723 if (!class_data) {
724 pr_warning("%s:, Smartreflex class data passed is NULL\n",
725 __func__);
726 return -EINVAL;
727 }
728
729 if (sr_class) {
730 pr_warning("%s: Smartreflex class driver already registered\n",
731 __func__);
732 return -EBUSY;
733 }
734
735 sr_class = class_data;
736
737 /*
738 * Call into late init to do intializations that require
739 * both sr driver and sr class driver to be initiallized.
740 */
741 list_for_each_entry(sr_info, &sr_list, node)
742 sr_late_init(sr_info);
743
744 return 0;
745}
746
747/**
748 * omap_sr_enable() - API to enable SR clocks and to call into the
749 * registered smartreflex class enable API.
750 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
751 *
752 * This API is to be called from the kernel in order to enable
753 * a particular smartreflex module. This API will do the initial
754 * configurations to turn on the smartreflex module and in turn call
755 * into the registered smartreflex class enable API.
756 */
757void omap_sr_enable(struct voltagedomain *voltdm)
758{
759 struct omap_sr *sr = _sr_lookup(voltdm);
760
761 if (IS_ERR(sr)) {
762 pr_warning("%s: omap_sr struct for sr_%s not found\n",
763 __func__, voltdm->name);
764 return;
765 }
766
767 if (!sr->autocomp_active)
768 return;
769
770 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
771 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
772 "registered\n", __func__);
773 return;
774 }
775
776 sr_class->enable(voltdm);
777}
778
779/**
780 * omap_sr_disable() - API to disable SR without resetting the voltage
781 * processor voltage
782 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
783 *
784 * This API is to be called from the kernel in order to disable
785 * a particular smartreflex module. This API will in turn call
786 * into the registered smartreflex class disable API. This API will tell
787 * the smartreflex class disable not to reset the VP voltage after
788 * disabling smartreflex.
789 */
790void omap_sr_disable(struct voltagedomain *voltdm)
791{
792 struct omap_sr *sr = _sr_lookup(voltdm);
793
794 if (IS_ERR(sr)) {
795 pr_warning("%s: omap_sr struct for sr_%s not found\n",
796 __func__, voltdm->name);
797 return;
798 }
799
800 if (!sr->autocomp_active)
801 return;
802
803 if (!sr_class || !(sr_class->disable)) {
804 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
805 "registered\n", __func__);
806 return;
807 }
808
809 sr_class->disable(voltdm, 0);
810}
811
812/**
813 * omap_sr_disable_reset_volt() - API to disable SR and reset the
814 * voltage processor voltage
815 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
816 *
817 * This API is to be called from the kernel in order to disable
818 * a particular smartreflex module. This API will in turn call
819 * into the registered smartreflex class disable API. This API will tell
820 * the smartreflex class disable to reset the VP voltage after
821 * disabling smartreflex.
822 */
823void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
824{
825 struct omap_sr *sr = _sr_lookup(voltdm);
826
827 if (IS_ERR(sr)) {
828 pr_warning("%s: omap_sr struct for sr_%s not found\n",
829 __func__, voltdm->name);
830 return;
831 }
832
833 if (!sr->autocomp_active)
834 return;
835
836 if (!sr_class || !(sr_class->disable)) {
837 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
838 "registered\n", __func__);
839 return;
840 }
841
842 sr_class->disable(voltdm, 1);
843}
844
845/**
846 * omap_sr_register_pmic() - API to register pmic specific info.
847 * @pmic_data: The structure containing pmic specific data.
848 *
849 * This API is to be called from the PMIC specific code to register with
850 * smartreflex driver pmic specific info. Currently the only info required
851 * is the smartreflex init on the PMIC side.
852 */
853void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data)
854{
855 if (!pmic_data) {
856 pr_warning("%s: Trying to register NULL PMIC data structure"
857 "with smartreflex\n", __func__);
858 return;
859 }
860
861 sr_pmic_data = pmic_data;
862}
863
864/* PM Debug FS entries to enable and disable smartreflex. */
865static int omap_sr_autocomp_show(void *data, u64 *val)
866{
867 struct omap_sr *sr_info = data;
868
869 if (!sr_info) {
870 pr_warning("%s: omap_sr struct not found\n", __func__);
871 return -EINVAL;
872 }
873
874 *val = sr_info->autocomp_active;
875
876 return 0;
877}
878
879static int omap_sr_autocomp_store(void *data, u64 val)
880{
881 struct omap_sr *sr_info = data;
882
883 if (!sr_info) {
884 pr_warning("%s: omap_sr struct not found\n", __func__);
885 return -EINVAL;
886 }
887
888 /* Sanity check */
889 if (val > 1) {
890 pr_warning("%s: Invalid argument %lld\n", __func__, val);
891 return -EINVAL;
892 }
893
894 /* control enable/disable only if there is a delta in value */
895 if (sr_info->autocomp_active != val) {
896 if (!val)
897 sr_stop_vddautocomp(sr_info);
898 else
899 sr_start_vddautocomp(sr_info);
900 }
901
902 return 0;
903}
904
905DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
906 omap_sr_autocomp_store, "%llu\n");
907
908static int __init omap_sr_probe(struct platform_device *pdev)
909{
910 struct omap_sr *sr_info;
911 struct omap_sr_data *pdata = pdev->dev.platform_data;
912 struct resource *mem, *irq;
913 struct dentry *nvalue_dir;
914 struct omap_volt_data *volt_data;
915 int i, ret = 0;
916 char *name;
917
918 sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
919 if (!sr_info) {
920 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
921 __func__);
922 return -ENOMEM;
923 }
924
925 platform_set_drvdata(pdev, sr_info);
926
927 if (!pdata) {
928 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
929 ret = -EINVAL;
930 goto err_free_devinfo;
931 }
932
933 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
934 if (!mem) {
935 dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
936 ret = -ENODEV;
937 goto err_free_devinfo;
938 }
939
940 mem = request_mem_region(mem->start, resource_size(mem),
941 dev_name(&pdev->dev));
942 if (!mem) {
943 dev_err(&pdev->dev, "%s: no mem region\n", __func__);
944 ret = -EBUSY;
945 goto err_free_devinfo;
946 }
947
948 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
949
950 pm_runtime_enable(&pdev->dev);
951 pm_runtime_irq_safe(&pdev->dev);
952
953 sr_info->pdev = pdev;
954 sr_info->srid = pdev->id;
955 sr_info->voltdm = pdata->voltdm;
956 sr_info->nvalue_table = pdata->nvalue_table;
957 sr_info->nvalue_count = pdata->nvalue_count;
958 sr_info->senn_mod = pdata->senn_mod;
959 sr_info->senp_mod = pdata->senp_mod;
960 sr_info->autocomp_active = false;
961 sr_info->ip_type = pdata->ip_type;
962 sr_info->base = ioremap(mem->start, resource_size(mem));
963 if (!sr_info->base) {
964 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
965 ret = -ENOMEM;
966 goto err_release_region;
967 }
968
969 if (irq)
970 sr_info->irq = irq->start;
971
972 sr_set_clk_length(sr_info);
973 sr_set_regfields(sr_info);
974
975 list_add(&sr_info->node, &sr_list);
976
977 /*
978 * Call into late init to do intializations that require
979 * both sr driver and sr class driver to be initiallized.
980 */
981 if (sr_class) {
982 ret = sr_late_init(sr_info);
983 if (ret) {
984 pr_warning("%s: Error in SR late init\n", __func__);
985 goto err_iounmap;
986 }
987 }
988
989 dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
990 if (!sr_dbg_dir) {
991 sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);
992 if (IS_ERR_OR_NULL(sr_dbg_dir)) {
993 ret = PTR_ERR(sr_dbg_dir);
994 pr_err("%s:sr debugfs dir creation failed(%d)\n",
995 __func__, ret);
996 goto err_iounmap;
997 }
998 }
999
1000 name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
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)) {
1010 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
1011 __func__);
1012 ret = PTR_ERR(sr_info->dbg_dir);
1013 goto err_iounmap;
1014 }
1015
1016 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
1017 sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops);
1018 (void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir,
1019 &sr_info->err_weight);
1020 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir,
1021 &sr_info->err_maxlimit);
1022 (void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir,
1023 &sr_info->err_minlimit);
1024
1025 nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
1026 if (IS_ERR_OR_NULL(nvalue_dir)) {
1027 dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
1028 "for n-values\n", __func__);
1029 ret = PTR_ERR(nvalue_dir);
1030 goto err_debugfs;
1031 }
1032
1033 omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
1034 if (!volt_data) {
1035 dev_warn(&pdev->dev, "%s: No Voltage table for the"
1036 " corresponding vdd vdd_%s. Cannot create debugfs"
1037 "entries for n-values\n",
1038 __func__, sr_info->voltdm->name);
1039 ret = -ENODATA;
1040 goto err_debugfs;
1041 }
1042
1043 for (i = 0; i < sr_info->nvalue_count; i++) {
1044 char name[NVALUE_NAME_LEN + 1];
1045
1046 snprintf(name, sizeof(name), "volt_%d",
1047 volt_data[i].volt_nominal);
1048 (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
1049 &(sr_info->nvalue_table[i].nvalue));
1050 }
1051
1052 return ret;
1053
1054err_debugfs:
1055 debugfs_remove_recursive(sr_info->dbg_dir);
1056err_iounmap:
1057 list_del(&sr_info->node);
1058 iounmap(sr_info->base);
1059err_release_region:
1060 release_mem_region(mem->start, resource_size(mem));
1061err_free_devinfo:
1062 kfree(sr_info);
1063
1064 return ret;
1065}
1066
1067static int __devexit omap_sr_remove(struct platform_device *pdev)
1068{
1069 struct omap_sr_data *pdata = pdev->dev.platform_data;
1070 struct omap_sr *sr_info;
1071 struct resource *mem;
1072
1073 if (!pdata) {
1074 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
1075 return -EINVAL;
1076 }
1077
1078 sr_info = _sr_lookup(pdata->voltdm);
1079 if (IS_ERR(sr_info)) {
1080 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
1081 __func__);
1082 return PTR_ERR(sr_info);
1083 }
1084
1085 if (sr_info->autocomp_active)
1086 sr_stop_vddautocomp(sr_info);
1087 if (sr_info->dbg_dir)
1088 debugfs_remove_recursive(sr_info->dbg_dir);
1089
1090 list_del(&sr_info->node);
1091 iounmap(sr_info->base);
1092 kfree(sr_info);
1093 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1094 release_mem_region(mem->start, resource_size(mem));
1095
1096 return 0;
1097}
1098
1099static void __devexit omap_sr_shutdown(struct platform_device *pdev)
1100{
1101 struct omap_sr_data *pdata = pdev->dev.platform_data;
1102 struct omap_sr *sr_info;
1103
1104 if (!pdata) {
1105 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
1106 return;
1107 }
1108
1109 sr_info = _sr_lookup(pdata->voltdm);
1110 if (IS_ERR(sr_info)) {
1111 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
1112 __func__);
1113 return;
1114 }
1115
1116 if (sr_info->autocomp_active)
1117 sr_stop_vddautocomp(sr_info);
1118
1119 return;
1120}
1121
1122static struct platform_driver smartreflex_driver = {
1123 .remove = __devexit_p(omap_sr_remove),
1124 .shutdown = __devexit_p(omap_sr_shutdown),
1125 .driver = {
1126 .name = "smartreflex",
1127 },
1128};
1129
1130static int __init sr_init(void)
1131{
1132 int ret = 0;
1133
1134 /*
1135 * sr_init is a late init. If by then a pmic specific API is not
1136 * registered either there is no need for anything to be done on
1137 * the PMIC side or somebody has forgotten to register a PMIC
1138 * handler. Warn for the second condition.
1139 */
1140 if (sr_pmic_data && sr_pmic_data->sr_pmic_init)
1141 sr_pmic_data->sr_pmic_init();
1142 else
1143 pr_warning("%s: No PMIC hook to init smartreflex\n", __func__);
1144
1145 ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe);
1146 if (ret) {
1147 pr_err("%s: platform driver register failed for SR\n",
1148 __func__);
1149 return ret;
1150 }
1151
1152 return 0;
1153}
1154late_initcall(sr_init);
1155
1156static void __exit sr_exit(void)
1157{
1158 platform_driver_unregister(&smartreflex_driver);
1159}
1160module_exit(sr_exit);
1161
1162MODULE_DESCRIPTION("OMAP Smartreflex Driver");
1163MODULE_LICENSE("GPL");
1164MODULE_ALIAS("platform:" DRIVER_NAME);
1165MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
deleted file mode 100644
index 5809141171f8..000000000000
--- a/arch/arm/mach-omap2/smartreflex.h
+++ /dev/null
@@ -1,256 +0,0 @@
1/*
2 * OMAP Smartreflex Defines and Routines
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2010 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com>
8 *
9 * Copyright (C) 2008 Nokia Corporation
10 * Kalle Jokiniemi
11 *
12 * Copyright (C) 2007 Texas Instruments, Inc.
13 * Lesly A M <x0080970@ti.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
19
20#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H
21#define __ASM_ARM_OMAP_SMARTREFLEX_H
22
23#include <linux/platform_device.h>
24
25#include "voltage.h"
26
27/*
28 * Different Smartreflex IPs version. The v1 is the 65nm version used in
29 * OMAP3430. The v2 is the update for the 45nm version of the IP
30 * used in OMAP3630 and OMAP4430
31 */
32#define SR_TYPE_V1 1
33#define SR_TYPE_V2 2
34
35/* SMART REFLEX REG ADDRESS OFFSET */
36#define SRCONFIG 0x00
37#define SRSTATUS 0x04
38#define SENVAL 0x08
39#define SENMIN 0x0C
40#define SENMAX 0x10
41#define SENAVG 0x14
42#define AVGWEIGHT 0x18
43#define NVALUERECIPROCAL 0x1c
44#define SENERROR_V1 0x20
45#define ERRCONFIG_V1 0x24
46#define IRQ_EOI 0x20
47#define IRQSTATUS_RAW 0x24
48#define IRQSTATUS 0x28
49#define IRQENABLE_SET 0x2C
50#define IRQENABLE_CLR 0x30
51#define SENERROR_V2 0x34
52#define ERRCONFIG_V2 0x38
53
54/* Bit/Shift Positions */
55
56/* SRCONFIG */
57#define SRCONFIG_ACCUMDATA_SHIFT 22
58#define SRCONFIG_SRCLKLENGTH_SHIFT 12
59#define SRCONFIG_SENNENABLE_V1_SHIFT 5
60#define SRCONFIG_SENPENABLE_V1_SHIFT 3
61#define SRCONFIG_SENNENABLE_V2_SHIFT 1
62#define SRCONFIG_SENPENABLE_V2_SHIFT 0
63#define SRCONFIG_CLKCTRL_SHIFT 0
64
65#define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
66
67#define SRCONFIG_SRENABLE BIT(11)
68#define SRCONFIG_SENENABLE BIT(10)
69#define SRCONFIG_ERRGEN_EN BIT(9)
70#define SRCONFIG_MINMAXAVG_EN BIT(8)
71#define SRCONFIG_DELAYCTRL BIT(2)
72
73/* AVGWEIGHT */
74#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
75#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
76
77/* NVALUERECIPROCAL */
78#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
79#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
80#define NVALUERECIPROCAL_RNSENP_SHIFT 8
81#define NVALUERECIPROCAL_RNSENN_SHIFT 0
82
83/* ERRCONFIG */
84#define ERRCONFIG_ERRWEIGHT_SHIFT 16
85#define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
86#define ERRCONFIG_ERRMINLIMIT_SHIFT 0
87
88#define SR_ERRWEIGHT_MASK (0x07 << 16)
89#define SR_ERRMAXLIMIT_MASK (0xff << 8)
90#define SR_ERRMINLIMIT_MASK (0xff << 0)
91
92#define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
93#define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
94#define ERRCONFIG_MCUACCUMINTEN BIT(29)
95#define ERRCONFIG_MCUACCUMINTST BIT(28)
96#define ERRCONFIG_MCUVALIDINTEN BIT(27)
97#define ERRCONFIG_MCUVALIDINTST BIT(26)
98#define ERRCONFIG_MCUBOUNDINTEN BIT(25)
99#define ERRCONFIG_MCUBOUNDINTST BIT(24)
100#define ERRCONFIG_MCUDISACKINTEN BIT(23)
101#define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
102#define ERRCONFIG_MCUDISACKINTST BIT(22)
103#define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
104
105#define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
106 ERRCONFIG_MCUACCUMINTST | \
107 ERRCONFIG_MCUVALIDINTST | \
108 ERRCONFIG_MCUBOUNDINTST | \
109 ERRCONFIG_MCUDISACKINTST)
110/* IRQSTATUS */
111#define IRQSTATUS_MCUACCUMINT BIT(3)
112#define IRQSTATUS_MCVALIDINT BIT(2)
113#define IRQSTATUS_MCBOUNDSINT BIT(1)
114#define IRQSTATUS_MCUDISABLEACKINT BIT(0)
115
116/* IRQENABLE_SET and IRQENABLE_CLEAR */
117#define IRQENABLE_MCUACCUMINT BIT(3)
118#define IRQENABLE_MCUVALIDINT BIT(2)
119#define IRQENABLE_MCUBOUNDSINT BIT(1)
120#define IRQENABLE_MCUDISABLEACKINT BIT(0)
121
122/* Common Bit values */
123
124#define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
125#define SRCLKLENGTH_13MHZ_SYSCLK 0x41
126#define SRCLKLENGTH_19MHZ_SYSCLK 0x60
127#define SRCLKLENGTH_26MHZ_SYSCLK 0x82
128#define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
129
130/*
131 * 3430 specific values. Maybe these should be passed from board file or
132 * pmic structures.
133 */
134#define OMAP3430_SR_ACCUMDATA 0x1f4
135
136#define OMAP3430_SR1_SENPAVGWEIGHT 0x03
137#define OMAP3430_SR1_SENNAVGWEIGHT 0x03
138
139#define OMAP3430_SR2_SENPAVGWEIGHT 0x01
140#define OMAP3430_SR2_SENNAVGWEIGHT 0x01
141
142#define OMAP3430_SR_ERRWEIGHT 0x04
143#define OMAP3430_SR_ERRMAXLIMIT 0x02
144
145/**
146 * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
147 * pmic specific info to smartreflex driver
148 *
149 * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
150 */
151struct omap_sr_pmic_data {
152 void (*sr_pmic_init) (void);
153};
154
155/**
156 * struct omap_smartreflex_dev_attr - Smartreflex Device attribute.
157 *
158 * @sensor_voltdm_name: Name of voltdomain of SR instance
159 */
160struct omap_smartreflex_dev_attr {
161 const char *sensor_voltdm_name;
162};
163
164#ifdef CONFIG_OMAP_SMARTREFLEX
165/*
166 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
167 * The smartreflex class driver should pass the class type.
168 * Should be used to populate the class_type field of the
169 * omap_smartreflex_class_data structure.
170 */
171#define SR_CLASS1 0x1
172#define SR_CLASS2 0x2
173#define SR_CLASS3 0x3
174
175/**
176 * struct omap_sr_class_data - Smartreflex class driver info
177 *
178 * @enable: API to enable a particular class smaartreflex.
179 * @disable: API to disable a particular class smartreflex.
180 * @configure: API to configure a particular class smartreflex.
181 * @notify: API to notify the class driver about an event in SR.
182 * Not needed for class3.
183 * @notify_flags: specify the events to be notified to the class driver
184 * @class_type: specify which smartreflex class.
185 * Can be used by the SR driver to take any class
186 * based decisions.
187 */
188struct omap_sr_class_data {
189 int (*enable)(struct voltagedomain *voltdm);
190 int (*disable)(struct voltagedomain *voltdm, int is_volt_reset);
191 int (*configure)(struct voltagedomain *voltdm);
192 int (*notify)(struct voltagedomain *voltdm, u32 status);
193 u8 notify_flags;
194 u8 class_type;
195};
196
197/**
198 * struct omap_sr_nvalue_table - Smartreflex n-target value info
199 *
200 * @efuse_offs: The offset of the efuse where n-target values are stored.
201 * @nvalue: The n-target value.
202 */
203struct omap_sr_nvalue_table {
204 u32 efuse_offs;
205 u32 nvalue;
206};
207
208/**
209 * struct omap_sr_data - Smartreflex platform data.
210 *
211 * @ip_type: Smartreflex IP type.
212 * @senp_mod: SENPENABLE value for the sr
213 * @senn_mod: SENNENABLE value for sr
214 * @nvalue_count: Number of distinct nvalues in the nvalue table
215 * @enable_on_init: whether this sr module needs to enabled at
216 * boot up or not.
217 * @nvalue_table: table containing the efuse offsets and nvalues
218 * corresponding to them.
219 * @voltdm: Pointer to the voltage domain associated with the SR
220 */
221struct omap_sr_data {
222 int ip_type;
223 u32 senp_mod;
224 u32 senn_mod;
225 int nvalue_count;
226 bool enable_on_init;
227 struct omap_sr_nvalue_table *nvalue_table;
228 struct voltagedomain *voltdm;
229};
230
231/* Smartreflex module enable/disable interface */
232void omap_sr_enable(struct voltagedomain *voltdm);
233void omap_sr_disable(struct voltagedomain *voltdm);
234void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
235
236/* API to register the pmic specific data with the smartreflex driver. */
237void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
238
239/* Smartreflex driver hooks to be called from Smartreflex class driver */
240int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
241void sr_disable(struct voltagedomain *voltdm);
242int sr_configure_errgen(struct voltagedomain *voltdm);
243int sr_disable_errgen(struct voltagedomain *voltdm);
244int sr_configure_minmax(struct voltagedomain *voltdm);
245
246/* API to register the smartreflex class driver with the smartreflex driver */
247int sr_register_class(struct omap_sr_class_data *class_data);
248#else
249static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
250static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
251static inline void omap_sr_disable_reset_volt(
252 struct voltagedomain *voltdm) {}
253static inline void omap_sr_register_pmic(
254 struct omap_sr_pmic_data *pmic_data) {}
255#endif
256#endif
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