aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:03:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-27 19:03:32 -0400
commitd61b7a572b292e2be409e13b4b3adf475f18fb29 (patch)
treee9d30390860147136c05e66abf1edda1bc5b0562 /arch/arm/mach-omap2/pm.c
parent18d9946bc7e2252fe3c0f2f609ac383c627edefd (diff)
parentf4e2467bad53023589cbff18dd1ab6e0aa3f004c (diff)
Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull "ARM: global cleanups" from Arnd Bergmann: "Quite a bit of code gets removed, and some stuff moved around, mostly the old samsung s3c24xx stuff. There should be no functional changes in this series otherwise. Some cleanups have dependencies on other arm-soc branches and will be sent in the second round. Signed-off-by: Arnd Bergmann <arnd@arndb.de>" Fixed up trivial conflicts mainly due to #include's being changes on both sides. * tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (121 commits) ep93xx: Remove unnecessary includes of ep93xx-regs.h ep93xx: Move EP93XX_SYSCON defines to SoC private header ep93xx: Move crunch code to mach-ep93xx directory ep93xx: Make syscon access functions private to SoC ep93xx: Configure GPIO ports in core code ep93xx: Move peripheral defines to local SoC header ep93xx: Convert the watchdog driver into a platform device. ep93xx: Use ioremap for backlight driver ep93xx: Move GPIO defines to gpio-ep93xx.h ep93xx: Don't use system controller defines in audio drivers ep93xx: Move PHYS_BASE defines to local SoC header file ARM: EXYNOS: Add clock register addresses for EXYNOS4X12 bus devfreq driver ARM: EXYNOS: add clock registers for exynos4x12-cpufreq PM / devfreq: update the name of EXYNOS clock registers that were omitted PM / devfreq: update the name of EXYNOS clock register ARM: EXYNOS: change the prefix S5P_ to EXYNOS4_ for clock ARM: EXYNOS: use static declaration on regarding clock ARM: EXYNOS: replace clock.c for other new EXYNOS SoCs ARM: OMAP2+: Fix build error after merge ARM: S3C24XX: remove call to s3c24xx_setup_clocks ...
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
-rw-r--r--arch/arm/mach-omap2/pm.c113
1 files changed, 91 insertions, 22 deletions
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 184ae21feea7..52787b0eaec6 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -15,11 +15,13 @@
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/opp.h> 16#include <linux/opp.h>
17#include <linux/export.h> 17#include <linux/export.h>
18#include <linux/suspend.h>
18 19
19#include <plat/omap-pm.h> 20#include <plat/omap-pm.h>
20#include <plat/omap_device.h> 21#include <plat/omap_device.h>
21#include "common.h" 22#include "common.h"
22 23
24#include "prcm-common.h"
23#include "voltage.h" 25#include "voltage.h"
24#include "powerdomain.h" 26#include "powerdomain.h"
25#include "clockdomain.h" 27#include "clockdomain.h"
@@ -28,6 +30,12 @@
28 30
29static struct omap_device_pm_latency *pm_lats; 31static struct omap_device_pm_latency *pm_lats;
30 32
33/*
34 * omap_pm_suspend: points to a function that does the SoC-specific
35 * suspend work
36 */
37int (*omap_pm_suspend)(void);
38
31static int __init _init_omap_device(char *name) 39static int __init _init_omap_device(char *name)
32{ 40{
33 struct omap_hwmod *oh; 41 struct omap_hwmod *oh;
@@ -68,32 +76,41 @@ static void __init omap2_init_processor_devices(void)
68#define FORCEWAKEUP_SWITCH 0 76#define FORCEWAKEUP_SWITCH 0
69#define LOWPOWERSTATE_SWITCH 1 77#define LOWPOWERSTATE_SWITCH 1
70 78
79int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
80{
81 if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
82 clkdm_allow_idle(clkdm);
83 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
84 atomic_read(&clkdm->usecount) == 0)
85 clkdm_sleep(clkdm);
86 return 0;
87}
88
71/* 89/*
72 * This sets pwrdm state (other than mpu & core. Currently only ON & 90 * This sets pwrdm state (other than mpu & core. Currently only ON &
73 * RET are supported. 91 * RET are supported.
74 */ 92 */
75int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) 93int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
76{ 94{
77 u32 cur_state; 95 u8 curr_pwrst, next_pwrst;
78 int sleep_switch = -1; 96 int sleep_switch = -1, ret = 0, hwsup = 0;
79 int ret = 0;
80 int hwsup = 0;
81 97
82 if (pwrdm == NULL || IS_ERR(pwrdm)) 98 if (!pwrdm || IS_ERR(pwrdm))
83 return -EINVAL; 99 return -EINVAL;
84 100
85 while (!(pwrdm->pwrsts & (1 << state))) { 101 while (!(pwrdm->pwrsts & (1 << pwrst))) {
86 if (state == PWRDM_POWER_OFF) 102 if (pwrst == PWRDM_POWER_OFF)
87 return ret; 103 return ret;
88 state--; 104 pwrst--;
89 } 105 }
90 106
91 cur_state = pwrdm_read_next_pwrst(pwrdm); 107 next_pwrst = pwrdm_read_next_pwrst(pwrdm);
92 if (cur_state == state) 108 if (next_pwrst == pwrst)
93 return ret; 109 return ret;
94 110
95 if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) { 111 curr_pwrst = pwrdm_read_pwrst(pwrdm);
96 if ((pwrdm_read_pwrst(pwrdm) > state) && 112 if (curr_pwrst < PWRDM_POWER_ON) {
113 if ((curr_pwrst > pwrst) &&
97 (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { 114 (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
98 sleep_switch = LOWPOWERSTATE_SWITCH; 115 sleep_switch = LOWPOWERSTATE_SWITCH;
99 } else { 116 } else {
@@ -103,12 +120,10 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
103 } 120 }
104 } 121 }
105 122
106 ret = pwrdm_set_next_pwrst(pwrdm, state); 123 ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
107 if (ret) { 124 if (ret)
108 pr_err("%s: unable to set state of powerdomain: %s\n", 125 pr_err("%s: unable to set power state of powerdomain: %s\n",
109 __func__, pwrdm->name); 126 __func__, pwrdm->name);
110 goto err;
111 }
112 127
113 switch (sleep_switch) { 128 switch (sleep_switch) {
114 case FORCEWAKEUP_SWITCH: 129 case FORCEWAKEUP_SWITCH:
@@ -119,16 +134,16 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
119 break; 134 break;
120 case LOWPOWERSTATE_SWITCH: 135 case LOWPOWERSTATE_SWITCH:
121 pwrdm_set_lowpwrstchange(pwrdm); 136 pwrdm_set_lowpwrstchange(pwrdm);
137 pwrdm_wait_transition(pwrdm);
138 pwrdm_state_switch(pwrdm);
122 break; 139 break;
123 default:
124 return ret;
125 } 140 }
126 141
127 pwrdm_state_switch(pwrdm);
128err:
129 return ret; 142 return ret;
130} 143}
131 144
145
146
132/* 147/*
133 * This API is to be called during init to set the various voltage 148 * This API is to be called during init to set the various voltage
134 * domains to the voltage as per the opp table. Typically we boot up 149 * domains to the voltage as per the opp table. Typically we boot up
@@ -199,6 +214,56 @@ exit:
199 return -EINVAL; 214 return -EINVAL;
200} 215}
201 216
217#ifdef CONFIG_SUSPEND
218static int omap_pm_enter(suspend_state_t suspend_state)
219{
220 int ret = 0;
221
222 if (!omap_pm_suspend)
223 return -ENOENT; /* XXX doublecheck */
224
225 switch (suspend_state) {
226 case PM_SUSPEND_STANDBY:
227 case PM_SUSPEND_MEM:
228 ret = omap_pm_suspend();
229 break;
230 default:
231 ret = -EINVAL;
232 }
233
234 return ret;
235}
236
237static int omap_pm_begin(suspend_state_t state)
238{
239 disable_hlt();
240 if (cpu_is_omap34xx())
241 omap_prcm_irq_prepare();
242 return 0;
243}
244
245static void omap_pm_end(void)
246{
247 enable_hlt();
248 return;
249}
250
251static void omap_pm_finish(void)
252{
253 if (cpu_is_omap34xx())
254 omap_prcm_irq_complete();
255}
256
257static const struct platform_suspend_ops omap_pm_ops = {
258 .begin = omap_pm_begin,
259 .end = omap_pm_end,
260 .enter = omap_pm_enter,
261 .finish = omap_pm_finish,
262 .valid = suspend_valid_only_mem,
263};
264
265#endif /* CONFIG_SUSPEND */
266
202static void __init omap3_init_voltages(void) 267static void __init omap3_init_voltages(void)
203{ 268{
204 if (!cpu_is_omap34xx()) 269 if (!cpu_is_omap34xx())
@@ -241,6 +306,10 @@ static int __init omap2_common_pm_late_init(void)
241 /* Smartreflex device init */ 306 /* Smartreflex device init */
242 omap_devinit_smartreflex(); 307 omap_devinit_smartreflex();
243 308
309#ifdef CONFIG_SUSPEND
310 suspend_set_ops(&omap_pm_ops);
311#endif
312
244 return 0; 313 return 0;
245} 314}
246late_initcall(omap2_common_pm_late_init); 315late_initcall(omap2_common_pm_late_init);