diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap-mpuss-lowpower.c')
-rw-r--r-- | arch/arm/mach-omap2/omap-mpuss-lowpower.c | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index e80327b6c81f..f993a4188701 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c | |||
@@ -71,10 +71,43 @@ struct omap4_cpu_pm_info { | |||
71 | void (*secondary_startup)(void); | 71 | void (*secondary_startup)(void); |
72 | }; | 72 | }; |
73 | 73 | ||
74 | /** | ||
75 | * struct cpu_pm_ops - CPU pm operations | ||
76 | * @finish_suspend: CPU suspend finisher function pointer | ||
77 | * @resume: CPU resume function pointer | ||
78 | * @scu_prepare: CPU Snoop Control program function pointer | ||
79 | * | ||
80 | * Structure holds functions pointer for CPU low power operations like | ||
81 | * suspend, resume and scu programming. | ||
82 | */ | ||
83 | struct cpu_pm_ops { | ||
84 | int (*finish_suspend)(unsigned long cpu_state); | ||
85 | void (*resume)(void); | ||
86 | void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state); | ||
87 | }; | ||
88 | |||
74 | static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); | 89 | static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); |
75 | static struct powerdomain *mpuss_pd; | 90 | static struct powerdomain *mpuss_pd; |
76 | static void __iomem *sar_base; | 91 | static void __iomem *sar_base; |
77 | 92 | ||
93 | static int default_finish_suspend(unsigned long cpu_state) | ||
94 | { | ||
95 | omap_do_wfi(); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static void dummy_cpu_resume(void) | ||
100 | {} | ||
101 | |||
102 | static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state) | ||
103 | {} | ||
104 | |||
105 | struct cpu_pm_ops omap_pm_ops = { | ||
106 | .finish_suspend = default_finish_suspend, | ||
107 | .resume = dummy_cpu_resume, | ||
108 | .scu_prepare = dummy_scu_prepare, | ||
109 | }; | ||
110 | |||
78 | /* | 111 | /* |
79 | * Program the wakeup routine address for the CPU0 and CPU1 | 112 | * Program the wakeup routine address for the CPU0 and CPU1 |
80 | * used for OFF or DORMANT wakeup. | 113 | * used for OFF or DORMANT wakeup. |
@@ -158,11 +191,12 @@ static void save_l2x0_context(void) | |||
158 | { | 191 | { |
159 | u32 val; | 192 | u32 val; |
160 | void __iomem *l2x0_base = omap4_get_l2cache_base(); | 193 | void __iomem *l2x0_base = omap4_get_l2cache_base(); |
161 | 194 | if (l2x0_base) { | |
162 | val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); | 195 | val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); |
163 | __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); | 196 | __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); |
164 | val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); | 197 | val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); |
165 | __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); | 198 | __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); |
199 | } | ||
166 | } | 200 | } |
167 | #else | 201 | #else |
168 | static void save_l2x0_context(void) | 202 | static void save_l2x0_context(void) |
@@ -225,14 +259,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | |||
225 | 259 | ||
226 | cpu_clear_prev_logic_pwrst(cpu); | 260 | cpu_clear_prev_logic_pwrst(cpu); |
227 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); | 261 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); |
228 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); | 262 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume)); |
229 | scu_pwrst_prepare(cpu, power_state); | 263 | omap_pm_ops.scu_prepare(cpu, power_state); |
230 | l2x0_pwrst_prepare(cpu, save_state); | 264 | l2x0_pwrst_prepare(cpu, save_state); |
231 | 265 | ||
232 | /* | 266 | /* |
233 | * Call low level function with targeted low power state. | 267 | * Call low level function with targeted low power state. |
234 | */ | 268 | */ |
235 | cpu_suspend(save_state, omap4_finish_suspend); | 269 | if (save_state) |
270 | cpu_suspend(save_state, omap_pm_ops.finish_suspend); | ||
271 | else | ||
272 | omap_pm_ops.finish_suspend(save_state); | ||
236 | 273 | ||
237 | /* | 274 | /* |
238 | * Restore the CPUx power state to ON otherwise CPUx | 275 | * Restore the CPUx power state to ON otherwise CPUx |
@@ -268,14 +305,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) | |||
268 | pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); | 305 | pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); |
269 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); | 306 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); |
270 | set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); | 307 | set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup)); |
271 | scu_pwrst_prepare(cpu, power_state); | 308 | omap_pm_ops.scu_prepare(cpu, power_state); |
272 | 309 | ||
273 | /* | 310 | /* |
274 | * CPU never retuns back if targeted power state is OFF mode. | 311 | * CPU never retuns back if targeted power state is OFF mode. |
275 | * CPU ONLINE follows normal CPU ONLINE ptah via | 312 | * CPU ONLINE follows normal CPU ONLINE ptah via |
276 | * omap_secondary_startup(). | 313 | * omap4_secondary_startup(). |
277 | */ | 314 | */ |
278 | omap4_finish_suspend(cpu_state); | 315 | omap_pm_ops.finish_suspend(cpu_state); |
279 | 316 | ||
280 | pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); | 317 | pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); |
281 | return 0; | 318 | return 0; |
@@ -319,9 +356,9 @@ int __init omap4_mpuss_init(void) | |||
319 | pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; | 356 | pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; |
320 | pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; | 357 | pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; |
321 | if (cpu_is_omap446x()) | 358 | if (cpu_is_omap446x()) |
322 | pm_info->secondary_startup = omap_secondary_startup_4460; | 359 | pm_info->secondary_startup = omap4460_secondary_startup; |
323 | else | 360 | else |
324 | pm_info->secondary_startup = omap_secondary_startup; | 361 | pm_info->secondary_startup = omap4_secondary_startup; |
325 | 362 | ||
326 | pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); | 363 | pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); |
327 | if (!pm_info->pwrdm) { | 364 | if (!pm_info->pwrdm) { |
@@ -352,6 +389,12 @@ int __init omap4_mpuss_init(void) | |||
352 | 389 | ||
353 | save_l2x0_context(); | 390 | save_l2x0_context(); |
354 | 391 | ||
392 | if (cpu_is_omap44xx()) { | ||
393 | omap_pm_ops.finish_suspend = omap4_finish_suspend; | ||
394 | omap_pm_ops.resume = omap4_cpu_resume; | ||
395 | omap_pm_ops.scu_prepare = scu_pwrst_prepare; | ||
396 | } | ||
397 | |||
355 | return 0; | 398 | return 0; |
356 | } | 399 | } |
357 | 400 | ||