aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-09-23 20:29:28 -0400
committerTony Lindgren <tony@atomide.com>2010-09-23 20:29:28 -0400
commit172c11351576cf5daa8f1b02a265bf84de8bbed1 (patch)
tree5bd75dc35bfced691abdef92bde861ca246b4321
parent9af2ebbd09e01bd2711617dcafce5f608cace6ec (diff)
parent0aed043517ad4135cb458a46e9e99e21cbb59c69 (diff)
Merge branch 'pm-next' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/clockdomain.c110
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c58
-rw-r--r--arch/arm/mach-omap2/io.c7
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c482
-rw-r--r--arch/arm/mach-omap2/pm-debug.c42
-rw-r--r--arch/arm/mach-omap2/pm.c75
-rw-r--r--arch/arm/mach-omap2/pm.h4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c99
-rw-r--r--arch/arm/plat-omap/Makefile2
-rw-r--r--arch/arm/plat-omap/gpio.c6
-rw-r--r--arch/arm/plat-omap/include/plat/common.h3
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h4
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h1
-rw-r--r--arch/arm/plat-omap/omap_device.c32
15 files changed, 696 insertions, 230 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index eb2504a300c2..826cb0980054 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_ARCH_OMAP2430) += opp2430_data.o
87obj-$(CONFIG_ARCH_OMAP2420) += omap_hwmod_2420_data.o 87obj-$(CONFIG_ARCH_OMAP2420) += omap_hwmod_2420_data.o
88obj-$(CONFIG_ARCH_OMAP2430) += omap_hwmod_2430_data.o 88obj-$(CONFIG_ARCH_OMAP2430) += omap_hwmod_2430_data.o
89obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o 89obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o
90obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
90 91
91# EMU peripherals 92# EMU peripherals
92obj-$(CONFIG_OMAP3_EMU) += emu.o 93obj-$(CONFIG_OMAP3_EMU) += emu.o
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 5d80cb897489..6fb61b1a0d46 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -258,97 +258,6 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
258 258
259} 259}
260 260
261/**
262 * _init_wkdep_usecount - initialize wkdep usecounts to match hardware
263 * @clkdm: clockdomain to initialize wkdep usecounts
264 *
265 * Initialize the wakeup dependency usecount variables for clockdomain @clkdm.
266 * If a wakeup dependency is present in the hardware, the usecount will be
267 * set to 1; otherwise, it will be set to 0. Software should clear all
268 * software wakeup dependencies prior to calling this function if it wishes
269 * to ensure that all usecounts start at 0. No return value.
270 */
271static void _init_wkdep_usecount(struct clockdomain *clkdm)
272{
273 u32 v;
274 struct clkdm_dep *cd;
275
276 if (!clkdm->wkdep_srcs)
277 return;
278
279 for (cd = clkdm->wkdep_srcs; cd->clkdm_name; cd++) {
280 if (!omap_chip_is(cd->omap_chip))
281 continue;
282
283 if (!cd->clkdm && cd->clkdm_name)
284 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
285
286 if (!cd->clkdm) {
287 WARN(!cd->clkdm, "clockdomain: %s: wkdep clkdm %s not "
288 "found\n", clkdm->name, cd->clkdm_name);
289 continue;
290 }
291
292 v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
293 PM_WKDEP,
294 (1 << cd->clkdm->dep_bit));
295
296 if (v)
297 pr_debug("clockdomain: %s: wakeup dependency already "
298 "set to wake up when %s wakes\n",
299 clkdm->name, cd->clkdm->name);
300
301 atomic_set(&cd->wkdep_usecount, (v) ? 1 : 0);
302 }
303}
304
305/**
306 * _init_sleepdep_usecount - initialize sleepdep usecounts to match hardware
307 * @clkdm: clockdomain to initialize sleepdep usecounts
308 *
309 * Initialize the sleep dependency usecount variables for clockdomain @clkdm.
310 * If a sleep dependency is present in the hardware, the usecount will be
311 * set to 1; otherwise, it will be set to 0. Software should clear all
312 * software sleep dependencies prior to calling this function if it wishes
313 * to ensure that all usecounts start at 0. No return value.
314 */
315static void _init_sleepdep_usecount(struct clockdomain *clkdm)
316{
317 u32 v;
318 struct clkdm_dep *cd;
319
320 if (!cpu_is_omap34xx())
321 return;
322
323 if (!clkdm->sleepdep_srcs)
324 return;
325
326 for (cd = clkdm->sleepdep_srcs; cd->clkdm_name; cd++) {
327 if (!omap_chip_is(cd->omap_chip))
328 continue;
329
330 if (!cd->clkdm && cd->clkdm_name)
331 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
332
333 if (!cd->clkdm) {
334 WARN(!cd->clkdm, "clockdomain: %s: sleepdep clkdm %s "
335 "not found\n", clkdm->name, cd->clkdm_name);
336 continue;
337 }
338
339 v = prm_read_mod_bits_shift(clkdm->pwrdm.ptr->prcm_offs,
340 OMAP3430_CM_SLEEPDEP,
341 (1 << cd->clkdm->dep_bit));
342
343 if (v)
344 pr_debug("clockdomain: %s: sleep dependency already "
345 "set to prevent from idling until %s "
346 "idles\n", clkdm->name, cd->clkdm->name);
347
348 atomic_set(&cd->sleepdep_usecount, (v) ? 1 : 0);
349 }
350};
351
352/* Public functions */ 261/* Public functions */
353 262
354/** 263/**
@@ -379,12 +288,17 @@ void clkdm_init(struct clockdomain **clkdms,
379 _autodep_lookup(autodep); 288 _autodep_lookup(autodep);
380 289
381 /* 290 /*
382 * Ensure that the *dep_usecount registers reflect the current 291 * Put all clockdomains into software-supervised mode; PM code
383 * state of the PRCM. 292 * should later enable hardware-supervised mode as appropriate
384 */ 293 */
385 list_for_each_entry(clkdm, &clkdm_list, node) { 294 list_for_each_entry(clkdm, &clkdm_list, node) {
386 _init_wkdep_usecount(clkdm); 295 if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
387 _init_sleepdep_usecount(clkdm); 296 omap2_clkdm_wakeup(clkdm);
297 else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
298 omap2_clkdm_deny_idle(clkdm);
299
300 clkdm_clear_all_wkdeps(clkdm);
301 clkdm_clear_all_sleepdeps(clkdm);
388 } 302 }
389} 303}
390 304
@@ -592,6 +506,9 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
592 if (!omap_chip_is(cd->omap_chip)) 506 if (!omap_chip_is(cd->omap_chip))
593 continue; 507 continue;
594 508
509 if (!cd->clkdm && cd->clkdm_name)
510 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
511
595 /* PRM accesses are slow, so minimize them */ 512 /* PRM accesses are slow, so minimize them */
596 mask |= 1 << cd->clkdm->dep_bit; 513 mask |= 1 << cd->clkdm->dep_bit;
597 atomic_set(&cd->wkdep_usecount, 0); 514 atomic_set(&cd->wkdep_usecount, 0);
@@ -752,6 +669,9 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
752 if (!omap_chip_is(cd->omap_chip)) 669 if (!omap_chip_is(cd->omap_chip))
753 continue; 670 continue;
754 671
672 if (!cd->clkdm && cd->clkdm_name)
673 cd->clkdm = _clkdm_lookup(cd->clkdm_name);
674
755 /* PRM accesses are slow, so minimize them */ 675 /* PRM accesses are slow, so minimize them */
756 mask |= 1 << cd->clkdm->dep_bit; 676 mask |= 1 << cd->clkdm->dep_bit;
757 atomic_set(&cd->sleepdep_usecount, 0); 677 atomic_set(&cd->sleepdep_usecount, 0);
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 3d3d035db9af..8ea012ef0b5a 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -60,7 +60,8 @@ struct omap3_processor_cx {
60 60
61struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES]; 61struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
62struct omap3_processor_cx current_cx_state; 62struct omap3_processor_cx current_cx_state;
63struct powerdomain *mpu_pd, *core_pd; 63struct powerdomain *mpu_pd, *core_pd, *per_pd;
64struct powerdomain *cam_pd;
64 65
65/* 66/*
66 * The latencies/thresholds for various C states have 67 * The latencies/thresholds for various C states have
@@ -233,14 +234,62 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
233 struct cpuidle_state *state) 234 struct cpuidle_state *state)
234{ 235{
235 struct cpuidle_state *new_state = next_valid_state(dev, state); 236 struct cpuidle_state *new_state = next_valid_state(dev, state);
237 u32 core_next_state, per_next_state = 0, per_saved_state = 0;
238 u32 cam_state;
239 struct omap3_processor_cx *cx;
240 int ret;
236 241
237 if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) { 242 if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
238 BUG_ON(!dev->safe_state); 243 BUG_ON(!dev->safe_state);
239 new_state = dev->safe_state; 244 new_state = dev->safe_state;
245 goto select_state;
246 }
247
248 cx = cpuidle_get_statedata(state);
249 core_next_state = cx->core_state;
250
251 /*
252 * FIXME: we currently manage device-specific idle states
253 * for PER and CORE in combination with CPU-specific
254 * idle states. This is wrong, and device-specific
255 * idle managment needs to be separated out into
256 * its own code.
257 */
258
259 /*
260 * Prevent idle completely if CAM is active.
261 * CAM does not have wakeup capability in OMAP3.
262 */
263 cam_state = pwrdm_read_pwrst(cam_pd);
264 if (cam_state == PWRDM_POWER_ON) {
265 new_state = dev->safe_state;
266 goto select_state;
267 }
268
269 /*
270 * Prevent PER off if CORE is not in retention or off as this
271 * would disable PER wakeups completely.
272 */
273 per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
274 if ((per_next_state == PWRDM_POWER_OFF) &&
275 (core_next_state > PWRDM_POWER_RET)) {
276 per_next_state = PWRDM_POWER_RET;
277 pwrdm_set_next_pwrst(per_pd, per_next_state);
240 } 278 }
241 279
280 /* Are we changing PER target state? */
281 if (per_next_state != per_saved_state)
282 pwrdm_set_next_pwrst(per_pd, per_next_state);
283
284select_state:
242 dev->last_state = new_state; 285 dev->last_state = new_state;
243 return omap3_enter_idle(dev, new_state); 286 ret = omap3_enter_idle(dev, new_state);
287
288 /* Restore original PER state if it was modified */
289 if (per_next_state != per_saved_state)
290 pwrdm_set_next_pwrst(per_pd, per_saved_state);
291
292 return ret;
244} 293}
245 294
246DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); 295DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
@@ -328,7 +377,8 @@ void omap_init_power_states(void)
328 cpuidle_params_table[OMAP3_STATE_C2].threshold; 377 cpuidle_params_table[OMAP3_STATE_C2].threshold;
329 omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON; 378 omap3_power_states[OMAP3_STATE_C2].mpu_state = PWRDM_POWER_ON;
330 omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON; 379 omap3_power_states[OMAP3_STATE_C2].core_state = PWRDM_POWER_ON;
331 omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID; 380 omap3_power_states[OMAP3_STATE_C2].flags = CPUIDLE_FLAG_TIME_VALID |
381 CPUIDLE_FLAG_CHECK_BM;
332 382
333 /* C3 . MPU CSWR + Core inactive */ 383 /* C3 . MPU CSWR + Core inactive */
334 omap3_power_states[OMAP3_STATE_C3].valid = 384 omap3_power_states[OMAP3_STATE_C3].valid =
@@ -426,6 +476,8 @@ int __init omap3_idle_init(void)
426 476
427 mpu_pd = pwrdm_lookup("mpu_pwrdm"); 477 mpu_pd = pwrdm_lookup("mpu_pwrdm");
428 core_pd = pwrdm_lookup("core_pwrdm"); 478 core_pd = pwrdm_lookup("core_pwrdm");
479 per_pd = pwrdm_lookup("per_pwrdm");
480 cam_pd = pwrdm_lookup("cam_pwrdm");
429 481
430 omap_init_power_states(); 482 omap_init_power_states();
431 cpuidle_register_driver(&omap3_idle_driver); 483 cpuidle_register_driver(&omap3_idle_driver);
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index b9ea70bce563..490d87082fad 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -323,6 +323,9 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
323 omap2430_hwmod_init(); 323 omap2430_hwmod_init();
324 else if (cpu_is_omap34xx()) 324 else if (cpu_is_omap34xx())
325 omap3xxx_hwmod_init(); 325 omap3xxx_hwmod_init();
326 else if (cpu_is_omap44xx())
327 omap44xx_hwmod_init();
328
326 /* The OPP tables have to be registered before a clk init */ 329 /* The OPP tables have to be registered before a clk init */
327 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps); 330 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
328 331
@@ -342,9 +345,7 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
342#ifndef CONFIG_PM_RUNTIME 345#ifndef CONFIG_PM_RUNTIME
343 skip_setup_idle = 1; 346 skip_setup_idle = 1;
344#endif 347#endif
345 if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */ 348 omap_hwmod_late_init(skip_setup_idle);
346 omap_hwmod_late_init(skip_setup_idle);
347
348 if (cpu_is_omap24xx() || cpu_is_omap34xx()) { 349 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
349 omap2_sdrc_init(sdrc_cs0, sdrc_cs1); 350 omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
350 _omap2_init_reprogram_sdrc(); 351 _omap2_init_reprogram_sdrc();
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
new file mode 100644
index 000000000000..e20b0eebc6d9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -0,0 +1,482 @@
1/*
2 * Hardware modules present on the OMAP44xx chips
3 *
4 * Copyright (C) 2009-2010 Texas Instruments, Inc.
5 * Copyright (C) 2009-2010 Nokia Corporation
6 *
7 * Paul Walmsley
8 * Benoit Cousson
9 *
10 * This file is automatically generated from the OMAP hardware databases.
11 * We respectfully ask that any modifications to this file be coordinated
12 * with the public linux-omap@vger.kernel.org mailing list and the
13 * authors above to ensure that the autogeneration scripts are kept
14 * up-to-date with the file contents.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21#include <linux/io.h>
22
23#include <plat/omap_hwmod.h>
24#include <plat/cpu.h>
25
26#include "omap_hwmod_common_data.h"
27
28#include "cm.h"
29#include "prm-regbits-44xx.h"
30
31/* Base offset for all OMAP4 interrupts external to MPUSS */
32#define OMAP44XX_IRQ_GIC_START 32
33
34/* Base offset for all OMAP4 dma requests */
35#define OMAP44XX_DMA_REQ_START 1
36
37/* Backward references (IPs with Bus Master capability) */
38static struct omap_hwmod omap44xx_dmm_hwmod;
39static struct omap_hwmod omap44xx_emif_fw_hwmod;
40static struct omap_hwmod omap44xx_l3_instr_hwmod;
41static struct omap_hwmod omap44xx_l3_main_1_hwmod;
42static struct omap_hwmod omap44xx_l3_main_2_hwmod;
43static struct omap_hwmod omap44xx_l3_main_3_hwmod;
44static struct omap_hwmod omap44xx_l4_abe_hwmod;
45static struct omap_hwmod omap44xx_l4_cfg_hwmod;
46static struct omap_hwmod omap44xx_l4_per_hwmod;
47static struct omap_hwmod omap44xx_l4_wkup_hwmod;
48static struct omap_hwmod omap44xx_mpu_hwmod;
49static struct omap_hwmod omap44xx_mpu_private_hwmod;
50
51/*
52 * Interconnects omap_hwmod structures
53 * hwmods that compose the global OMAP interconnect
54 */
55
56/*
57 * 'dmm' class
58 * instance(s): dmm
59 */
60static struct omap_hwmod_class omap44xx_dmm_hwmod_class = {
61 .name = "dmm",
62};
63
64/* dmm interface data */
65/* l3_main_1 -> dmm */
66static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = {
67 .master = &omap44xx_l3_main_1_hwmod,
68 .slave = &omap44xx_dmm_hwmod,
69 .clk = "l3_div_ck",
70 .user = OCP_USER_MPU | OCP_USER_SDMA,
71};
72
73/* mpu -> dmm */
74static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = {
75 .master = &omap44xx_mpu_hwmod,
76 .slave = &omap44xx_dmm_hwmod,
77 .clk = "l3_div_ck",
78 .user = OCP_USER_MPU | OCP_USER_SDMA,
79};
80
81/* dmm slave ports */
82static struct omap_hwmod_ocp_if *omap44xx_dmm_slaves[] = {
83 &omap44xx_l3_main_1__dmm,
84 &omap44xx_mpu__dmm,
85};
86
87static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = {
88 { .irq = 113 + OMAP44XX_IRQ_GIC_START },
89};
90
91static struct omap_hwmod omap44xx_dmm_hwmod = {
92 .name = "dmm",
93 .class = &omap44xx_dmm_hwmod_class,
94 .slaves = omap44xx_dmm_slaves,
95 .slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
96 .mpu_irqs = omap44xx_dmm_irqs,
97 .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmm_irqs),
98 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
99};
100
101/*
102 * 'emif_fw' class
103 * instance(s): emif_fw
104 */
105static struct omap_hwmod_class omap44xx_emif_fw_hwmod_class = {
106 .name = "emif_fw",
107};
108
109/* emif_fw interface data */
110/* dmm -> emif_fw */
111static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = {
112 .master = &omap44xx_dmm_hwmod,
113 .slave = &omap44xx_emif_fw_hwmod,
114 .clk = "l3_div_ck",
115 .user = OCP_USER_MPU | OCP_USER_SDMA,
116};
117
118/* l4_cfg -> emif_fw */
119static struct omap_hwmod_ocp_if omap44xx_l4_cfg__emif_fw = {
120 .master = &omap44xx_l4_cfg_hwmod,
121 .slave = &omap44xx_emif_fw_hwmod,
122 .clk = "l4_div_ck",
123 .user = OCP_USER_MPU | OCP_USER_SDMA,
124};
125
126/* emif_fw slave ports */
127static struct omap_hwmod_ocp_if *omap44xx_emif_fw_slaves[] = {
128 &omap44xx_dmm__emif_fw,
129 &omap44xx_l4_cfg__emif_fw,
130};
131
132static struct omap_hwmod omap44xx_emif_fw_hwmod = {
133 .name = "emif_fw",
134 .class = &omap44xx_emif_fw_hwmod_class,
135 .slaves = omap44xx_emif_fw_slaves,
136 .slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves),
137 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
138};
139
140/*
141 * 'l3' class
142 * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3
143 */
144static struct omap_hwmod_class omap44xx_l3_hwmod_class = {
145 .name = "l3",
146};
147
148/* l3_instr interface data */
149/* l3_main_3 -> l3_instr */
150static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = {
151 .master = &omap44xx_l3_main_3_hwmod,
152 .slave = &omap44xx_l3_instr_hwmod,
153 .clk = "l3_div_ck",
154 .user = OCP_USER_MPU | OCP_USER_SDMA,
155};
156
157/* l3_instr slave ports */
158static struct omap_hwmod_ocp_if *omap44xx_l3_instr_slaves[] = {
159 &omap44xx_l3_main_3__l3_instr,
160};
161
162static struct omap_hwmod omap44xx_l3_instr_hwmod = {
163 .name = "l3_instr",
164 .class = &omap44xx_l3_hwmod_class,
165 .slaves = omap44xx_l3_instr_slaves,
166 .slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves),
167 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
168};
169
170/* l3_main_2 -> l3_main_1 */
171static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = {
172 .master = &omap44xx_l3_main_2_hwmod,
173 .slave = &omap44xx_l3_main_1_hwmod,
174 .clk = "l3_div_ck",
175 .user = OCP_USER_MPU | OCP_USER_SDMA,
176};
177
178/* l4_cfg -> l3_main_1 */
179static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_1 = {
180 .master = &omap44xx_l4_cfg_hwmod,
181 .slave = &omap44xx_l3_main_1_hwmod,
182 .clk = "l4_div_ck",
183 .user = OCP_USER_MPU | OCP_USER_SDMA,
184};
185
186/* mpu -> l3_main_1 */
187static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = {
188 .master = &omap44xx_mpu_hwmod,
189 .slave = &omap44xx_l3_main_1_hwmod,
190 .clk = "l3_div_ck",
191 .user = OCP_USER_MPU | OCP_USER_SDMA,
192};
193
194/* l3_main_1 slave ports */
195static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = {
196 &omap44xx_l3_main_2__l3_main_1,
197 &omap44xx_l4_cfg__l3_main_1,
198 &omap44xx_mpu__l3_main_1,
199};
200
201static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
202 .name = "l3_main_1",
203 .class = &omap44xx_l3_hwmod_class,
204 .slaves = omap44xx_l3_main_1_slaves,
205 .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
206 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
207};
208
209/* l3_main_2 interface data */
210/* l3_main_1 -> l3_main_2 */
211static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
212 .master = &omap44xx_l3_main_1_hwmod,
213 .slave = &omap44xx_l3_main_2_hwmod,
214 .clk = "l3_div_ck",
215 .user = OCP_USER_MPU | OCP_USER_SDMA,
216};
217
218/* l4_cfg -> l3_main_2 */
219static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = {
220 .master = &omap44xx_l4_cfg_hwmod,
221 .slave = &omap44xx_l3_main_2_hwmod,
222 .clk = "l4_div_ck",
223 .user = OCP_USER_MPU | OCP_USER_SDMA,
224};
225
226/* l3_main_2 slave ports */
227static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = {
228 &omap44xx_l3_main_1__l3_main_2,
229 &omap44xx_l4_cfg__l3_main_2,
230};
231
232static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
233 .name = "l3_main_2",
234 .class = &omap44xx_l3_hwmod_class,
235 .slaves = omap44xx_l3_main_2_slaves,
236 .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves),
237 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
238};
239
240/* l3_main_3 interface data */
241/* l3_main_1 -> l3_main_3 */
242static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = {
243 .master = &omap44xx_l3_main_1_hwmod,
244 .slave = &omap44xx_l3_main_3_hwmod,
245 .clk = "l3_div_ck",
246 .user = OCP_USER_MPU | OCP_USER_SDMA,
247};
248
249/* l3_main_2 -> l3_main_3 */
250static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_3 = {
251 .master = &omap44xx_l3_main_2_hwmod,
252 .slave = &omap44xx_l3_main_3_hwmod,
253 .clk = "l3_div_ck",
254 .user = OCP_USER_MPU | OCP_USER_SDMA,
255};
256
257/* l4_cfg -> l3_main_3 */
258static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = {
259 .master = &omap44xx_l4_cfg_hwmod,
260 .slave = &omap44xx_l3_main_3_hwmod,
261 .clk = "l4_div_ck",
262 .user = OCP_USER_MPU | OCP_USER_SDMA,
263};
264
265/* l3_main_3 slave ports */
266static struct omap_hwmod_ocp_if *omap44xx_l3_main_3_slaves[] = {
267 &omap44xx_l3_main_1__l3_main_3,
268 &omap44xx_l3_main_2__l3_main_3,
269 &omap44xx_l4_cfg__l3_main_3,
270};
271
272static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
273 .name = "l3_main_3",
274 .class = &omap44xx_l3_hwmod_class,
275 .slaves = omap44xx_l3_main_3_slaves,
276 .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves),
277 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
278};
279
280/*
281 * 'l4' class
282 * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup
283 */
284static struct omap_hwmod_class omap44xx_l4_hwmod_class = {
285 .name = "l4",
286};
287
288/* l4_abe interface data */
289/* l3_main_1 -> l4_abe */
290static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = {
291 .master = &omap44xx_l3_main_1_hwmod,
292 .slave = &omap44xx_l4_abe_hwmod,
293 .clk = "l3_div_ck",
294 .user = OCP_USER_MPU | OCP_USER_SDMA,
295};
296
297/* mpu -> l4_abe */
298static struct omap_hwmod_ocp_if omap44xx_mpu__l4_abe = {
299 .master = &omap44xx_mpu_hwmod,
300 .slave = &omap44xx_l4_abe_hwmod,
301 .clk = "ocp_abe_iclk",
302 .user = OCP_USER_MPU | OCP_USER_SDMA,
303};
304
305/* l4_abe slave ports */
306static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = {
307 &omap44xx_l3_main_1__l4_abe,
308 &omap44xx_mpu__l4_abe,
309};
310
311static struct omap_hwmod omap44xx_l4_abe_hwmod = {
312 .name = "l4_abe",
313 .class = &omap44xx_l4_hwmod_class,
314 .slaves = omap44xx_l4_abe_slaves,
315 .slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves),
316 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
317};
318
319/* l4_cfg interface data */
320/* l3_main_1 -> l4_cfg */
321static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_cfg = {
322 .master = &omap44xx_l3_main_1_hwmod,
323 .slave = &omap44xx_l4_cfg_hwmod,
324 .clk = "l3_div_ck",
325 .user = OCP_USER_MPU | OCP_USER_SDMA,
326};
327
328/* l4_cfg slave ports */
329static struct omap_hwmod_ocp_if *omap44xx_l4_cfg_slaves[] = {
330 &omap44xx_l3_main_1__l4_cfg,
331};
332
333static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
334 .name = "l4_cfg",
335 .class = &omap44xx_l4_hwmod_class,
336 .slaves = omap44xx_l4_cfg_slaves,
337 .slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves),
338 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
339};
340
341/* l4_per interface data */
342/* l3_main_2 -> l4_per */
343static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l4_per = {
344 .master = &omap44xx_l3_main_2_hwmod,
345 .slave = &omap44xx_l4_per_hwmod,
346 .clk = "l3_div_ck",
347 .user = OCP_USER_MPU | OCP_USER_SDMA,
348};
349
350/* l4_per slave ports */
351static struct omap_hwmod_ocp_if *omap44xx_l4_per_slaves[] = {
352 &omap44xx_l3_main_2__l4_per,
353};
354
355static struct omap_hwmod omap44xx_l4_per_hwmod = {
356 .name = "l4_per",
357 .class = &omap44xx_l4_hwmod_class,
358 .slaves = omap44xx_l4_per_slaves,
359 .slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves),
360 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
361};
362
363/* l4_wkup interface data */
364/* l4_cfg -> l4_wkup */
365static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l4_wkup = {
366 .master = &omap44xx_l4_cfg_hwmod,
367 .slave = &omap44xx_l4_wkup_hwmod,
368 .clk = "l4_div_ck",
369 .user = OCP_USER_MPU | OCP_USER_SDMA,
370};
371
372/* l4_wkup slave ports */
373static struct omap_hwmod_ocp_if *omap44xx_l4_wkup_slaves[] = {
374 &omap44xx_l4_cfg__l4_wkup,
375};
376
377static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
378 .name = "l4_wkup",
379 .class = &omap44xx_l4_hwmod_class,
380 .slaves = omap44xx_l4_wkup_slaves,
381 .slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves),
382 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
383};
384
385/*
386 * 'mpu_bus' class
387 * instance(s): mpu_private
388 */
389static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = {
390 .name = "mpu_bus",
391};
392
393/* mpu_private interface data */
394/* mpu -> mpu_private */
395static struct omap_hwmod_ocp_if omap44xx_mpu__mpu_private = {
396 .master = &omap44xx_mpu_hwmod,
397 .slave = &omap44xx_mpu_private_hwmod,
398 .clk = "l3_div_ck",
399 .user = OCP_USER_MPU | OCP_USER_SDMA,
400};
401
402/* mpu_private slave ports */
403static struct omap_hwmod_ocp_if *omap44xx_mpu_private_slaves[] = {
404 &omap44xx_mpu__mpu_private,
405};
406
407static struct omap_hwmod omap44xx_mpu_private_hwmod = {
408 .name = "mpu_private",
409 .class = &omap44xx_mpu_bus_hwmod_class,
410 .slaves = omap44xx_mpu_private_slaves,
411 .slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves),
412 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
413};
414
415/*
416 * 'mpu' class
417 * mpu sub-system
418 */
419
420static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
421 .name = "mpu",
422};
423
424/* mpu */
425static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
426 { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
427 { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
428 { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
429};
430
431/* mpu master ports */
432static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = {
433 &omap44xx_mpu__l3_main_1,
434 &omap44xx_mpu__l4_abe,
435 &omap44xx_mpu__dmm,
436};
437
438static struct omap_hwmod omap44xx_mpu_hwmod = {
439 .name = "mpu",
440 .class = &omap44xx_mpu_hwmod_class,
441 .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
442 .mpu_irqs = omap44xx_mpu_irqs,
443 .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs),
444 .main_clk = "dpll_mpu_m2_ck",
445 .prcm = {
446 .omap4 = {
447 .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL,
448 },
449 },
450 .masters = omap44xx_mpu_masters,
451 .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters),
452 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
453};
454
455static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
456 /* dmm class */
457 &omap44xx_dmm_hwmod,
458 /* emif_fw class */
459 &omap44xx_emif_fw_hwmod,
460 /* l3 class */
461 &omap44xx_l3_instr_hwmod,
462 &omap44xx_l3_main_1_hwmod,
463 &omap44xx_l3_main_2_hwmod,
464 &omap44xx_l3_main_3_hwmod,
465 /* l4 class */
466 &omap44xx_l4_abe_hwmod,
467 &omap44xx_l4_cfg_hwmod,
468 &omap44xx_l4_per_hwmod,
469 &omap44xx_l4_wkup_hwmod,
470 /* mpu_bus class */
471 &omap44xx_mpu_private_hwmod,
472
473 /* mpu class */
474 &omap44xx_mpu_hwmod,
475 NULL,
476};
477
478int __init omap44xx_hwmod_init(void)
479{
480 return omap_hwmod_init(omap44xx_hwmods);
481}
482
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 723b44e252fd..af00c174d7a9 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -31,12 +31,17 @@
31#include <plat/board.h> 31#include <plat/board.h>
32#include <plat/powerdomain.h> 32#include <plat/powerdomain.h>
33#include <plat/clockdomain.h> 33#include <plat/clockdomain.h>
34#include <plat/dmtimer.h>
34 35
35#include "prm.h" 36#include "prm.h"
36#include "cm.h" 37#include "cm.h"
37#include "pm.h" 38#include "pm.h"
38 39
39int omap2_pm_debug; 40int omap2_pm_debug;
41u32 enable_off_mode;
42u32 sleep_while_idle;
43u32 wakeup_timer_seconds;
44u32 wakeup_timer_milliseconds;
40 45
41#define DUMP_PRM_MOD_REG(mod, reg) \ 46#define DUMP_PRM_MOD_REG(mod, reg) \
42 regs[reg_count].name = #mod "." #reg; \ 47 regs[reg_count].name = #mod "." #reg; \
@@ -349,6 +354,23 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
349 pwrdm->timer = t; 354 pwrdm->timer = t;
350} 355}
351 356
357void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
358{
359 u32 tick_rate, cycles;
360
361 if (!seconds && !milliseconds)
362 return;
363
364 tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
365 cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
366 omap_dm_timer_stop(gptimer_wakeup);
367 omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
368
369 pr_info("PM: Resume timer in %u.%03u secs"
370 " (%d ticks at %d ticks/sec.)\n",
371 seconds, milliseconds, cycles, tick_rate);
372}
373
352static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) 374static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
353{ 375{
354 struct seq_file *s = (struct seq_file *)user; 376 struct seq_file *s = (struct seq_file *)user;
@@ -494,8 +516,10 @@ int pm_dbg_regset_init(int reg_set)
494 516
495static int pwrdm_suspend_get(void *data, u64 *val) 517static int pwrdm_suspend_get(void *data, u64 *val)
496{ 518{
497 int ret; 519 int ret = -EINVAL;
498 ret = omap3_pm_get_suspend_state((struct powerdomain *)data); 520
521 if (cpu_is_omap34xx())
522 ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
499 *val = ret; 523 *val = ret;
500 524
501 if (ret >= 0) 525 if (ret >= 0)
@@ -505,7 +529,10 @@ static int pwrdm_suspend_get(void *data, u64 *val)
505 529
506static int pwrdm_suspend_set(void *data, u64 val) 530static int pwrdm_suspend_set(void *data, u64 val)
507{ 531{
508 return omap3_pm_set_suspend_state((struct powerdomain *)data, (int)val); 532 if (cpu_is_omap34xx())
533 return omap3_pm_set_suspend_state(
534 (struct powerdomain *)data, (int)val);
535 return -EINVAL;
509} 536}
510 537
511DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get, 538DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
@@ -553,8 +580,10 @@ static int option_set(void *data, u64 val)
553 580
554 *option = val; 581 *option = val;
555 582
556 if (option == &enable_off_mode) 583 if (option == &enable_off_mode) {
557 omap3_pm_off_mode_enable(val); 584 if (cpu_is_omap34xx())
585 omap3_pm_off_mode_enable(val);
586 }
558 587
559 return 0; 588 return 0;
560} 589}
@@ -609,6 +638,9 @@ static int __init pm_dbg_init(void)
609 &sleep_while_idle, &pm_dbg_option_fops); 638 &sleep_while_idle, &pm_dbg_option_fops);
610 (void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d, 639 (void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d,
611 &wakeup_timer_seconds, &pm_dbg_option_fops); 640 &wakeup_timer_seconds, &pm_dbg_option_fops);
641 (void) debugfs_create_file("wakeup_timer_milliseconds",
642 S_IRUGO | S_IWUGO, d, &wakeup_timer_milliseconds,
643 &pm_dbg_option_fops);
612 pm_dbg_init_done = 1; 644 pm_dbg_init_done = 1;
613 645
614 return 0; 646 return 0;
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 68f9f2e95891..59ca03b0e691 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -18,11 +18,15 @@
18#include <plat/omap_device.h> 18#include <plat/omap_device.h>
19#include <plat/common.h> 19#include <plat/common.h>
20 20
21#include <plat/powerdomain.h>
22#include <plat/clockdomain.h>
23
21static struct omap_device_pm_latency *pm_lats; 24static struct omap_device_pm_latency *pm_lats;
22 25
23static struct device *mpu_dev; 26static struct device *mpu_dev;
24static struct device *dsp_dev; 27static struct device *iva_dev;
25static struct device *l3_dev; 28static struct device *l3_dev;
29static struct device *dsp_dev;
26 30
27struct device *omap2_get_mpuss_device(void) 31struct device *omap2_get_mpuss_device(void)
28{ 32{
@@ -30,10 +34,10 @@ struct device *omap2_get_mpuss_device(void)
30 return mpu_dev; 34 return mpu_dev;
31} 35}
32 36
33struct device *omap2_get_dsp_device(void) 37struct device *omap2_get_iva_device(void)
34{ 38{
35 WARN_ON_ONCE(!dsp_dev); 39 WARN_ON_ONCE(!iva_dev);
36 return dsp_dev; 40 return iva_dev;
37} 41}
38 42
39struct device *omap2_get_l3_device(void) 43struct device *omap2_get_l3_device(void)
@@ -42,6 +46,13 @@ struct device *omap2_get_l3_device(void)
42 return l3_dev; 46 return l3_dev;
43} 47}
44 48
49struct device *omap4_get_dsp_device(void)
50{
51 WARN_ON_ONCE(!dsp_dev);
52 return dsp_dev;
53}
54EXPORT_SYMBOL(omap4_get_dsp_device);
55
45/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */ 56/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
46static int _init_omap_device(char *name, struct device **new_dev) 57static int _init_omap_device(char *name, struct device **new_dev)
47{ 58{
@@ -69,8 +80,60 @@ static int _init_omap_device(char *name, struct device **new_dev)
69static void omap2_init_processor_devices(void) 80static void omap2_init_processor_devices(void)
70{ 81{
71 _init_omap_device("mpu", &mpu_dev); 82 _init_omap_device("mpu", &mpu_dev);
72 _init_omap_device("iva", &dsp_dev); 83 _init_omap_device("iva", &iva_dev);
73 _init_omap_device("l3_main", &l3_dev); 84 if (cpu_is_omap44xx()) {
85 _init_omap_device("l3_main_1", &l3_dev);
86 _init_omap_device("dsp", &dsp_dev);
87 } else {
88 _init_omap_device("l3_main", &l3_dev);
89 }
90}
91
92/*
93 * This sets pwrdm state (other than mpu & core. Currently only ON &
94 * RET are supported. Function is assuming that clkdm doesn't have
95 * hw_sup mode enabled.
96 */
97int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
98{
99 u32 cur_state;
100 int sleep_switch = 0;
101 int ret = 0;
102
103 if (pwrdm == NULL || IS_ERR(pwrdm))
104 return -EINVAL;
105
106 while (!(pwrdm->pwrsts & (1 << state))) {
107 if (state == PWRDM_POWER_OFF)
108 return ret;
109 state--;
110 }
111
112 cur_state = pwrdm_read_next_pwrst(pwrdm);
113 if (cur_state == state)
114 return ret;
115
116 if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
117 omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
118 sleep_switch = 1;
119 pwrdm_wait_transition(pwrdm);
120 }
121
122 ret = pwrdm_set_next_pwrst(pwrdm, state);
123 if (ret) {
124 printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
125 pwrdm->name);
126 goto err;
127 }
128
129 if (sleep_switch) {
130 omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
131 pwrdm_wait_transition(pwrdm);
132 pwrdm_state_switch(pwrdm);
133 }
134
135err:
136 return ret;
74} 137}
75 138
76static int __init omap2_common_pm_init(void) 139static int __init omap2_common_pm_init(void)
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 3de6ece23fc8..77770a13cea8 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -20,7 +20,7 @@ extern void *omap3_secure_ram_storage;
20extern void omap3_pm_off_mode_enable(int); 20extern void omap3_pm_off_mode_enable(int);
21extern void omap_sram_idle(void); 21extern void omap_sram_idle(void);
22extern int omap3_can_sleep(void); 22extern int omap3_can_sleep(void);
23extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state); 23extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
24extern int omap3_idle_init(void); 24extern int omap3_idle_init(void);
25 25
26struct cpuidle_params { 26struct cpuidle_params {
@@ -48,9 +48,11 @@ extern struct omap_dm_timer *gptimer_wakeup;
48 48
49#ifdef CONFIG_PM_DEBUG 49#ifdef CONFIG_PM_DEBUG
50extern void omap2_pm_dump(int mode, int resume, unsigned int us); 50extern void omap2_pm_dump(int mode, int resume, unsigned int us);
51extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds);
51extern int omap2_pm_debug; 52extern int omap2_pm_debug;
52#else 53#else
53#define omap2_pm_dump(mode, resume, us) do {} while (0); 54#define omap2_pm_dump(mode, resume, us) do {} while (0);
55#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0);
54#define omap2_pm_debug 0 56#define omap2_pm_debug 0
55#endif 57#endif
56 58
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7b03426c72a3..d2b940c7215d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -38,7 +38,6 @@
38#include <plat/prcm.h> 38#include <plat/prcm.h>
39#include <plat/gpmc.h> 39#include <plat/gpmc.h>
40#include <plat/dma.h> 40#include <plat/dma.h>
41#include <plat/dmtimer.h>
42 41
43#include <asm/tlbflush.h> 42#include <asm/tlbflush.h>
44 43
@@ -55,11 +54,6 @@
55#define OMAP343X_TABLE_VALUE_OFFSET 0x30 54#define OMAP343X_TABLE_VALUE_OFFSET 0x30
56#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32 55#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0x32
57 56
58u32 enable_off_mode;
59u32 sleep_while_idle;
60u32 wakeup_timer_seconds;
61u32 wakeup_timer_milliseconds;
62
63struct power_state { 57struct power_state {
64 struct powerdomain *pwrdm; 58 struct powerdomain *pwrdm;
65 u32 next_state; 59 u32 next_state;
@@ -351,7 +345,6 @@ void omap_sram_idle(void)
351 int core_next_state = PWRDM_POWER_ON; 345 int core_next_state = PWRDM_POWER_ON;
352 int core_prev_state, per_prev_state; 346 int core_prev_state, per_prev_state;
353 u32 sdrc_pwr = 0; 347 u32 sdrc_pwr = 0;
354 int per_state_modified = 0;
355 348
356 if (!_omap_sram_idle) 349 if (!_omap_sram_idle)
357 return; 350 return;
@@ -385,9 +378,9 @@ void omap_sram_idle(void)
385 /* Enable IO-PAD and IO-CHAIN wakeups */ 378 /* Enable IO-PAD and IO-CHAIN wakeups */
386 per_next_state = pwrdm_read_next_pwrst(per_pwrdm); 379 per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
387 core_next_state = pwrdm_read_next_pwrst(core_pwrdm); 380 core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
388 if (omap3_has_io_wakeup() && \ 381 if (omap3_has_io_wakeup() &&
389 (per_next_state < PWRDM_POWER_ON || 382 (per_next_state < PWRDM_POWER_ON ||
390 core_next_state < PWRDM_POWER_ON)) { 383 core_next_state < PWRDM_POWER_ON)) {
391 prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN); 384 prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
392 omap3_enable_io_chain(); 385 omap3_enable_io_chain();
393 } 386 }
@@ -396,19 +389,10 @@ void omap_sram_idle(void)
396 if (per_next_state < PWRDM_POWER_ON) { 389 if (per_next_state < PWRDM_POWER_ON) {
397 omap_uart_prepare_idle(2); 390 omap_uart_prepare_idle(2);
398 omap2_gpio_prepare_for_idle(per_next_state); 391 omap2_gpio_prepare_for_idle(per_next_state);
399 if (per_next_state == PWRDM_POWER_OFF) { 392 if (per_next_state == PWRDM_POWER_OFF)
400 if (core_next_state == PWRDM_POWER_ON) {
401 per_next_state = PWRDM_POWER_RET;
402 pwrdm_set_next_pwrst(per_pwrdm, per_next_state);
403 per_state_modified = 1;
404 } else
405 omap3_per_save_context(); 393 omap3_per_save_context();
406 }
407 } 394 }
408 395
409 if (pwrdm_read_pwrst(cam_pwrdm) == PWRDM_POWER_ON)
410 omap2_clkdm_deny_idle(mpu_pwrdm->pwrdm_clkdms[0]);
411
412 /* CORE */ 396 /* CORE */
413 if (core_next_state < PWRDM_POWER_ON) { 397 if (core_next_state < PWRDM_POWER_ON) {
414 omap_uart_prepare_idle(0); 398 omap_uart_prepare_idle(0);
@@ -475,8 +459,6 @@ void omap_sram_idle(void)
475 if (per_prev_state == PWRDM_POWER_OFF) 459 if (per_prev_state == PWRDM_POWER_OFF)
476 omap3_per_restore_context(); 460 omap3_per_restore_context();
477 omap_uart_resume_idle(2); 461 omap_uart_resume_idle(2);
478 if (per_state_modified)
479 pwrdm_set_next_pwrst(per_pwrdm, PWRDM_POWER_OFF);
480 } 462 }
481 463
482 /* Disable IO-PAD and IO-CHAIN wakeup */ 464 /* Disable IO-PAD and IO-CHAIN wakeup */
@@ -501,51 +483,6 @@ int omap3_can_sleep(void)
501 return 1; 483 return 1;
502} 484}
503 485
504/* This sets pwrdm state (other than mpu & core. Currently only ON &
505 * RET are supported. Function is assuming that clkdm doesn't have
506 * hw_sup mode enabled. */
507int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
508{
509 u32 cur_state;
510 int sleep_switch = 0;
511 int ret = 0;
512
513 if (pwrdm == NULL || IS_ERR(pwrdm))
514 return -EINVAL;
515
516 while (!(pwrdm->pwrsts & (1 << state))) {
517 if (state == PWRDM_POWER_OFF)
518 return ret;
519 state--;
520 }
521
522 cur_state = pwrdm_read_next_pwrst(pwrdm);
523 if (cur_state == state)
524 return ret;
525
526 if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
527 omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
528 sleep_switch = 1;
529 pwrdm_wait_transition(pwrdm);
530 }
531
532 ret = pwrdm_set_next_pwrst(pwrdm, state);
533 if (ret) {
534 printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
535 pwrdm->name);
536 goto err;
537 }
538
539 if (sleep_switch) {
540 omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
541 pwrdm_wait_transition(pwrdm);
542 pwrdm_state_switch(pwrdm);
543 }
544
545err:
546 return ret;
547}
548
549static void omap3_pm_idle(void) 486static void omap3_pm_idle(void)
550{ 487{
551 local_irq_disable(); 488 local_irq_disable();
@@ -567,23 +504,6 @@ out:
567#ifdef CONFIG_SUSPEND 504#ifdef CONFIG_SUSPEND
568static suspend_state_t suspend_state; 505static suspend_state_t suspend_state;
569 506
570static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
571{
572 u32 tick_rate, cycles;
573
574 if (!seconds && !milliseconds)
575 return;
576
577 tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
578 cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
579 omap_dm_timer_stop(gptimer_wakeup);
580 omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
581
582 pr_info("PM: Resume timer in %u.%03u secs"
583 " (%d ticks at %d ticks/sec.)\n",
584 seconds, milliseconds, cycles, tick_rate);
585}
586
587static int omap3_pm_prepare(void) 507static int omap3_pm_prepare(void)
588{ 508{
589 disable_hlt(); 509 disable_hlt();
@@ -604,7 +524,7 @@ static int omap3_pm_suspend(void)
604 pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); 524 pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
605 /* Set ones wanted by suspend */ 525 /* Set ones wanted by suspend */
606 list_for_each_entry(pwrst, &pwrst_list, node) { 526 list_for_each_entry(pwrst, &pwrst_list, node) {
607 if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) 527 if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
608 goto restore; 528 goto restore;
609 if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm)) 529 if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
610 goto restore; 530 goto restore;
@@ -625,7 +545,7 @@ restore:
625 pwrst->pwrdm->name, pwrst->next_state); 545 pwrst->pwrdm->name, pwrst->next_state);
626 ret = -1; 546 ret = -1;
627 } 547 }
628 set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); 548 omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
629 } 549 }
630 if (ret) 550 if (ret)
631 printk(KERN_ERR "Could not enter target state in pm_suspend\n"); 551 printk(KERN_ERR "Could not enter target state in pm_suspend\n");
@@ -974,7 +894,7 @@ void omap3_pm_off_mode_enable(int enable)
974 894
975 list_for_each_entry(pwrst, &pwrst_list, node) { 895 list_for_each_entry(pwrst, &pwrst_list, node) {
976 pwrst->next_state = state; 896 pwrst->next_state = state;
977 set_pwrdm_state(pwrst->pwrdm, state); 897 omap_set_pwrdm_state(pwrst->pwrdm, state);
978 } 898 }
979} 899}
980 900
@@ -1019,7 +939,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
1019 if (pwrdm_has_hdwr_sar(pwrdm)) 939 if (pwrdm_has_hdwr_sar(pwrdm))
1020 pwrdm_enable_hdwr_sar(pwrdm); 940 pwrdm_enable_hdwr_sar(pwrdm);
1021 941
1022 return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); 942 return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
1023} 943}
1024 944
1025/* 945/*
@@ -1029,9 +949,6 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
1029 */ 949 */
1030static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) 950static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
1031{ 951{
1032 clkdm_clear_all_wkdeps(clkdm);
1033 clkdm_clear_all_sleepdeps(clkdm);
1034
1035 if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) 952 if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
1036 omap2_clkdm_allow_idle(clkdm); 953 omap2_clkdm_allow_idle(clkdm);
1037 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && 954 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 9405831b746a..2a151917ef52 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -31,4 +31,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
31# OMAP mailbox framework 31# OMAP mailbox framework
32obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o 32obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
33 33
34obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o \ No newline at end of file 34obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 7951eefe1a0e..11c5b0eefb85 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -2085,8 +2085,9 @@ void omap2_gpio_prepare_for_idle(int power_state)
2085 for (i = min; i < gpio_bank_count; i++) { 2085 for (i = min; i < gpio_bank_count; i++) {
2086 struct gpio_bank *bank = &gpio_bank[i]; 2086 struct gpio_bank *bank = &gpio_bank[i];
2087 u32 l1, l2; 2087 u32 l1, l2;
2088 int j;
2088 2089
2089 if (bank->dbck_enable_mask) 2090 for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
2090 clk_disable(bank->dbck); 2091 clk_disable(bank->dbck);
2091 2092
2092 if (power_state > PWRDM_POWER_OFF) 2093 if (power_state > PWRDM_POWER_OFF)
@@ -2152,8 +2153,9 @@ void omap2_gpio_resume_after_idle(void)
2152 for (i = min; i < gpio_bank_count; i++) { 2153 for (i = min; i < gpio_bank_count; i++) {
2153 struct gpio_bank *bank = &gpio_bank[i]; 2154 struct gpio_bank *bank = &gpio_bank[i];
2154 u32 l, gen, gen0, gen1; 2155 u32 l, gen, gen0, gen1;
2156 int j;
2155 2157
2156 if (bank->dbck_enable_mask) 2158 for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
2157 clk_enable(bank->dbck); 2159 clk_enable(bank->dbck);
2158 2160
2159 if (!workaround_enabled) 2161 if (!workaround_enabled)
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 9776b41ad76f..c45dbb975e09 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -91,7 +91,8 @@ void omap3_map_io(void);
91}) 91})
92 92
93extern struct device *omap2_get_mpuss_device(void); 93extern struct device *omap2_get_mpuss_device(void);
94extern struct device *omap2_get_dsp_device(void); 94extern struct device *omap2_get_iva_device(void);
95extern struct device *omap2_get_l3_device(void); 95extern struct device *omap2_get_l3_device(void);
96extern struct device *omap4_get_dsp_device(void);
96 97
97#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ 98#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 25cd9ac3b095..28e2d1a78433 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -36,6 +36,8 @@
36 36
37#include <plat/omap_hwmod.h> 37#include <plat/omap_hwmod.h>
38 38
39extern struct device omap_device_parent;
40
39/* omap_device._state values */ 41/* omap_device._state values */
40#define OMAP_DEVICE_STATE_UNKNOWN 0 42#define OMAP_DEVICE_STATE_UNKNOWN 0
41#define OMAP_DEVICE_STATE_ENABLED 1 43#define OMAP_DEVICE_STATE_ENABLED 1
@@ -62,7 +64,6 @@
62 * 64 *
63 */ 65 */
64struct omap_device { 66struct omap_device {
65 u32 magic;
66 struct platform_device pdev; 67 struct platform_device pdev;
67 struct omap_hwmod **hwmods; 68 struct omap_hwmod **hwmods;
68 struct omap_device_pm_latency *pm_lats; 69 struct omap_device_pm_latency *pm_lats;
@@ -82,7 +83,6 @@ int omap_device_shutdown(struct platform_device *pdev);
82 83
83/* Core code interface */ 84/* Core code interface */
84 85
85bool omap_device_is_valid(struct omap_device *od);
86int omap_device_count_resources(struct omap_device *od); 86int omap_device_count_resources(struct omap_device *od);
87int omap_device_fill_resources(struct omap_device *od, struct resource *res); 87int omap_device_fill_resources(struct omap_device *od, struct resource *res);
88 88
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 72902814c3ca..c1835afc238d 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -561,5 +561,6 @@ int omap_hwmod_for_each_by_class(const char *classname,
561extern int omap2420_hwmod_init(void); 561extern int omap2420_hwmod_init(void);
562extern int omap2430_hwmod_init(void); 562extern int omap2430_hwmod_init(void);
563extern int omap3xxx_hwmod_init(void); 563extern int omap3xxx_hwmod_init(void);
564extern int omap44xx_hwmod_init(void);
564 565
565#endif 566#endif
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index ceba58a47595..b5e5f6074b0b 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -91,12 +91,6 @@
91#define USE_WAKEUP_LAT 0 91#define USE_WAKEUP_LAT 0
92#define IGNORE_WAKEUP_LAT 1 92#define IGNORE_WAKEUP_LAT 1
93 93
94/*
95 * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
96 * obtained via container_of() is in fact a struct omap_device
97 */
98#define OMAP_DEVICE_MAGIC 0xf00dcafe
99
100/* Private functions */ 94/* Private functions */
101 95
102/** 96/**
@@ -453,8 +447,6 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
453 od->pm_lats = pm_lats; 447 od->pm_lats = pm_lats;
454 od->pm_lats_cnt = pm_lats_cnt; 448 od->pm_lats_cnt = pm_lats_cnt;
455 449
456 od->magic = OMAP_DEVICE_MAGIC;
457
458 if (is_early_device) 450 if (is_early_device)
459 ret = omap_early_device_register(od); 451 ret = omap_early_device_register(od);
460 else 452 else
@@ -514,6 +506,7 @@ int omap_device_register(struct omap_device *od)
514{ 506{
515 pr_debug("omap_device: %s: registering\n", od->pdev.name); 507 pr_debug("omap_device: %s: registering\n", od->pdev.name);
516 508
509 od->pdev.dev.parent = &omap_device_parent;
517 return platform_device_register(&od->pdev); 510 return platform_device_register(&od->pdev);
518} 511}
519 512
@@ -668,18 +661,6 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
668} 661}
669 662
670/** 663/**
671 * omap_device_is_valid - Check if pointer is a valid omap_device
672 * @od: struct omap_device *
673 *
674 * Return whether struct omap_device pointer @od points to a valid
675 * omap_device.
676 */
677bool omap_device_is_valid(struct omap_device *od)
678{
679 return (od && od->magic == OMAP_DEVICE_MAGIC);
680}
681
682/**
683 * omap_device_get_pwrdm - return the powerdomain * associated with @od 664 * omap_device_get_pwrdm - return the powerdomain * associated with @od
684 * @od: struct omap_device * 665 * @od: struct omap_device *
685 * 666 *
@@ -798,3 +779,14 @@ int omap_device_enable_clocks(struct omap_device *od)
798 /* XXX pass along return value here? */ 779 /* XXX pass along return value here? */
799 return 0; 780 return 0;
800} 781}
782
783struct device omap_device_parent = {
784 .init_name = "omap",
785 .parent = &platform_bus,
786};
787
788static int __init omap_device_init(void)
789{
790 return device_register(&omap_device_parent);
791}
792core_initcall(omap_device_init);