aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2013-01-30 17:03:05 -0500
committerTony Lindgren <tony@atomide.com>2013-01-30 17:03:05 -0500
commit0e084c9c843320995b0e219f02880f910d439b37 (patch)
treefe541c1d636f9666104f7753d0435c4681685ef9 /arch/arm/mach-omap2/pm.c
parent7b4bc07991564dfcdfd9e6e7cbebc9bf337111eb (diff)
parent562e54d13b6e0b17f72c9e629e1fd0b71e2a8a36 (diff)
Merge tag 'omap-cleanup-b-for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.9/pm
Several OMAP2+ power management fixes, optimizations, and cleanup. This series is a prerequisite for the functional powerdomain conversion series. Basic test logs for this branch are here: http://www.pwsan.com/omap/testlogs/pm_cleanup_fixes_3.9/20130129150017/
Diffstat (limited to 'arch/arm/mach-omap2/pm.c')
-rw-r--r--arch/arm/mach-omap2/pm.c65
1 files changed, 2 insertions, 63 deletions
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 9627547ee72a..9a9be3c9f208 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -106,80 +106,19 @@ static void __init omap2_init_processor_devices(void)
106 } 106 }
107} 107}
108 108
109/* Types of sleep_switch used in omap_set_pwrdm_state */
110#define FORCEWAKEUP_SWITCH 0
111#define LOWPOWERSTATE_SWITCH 1
112
113int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) 109int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
114{ 110{
111 /* XXX The usecount test is racy */
115 if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) && 112 if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
116 !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)) 113 !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
117 clkdm_allow_idle(clkdm); 114 clkdm_allow_idle(clkdm);
118 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && 115 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
119 atomic_read(&clkdm->usecount) == 0) 116 clkdm->usecount == 0)
120 clkdm_sleep(clkdm); 117 clkdm_sleep(clkdm);
121 return 0; 118 return 0;
122} 119}
123 120
124/* 121/*
125 * This sets pwrdm state (other than mpu & core. Currently only ON &
126 * RET are supported.
127 */
128int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst)
129{
130 u8 curr_pwrst, next_pwrst;
131 int sleep_switch = -1, ret = 0, hwsup = 0;
132
133 if (!pwrdm || IS_ERR(pwrdm))
134 return -EINVAL;
135
136 while (!(pwrdm->pwrsts & (1 << pwrst))) {
137 if (pwrst == PWRDM_POWER_OFF)
138 return ret;
139 pwrst--;
140 }
141
142 next_pwrst = pwrdm_read_next_pwrst(pwrdm);
143 if (next_pwrst == pwrst)
144 return ret;
145
146 curr_pwrst = pwrdm_read_pwrst(pwrdm);
147 if (curr_pwrst < PWRDM_POWER_ON) {
148 if ((curr_pwrst > pwrst) &&
149 (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
150 sleep_switch = LOWPOWERSTATE_SWITCH;
151 } else {
152 hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
153 clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
154 sleep_switch = FORCEWAKEUP_SWITCH;
155 }
156 }
157
158 ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
159 if (ret)
160 pr_err("%s: unable to set power state of powerdomain: %s\n",
161 __func__, pwrdm->name);
162
163 switch (sleep_switch) {
164 case FORCEWAKEUP_SWITCH:
165 if (hwsup)
166 clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
167 else
168 clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
169 break;
170 case LOWPOWERSTATE_SWITCH:
171 pwrdm_set_lowpwrstchange(pwrdm);
172 pwrdm_wait_transition(pwrdm);
173 pwrdm_state_switch(pwrdm);
174 break;
175 }
176
177 return ret;
178}
179
180
181
182/*
183 * This API is to be called during init to set the various voltage 122 * This API is to be called during init to set the various voltage
184 * domains to the voltage as per the opp table. Typically we boot up 123 * domains to the voltage as per the opp table. Typically we boot up
185 * at the nominal voltage. So this function finds out the rate of 124 * at the nominal voltage. So this function finds out the rate of