aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-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/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
15 files changed, 242 insertions, 59 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 eb04b6248e48..481c3e96ad7f 100644
--- a/arch/arm/mach-imx/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
@@ -147,6 +147,7 @@ DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
147 .handle_irq = imx53_handle_irq, 147 .handle_irq = imx53_handle_irq,
148 .timer = &imx53_timer, 148 .timer = &imx53_timer,
149 .init_machine = imx53_dt_init, 149 .init_machine = imx53_dt_init,
150 .init_late = imx53_init_late,
150 .dt_compat = imx53_dt_board_compat, 151 .dt_compat = imx53_dt_board_compat,
151 .restart = mxc_restart, 152 .restart = mxc_restart,
152MACHINE_END 153MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index b47e98b7d539..d4ca2c470142 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/pinctrl/machine.h> 26#include <linux/pinctrl/machine.h>
25#include <linux/phy.h> 27#include <linux/phy.h>
26#include <linux/micrel_phy.h> 28#include <linux/micrel_phy.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;
@@ -129,6 +134,19 @@ static void __init imx6q_init_machine(void)
129 imx6q_pm_init(); 134 imx6q_pm_init();
130} 135}
131 136
137static struct cpuidle_driver imx6q_cpuidle_driver = {
138 .name = "imx6q_cpuidle",
139 .owner = THIS_MODULE,
140 .en_core_tk_irqen = 1,
141 .states[0] = ARM_CPUIDLE_WFI_STATE,
142 .state_count = 1,
143};
144
145static void __init imx6q_init_late(void)
146{
147 imx_cpuidle_init(&imx6q_cpuidle_driver);
148}
149
132static void __init imx6q_map_io(void) 150static void __init imx6q_map_io(void)
133{ 151{
134 imx_lluart_map_io(); 152 imx_lluart_map_io();
@@ -186,6 +204,7 @@ DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)")
186 .handle_irq = imx6q_handle_irq, 204 .handle_irq = imx6q_handle_irq,
187 .timer = &imx6q_timer, 205 .timer = &imx6q_timer,
188 .init_machine = imx6q_init_machine, 206 .init_machine = imx6q_init_machine,
207 .init_late = imx6q_init_late,
189 .dt_compat = imx6q_dt_compat, 208 .dt_compat = imx6q_dt_compat,
190 .restart = imx6q_restart, 209 .restart = imx6q_restart,
191MACHINE_END 210MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx53_ard.c b/arch/arm/mach-imx/mach-mx53_ard.c
index 05641980dc5e..f1e83d6d2dfc 100644
--- a/arch/arm/mach-imx/mach-mx53_ard.c
+++ b/arch/arm/mach-imx/mach-mx53_ard.c
@@ -266,5 +266,6 @@ MACHINE_START(MX53_ARD, "Freescale MX53 ARD Board")
266 .handle_irq = imx53_handle_irq, 266 .handle_irq = imx53_handle_irq,
267 .timer = &mx53_ard_timer, 267 .timer = &mx53_ard_timer,
268 .init_machine = mx53_ard_board_init, 268 .init_machine = mx53_ard_board_init,
269 .init_late = imx53_init_late,
269 .restart = mxc_restart, 270 .restart = mxc_restart,
270MACHINE_END 271MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx53_evk.c b/arch/arm/mach-imx/mach-mx53_evk.c
index 5a72188b9cdb..8387496ef5ec 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 37f67cac15a4..e266f3f0f080 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 8e972c5c3e13..4f4c1b93ea66 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/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 e429ca1b814a..7ca15044154f 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);
@@ -95,7 +96,6 @@ enum mx3_cpu_pwr_mode {
95}; 96};
96 97
97extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); 98extern void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode);
98extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
99extern void imx_print_silicon_rev(const char *cpu, int srev); 99extern void imx_print_silicon_rev(const char *cpu, int srev);
100 100
101void avic_handle_irq(struct pt_regs *); 101void avic_handle_irq(struct pt_regs *);
@@ -146,8 +146,12 @@ extern void imx6q_clock_map_io(void);
146 146
147#ifdef CONFIG_PM 147#ifdef CONFIG_PM
148extern void imx6q_pm_init(void); 148extern void imx6q_pm_init(void);
149extern void imx51_pm_init(void);
150extern void imx53_pm_init(void);
149#else 151#else
150static inline void imx6q_pm_init(void) {} 152static inline void imx6q_pm_init(void) {}
153static inline void imx51_pm_init(void) {}
154static inline void imx53_pm_init(void) {}
151#endif 155#endif
152 156
153#ifdef CONFIG_NEON 157#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 0630513554de..071afd0b9283 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 98308ec1f321..a45dbea5e176 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -190,6 +190,10 @@ void __init tzic_init_irq(void __iomem *irqbase)
190 * tzic_enable_wake() - enable wakeup interrupt 190 * tzic_enable_wake() - enable wakeup interrupt
191 * 191 *
192 * @return 0 if successful; non-zero otherwise 192 * @return 0 if successful; non-zero otherwise
193 *
194 * This function provides an interrupt synchronization point that is required
195 * by tzic enabled platforms before entering imx specific low power modes (ie,
196 * those low power modes beyond the WAIT_CLOCKED basic ARM WFI only mode).
193 */ 197 */
194int tzic_enable_wake(void) 198int tzic_enable_wake(void)
195{ 199{