1 /*
2 * OMAP powerdomain control
3 *
4 * Copyright (C) 2007-2008, 2011-2012 Texas Instruments, Inc.
5 * Copyright (C) 2007-2011 Nokia Corporation
6 *
7 * Written by Paul Walmsley
8 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
9 * State counting code by Tero Kristo <tero.kristo@nokia.com>
10 *
11 * Contains some code previously from mach-omap2/pm-debug.c, which was:
12 * Copyright (C) 2005 Texas Instruments, Inc.
13 * Copyright (C) 2006-2008 Nokia Corporation
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
19 #undef DEBUG
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/list.h>
24 #include <linux/errno.h>
25 #include <linux/string.h>
26 #include <linux/spinlock.h>
27 #include <linux/sched.h>
28 #include <linux/seq_file.h>
30 #include <trace/events/power.h>
32 #include "cm2xxx_3xxx.h"
33 #include "prcm44xx.h"
34 #include "cm44xx.h"
35 #include "prm2xxx_3xxx.h"
36 #include "prm44xx.h"
38 #include <asm/cpu.h>
40 #include "powerdomain.h"
41 #include "clockdomain.h"
43 #include "soc.h"
44 #include "pm.h"
46 #define PWRDM_TRACE_STATES_FLAG (1<<31)
48 /* Types of sleep_switch used in pwrdm_set_fpwrst() */
49 #define ALREADYACTIVE_SWITCH 0
50 #define FORCEWAKEUP_SWITCH 1
51 #define LOWPOWERSTATE_SWITCH 2
52 #define ERROR_SWITCH 3
54 /* pwrdm_list contains all registered struct powerdomains */
55 static LIST_HEAD(pwrdm_list);
57 static struct pwrdm_ops *arch_pwrdm;
59 /*
60 * _fpwrst_names: human-readable functional powerstate names - should match
61 * the enum pwrdm_func_state order and names
62 */
63 static const char * const _fpwrst_names[] = {
64 "OFF", "OSWR", "CSWR", "INACTIVE", "ON"
65 };
67 /* Private functions */
69 static struct powerdomain *_pwrdm_lookup(const char *name)
70 {
71 struct powerdomain *pwrdm, *temp_pwrdm;
73 pwrdm = NULL;
75 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
76 if (!strcmp(name, temp_pwrdm->name)) {
77 pwrdm = temp_pwrdm;
78 break;
79 }
80 }
82 return pwrdm;
83 }
85 /**
86 * _pwrdm_register - register a powerdomain
87 * @pwrdm: struct powerdomain * to register
88 *
89 * Adds a powerdomain to the internal powerdomain list. Returns
90 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
91 * already registered by the provided name, or 0 upon success.
92 */
93 static int _pwrdm_register(struct powerdomain *pwrdm)
94 {
95 int i;
96 struct voltagedomain *voltdm;
98 if (!pwrdm->name)
99 return -EINVAL;
101 if (cpu_is_omap44xx() &&
102 pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
103 pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
104 pwrdm->name);
105 return -EINVAL;
106 }
108 if (_pwrdm_lookup(pwrdm->name))
109 return -EEXIST;
111 voltdm = voltdm_lookup(pwrdm->voltdm.name);
112 if (!voltdm) {
113 pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
114 pwrdm->name, pwrdm->voltdm.name);
115 return -EINVAL;
116 }
117 pwrdm->voltdm.ptr = voltdm;
118 INIT_LIST_HEAD(&pwrdm->voltdm_node);
119 voltdm_add_pwrdm(voltdm, pwrdm);
120 spin_lock_init(&pwrdm->_lock);
122 list_add(&pwrdm->node, &pwrdm_list);
124 /* Initialize the powerdomain's state counter */
125 for (i = 0; i < PWRDM_FPWRSTS_COUNT; i++)
126 pwrdm->fpwrst_counter[i] = 0;
128 arch_pwrdm->pwrdm_wait_transition(pwrdm);
129 pwrdm->fpwrst = pwrdm_read_fpwrst(pwrdm);
130 pwrdm->fpwrst_counter[pwrdm->fpwrst - PWRDM_FPWRST_OFFSET] = 1;
131 #ifdef CONFIG_PM_DEBUG
132 pwrdm->timer = sched_clock();
133 #endif
135 return 0;
136 }
138 /**
139 * _pwrdm_save_clkdm_state_and_activate - prepare for power state change
140 * @pwrdm: struct powerdomain * to operate on
141 * @pwrst: power state to switch to
142 * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised
143 *
144 * Determine whether the powerdomain needs to be turned on before
145 * attempting to switch power states. Called by
146 * pwrdm_set_fpwrst(). NOTE that if the powerdomain contains
147 * multiple clockdomains, this code assumes that the first clockdomain
148 * supports software-supervised wakeup mode - potentially a problem.
149 * Returns the power state switch mode currently in use (see the
150 * "Types of sleep_switch" comment above).
151 */
152 static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
153 u8 pwrst, bool *hwsup)
154 {
155 int curr_pwrst;
156 u8 sleep_switch;
158 curr_pwrst = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
159 if (curr_pwrst < 0) {
160 WARN_ON(1);
161 sleep_switch = ERROR_SWITCH;
162 } else if (curr_pwrst < PWRDM_POWER_ON) {
163 if (curr_pwrst > pwrst &&
164 pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
165 arch_pwrdm->pwrdm_set_lowpwrstchange) {
166 sleep_switch = LOWPOWERSTATE_SWITCH;
167 } else {
168 *hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
169 clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]);
170 sleep_switch = FORCEWAKEUP_SWITCH;
171 }
172 } else {
173 sleep_switch = ALREADYACTIVE_SWITCH;
174 }
176 return sleep_switch;
177 }
179 /**
180 * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
181 * @pwrdm: struct powerdomain * to operate on
182 * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
183 * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode?
184 *
185 * Restore the clockdomain state perturbed by
186 * _pwrdm_save_clkdm_state_and_activate(), and call the power state
187 * bookkeeping code. Called by pwrdm_set_fpwrst(). NOTE that if
188 * the powerdomain contains multiple clockdomains, this assumes that
189 * the first associated clockdomain supports either
190 * hardware-supervised idle control in the register, or
191 * software-supervised sleep. No return value.
192 */
193 static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
194 u8 sleep_switch, bool hwsup)
195 {
196 switch (sleep_switch) {
197 case FORCEWAKEUP_SWITCH:
198 if (hwsup)
199 clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
200 else
201 clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]);
202 break;
203 case LOWPOWERSTATE_SWITCH:
204 if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
205 arch_pwrdm->pwrdm_set_lowpwrstchange)
206 arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
207 pwrdm_state_switch_nolock(pwrdm);
208 break;
209 }
210 }
212 /**
213 * _pwrdm_pwrst_is_controllable - can software change the powerdomain pwrst?
214 * @pwrdm: struct powerdomain * to test
215 *
216 * If the kernel can program the power state that the powerdomain
217 * @pwrdm should enter next, return 1; otherwise, return 0.
218 */
219 static bool _pwrdm_pwrst_is_controllable(struct powerdomain *pwrdm)
220 {
221 return (!pwrdm->pwrsts || pwrdm->pwrsts == PWRSTS_ON) ? 0 : 1;
222 }
224 /**
225 * _pwrdm_pwrst_can_change - can the power state of @pwrdm change?
226 * @pwrdm: struct powerdomain * to test
227 *
228 * If the power state of the powerdomain represented by @pwrdm can
229 * change (i.e., is not always on), and the kernel has some way to
230 * detect this, return 1; otherwise, return 0. XXX The current
231 * implementation of this is based on an assumption and has not been
232 * verified against all OMAPs.
233 */
234 static bool _pwrdm_pwrst_can_change(struct powerdomain *pwrdm)
235 {
236 return _pwrdm_pwrst_is_controllable(pwrdm);
237 }
239 /**
240 * _pwrdm_logic_retst_is_controllable - can software change the logic retst?
241 * @pwrdm: struct powerdomain * to test
242 *
243 * If the kernel can program the power state that the powerdomain
244 * @pwrdm logic should enter when the @pwrdm enters the RETENTION
245 * power state, return 1; otherwise, return 0.
246 */
247 static bool _pwrdm_logic_retst_is_controllable(struct powerdomain *pwrdm)
248 {
249 return (!pwrdm->pwrsts_logic_ret ||
250 pwrdm->pwrsts_logic_ret == PWRSTS_RET) ? 0 : 1;
251 }
253 /**
254 * _pwrdm_logic_retst_can_change - can the logic retst change on @pwrdm?
255 * @pwrdm: struct powerdomain * to test
256 *
257 * If the logic powerstate for the powerdomain represented by @pwrdm
258 * can ever be something other than the powerdomain's powerstate, and
259 * the kernel has some way to detect this, return 1; otherwise, return
260 * 0. XXX The current implementation of this is based on an
261 * assumption and has not been verified against all OMAPs.
262 */
263 static bool _pwrdm_logic_retst_can_change(struct powerdomain *pwrdm)
264 {
265 return _pwrdm_logic_retst_is_controllable(pwrdm);
266 }
268 /**
269 * Search down then up for a valid state from a list of allowed
270 * states. Used by states conversion functions (_pwrdm_fpwrst_to_*)
271 * to look for allowed power and logic states for a powerdomain.
272 * _pwrdm_fpwrst_to_pwrst - Convert functional (i.e. logical) to
273 * internal (i.e. registers) values for the power domains states.
274 * @pwrdm: struct powerdomain * to convert the values for
275 * @fpwrst: functional power state
276 * @pwrdm_pwrst: ptr to u8 to return the power state in
277 * @logic_retst: ptr to u8 to return the logic retention state in
278 *
279 * Returns the internal power state value for the power domain, or
280 * -EINVAL in case of invalid parameters passed in.
281 */
282 static int _pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst,
283 u8 *pwrdm_pwrst, u8 *logic_retst)
284 {
285 switch (fpwrst) {
286 case PWRDM_FUNC_PWRST_ON:
287 *pwrdm_pwrst = PWRDM_POWER_ON;
288 *logic_retst = PWRDM_POWER_RET;
289 break;
290 case PWRDM_FUNC_PWRST_INACTIVE:
291 *pwrdm_pwrst = PWRDM_POWER_INACTIVE;
292 *logic_retst = PWRDM_POWER_RET;
293 break;
294 case PWRDM_FUNC_PWRST_CSWR:
295 *pwrdm_pwrst = PWRDM_POWER_RET;
296 *logic_retst = PWRDM_POWER_RET;
297 break;
298 case PWRDM_FUNC_PWRST_OSWR:
299 *pwrdm_pwrst = PWRDM_POWER_RET;
300 *logic_retst = PWRDM_POWER_OFF;
301 break;
302 case PWRDM_FUNC_PWRST_OFF:
303 *pwrdm_pwrst = PWRDM_POWER_OFF;
304 /*
305 * logic_retst is set to PWRDM_POWER_RET in this case
306 * since the actual value does not matter, and because
307 * some powerdomains don't support a logic_retst of
308 * OFF. XXX Maybe there's some way to indicate a
309 * 'don't care' value here?
310 */
311 *logic_retst = PWRDM_POWER_RET;
312 break;
313 default:
314 return -EINVAL;
315 }
317 pr_debug("powerdomain %s: convert fpwrst %0x to pwrst %0x\n",
318 pwrdm->name, fpwrst, *pwrdm_pwrst);
320 return 0;
321 }
323 /**
324 * _pwrdm_pwrst_to_fpwrst - Convert internal (i.e. registers) to
325 * functional (i.e. logical) values for the power domains states.
326 * @pwrdm: struct powerdomain * to convert the values for
327 * @pwrst: internal powerdomain power state
328 * @logic: internal powerdomain logic power state
329 * @fpwrst: pointer to a u8 to store the corresponding functional power state to
330 *
331 * Returns the functional power state value for the power domain, or
332 * -EINVAL in case of invalid parameters passed in. @pwrdm, @logic, and @pwrst
333 * are passed in, along with a pointer to the location to store the fpwrst to
334 * in @fpwrst.
335 */
336 static int _pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic,
337 u8 *fpwrst)
338 {
339 switch (pwrst) {
340 case PWRDM_POWER_ON:
341 *fpwrst = PWRDM_FUNC_PWRST_ON;
342 break;
343 case PWRDM_POWER_INACTIVE:
344 *fpwrst = PWRDM_FUNC_PWRST_INACTIVE;
345 break;
346 case PWRDM_POWER_RET:
347 if (logic == PWRDM_POWER_OFF)
348 *fpwrst = PWRDM_FUNC_PWRST_OSWR;
349 else if (logic == PWRDM_POWER_RET)
350 *fpwrst = PWRDM_FUNC_PWRST_CSWR;
351 else
352 return -EINVAL;
353 break;
354 case PWRDM_POWER_OFF:
355 *fpwrst = PWRDM_FUNC_PWRST_OFF;
356 break;
357 default:
358 return -EINVAL;
359 }
361 pr_debug("powerdomain: convert pwrst (%0x,%0x) to fpwrst %0x\n",
362 pwrst, logic, *fpwrst);
364 return 0;
365 }
367 /**
368 * _set_logic_retst_and_pwrdm_pwrst - program logic retst and pwrdm next pwrst
369 * @pwrdm: struct powerdomain * to program
370 * @logic: logic retention state to attempt to program
371 * @pwrst: powerdomain next-power-state to program
372 *
373 * Program the next-power-state and logic retention power state of the
374 * powerdomain represented by @pwrdm to @pwrst and @logic,
375 * respectively. If the powerdomain next-power-state is not
376 * software-controllable, returns 0; otherwise, passes along the
377 * return value from pwrdm_set_logic_retst() if there is an error
378 * returned by that function, otherwise, passes along the return value
379 * from pwrdm_set_next_fpwrst()
380 */
381 static int _set_logic_retst_and_pwrdm_pwrst(struct powerdomain *pwrdm,
382 u8 logic, u8 pwrst)
383 {
384 int ret;
386 /*
387 * XXX Should return an error, but this means that our PM code
388 * will need to be much more careful about what it programs
389 */
390 if (!_pwrdm_pwrst_is_controllable(pwrdm))
391 return 0;
393 if (!(pwrdm->pwrsts & (1 << pwrst)))
394 return -EINVAL;
396 if (pwrdm->pwrsts_logic_ret && pwrst == PWRDM_POWER_RET) {
397 if (!(pwrdm->pwrsts_logic_ret & (1 << logic)))
398 return -EINVAL;
400 ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, logic);
401 if (ret) {
402 pr_err("%s: unable to set logic state %0x of powerdomain: %s\n",
403 __func__, logic, pwrdm->name);
404 return ret;
405 }
406 }
408 ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
409 if (ret)
410 pr_err("%s: unable to set power state %0x of powerdomain: %s\n",
411 __func__, pwrst, pwrdm->name);
413 return ret;
414 }
416 /**
417 * _pwrdm_read_next_fpwrst - get next powerdomain func power state (lockless)
418 * @pwrdm: struct powerdomain * to get power state
419 *
420 * Return the powerdomain @pwrdm's next functional power state.
421 * Caller must hold @pwrdm->_lock. Returns -EINVAL if the powerdomain
422 * pointer is null or returns the next power state upon success.
423 */
424 static int _pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
425 {
426 int next_pwrst, next_logic, ret;
427 u8 fpwrst;
429 if (pwrdm->_flags & _PWRDM_NEXT_FPWRST_IS_VALID)
430 return pwrdm->next_fpwrst;
432 next_pwrst = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
433 if (next_pwrst < 0)
434 return next_pwrst;
436 next_logic = next_pwrst;
437 if (_pwrdm_logic_retst_can_change(pwrdm) &&
438 arch_pwrdm->pwrdm_read_logic_pwrst) {
439 next_logic = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
440 if (next_logic < 0)
441 return next_logic;
442 }
443 ret = _pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic, &fpwrst);
444 if (!ret) {
445 pwrdm->next_fpwrst = fpwrst;
446 pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
447 }
449 return (ret) ? ret : fpwrst;
450 }
452 /**
453 * _pwrdm_read_fpwrst - get current func powerdomain power state (lockless)
454 * @pwrdm: struct powerdomain * to get current functional power state
455 *
456 * Return the powerdomain @pwrdm's current functional power state.
457 * Returns -EINVAL if the powerdomain pointer is null or returns the
458 * current power state upon success.
459 */
460 static int _pwrdm_read_fpwrst(struct powerdomain *pwrdm)
461 {
462 int pwrst, logic_pwrst, ret;
463 u8 fpwrst;
465 if (!_pwrdm_pwrst_can_change(pwrdm) ||
466 pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL)
467 return PWRDM_FUNC_PWRST_ON;
469 pwrst = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
470 if (pwrst < 0)
471 return pwrst;
473 logic_pwrst = pwrst;
474 if (_pwrdm_logic_retst_can_change(pwrdm) &&
475 arch_pwrdm->pwrdm_read_logic_pwrst) {
476 logic_pwrst = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
477 if (logic_pwrst < 0)
478 return logic_pwrst;
479 }
481 ret = _pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic_pwrst, &fpwrst);
483 return (ret) ? ret : fpwrst;
484 }
486 /**
487 * _pwrdm_read_prev_fpwrst - get previous powerdomain func pwr state (lockless)
488 * @pwrdm: struct powerdomain * to get previous functional power state
489 *
490 * Return the powerdomain @pwrdm's previous functional power state.
491 * Returns -EINVAL if the powerdomain pointer is null or returns the
492 * previous functional power state upon success.
493 */
494 static int _pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
495 {
496 int ret = -EINVAL;
497 int pwrst, logic_pwrst;
498 u8 fpwrst;
500 if (!_pwrdm_pwrst_can_change(pwrdm))
501 return PWRDM_FUNC_PWRST_ON;
503 if (pwrdm->_flags & _PWRDM_PREV_FPWRST_IS_VALID)
504 return pwrdm->prev_fpwrst;
506 pwrst = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
507 if (pwrst < 0)
508 return pwrst;
510 logic_pwrst = pwrst;
511 if (_pwrdm_logic_retst_can_change(pwrdm) &&
512 arch_pwrdm->pwrdm_read_prev_logic_pwrst) {
513 logic_pwrst = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
514 if (logic_pwrst < 0)
515 return logic_pwrst;
516 }
518 ret = _pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic_pwrst, &fpwrst);
519 if (!ret) {
520 pwrdm->prev_fpwrst = fpwrst;
521 pwrdm->_flags |= _PWRDM_PREV_FPWRST_IS_VALID;
522 }
524 return (ret) ? ret : fpwrst;
525 }
527 /**
528 * _pwrdm_set_mem_onst - set memory power state while powerdomain ON
529 * @pwrdm: struct powerdomain * to set
530 * @bank: memory bank number to set (0-3)
531 * @pwrst: one of the PWRDM_POWER_* macros
532 *
533 * Set the next power state @pwrst that memory bank @bank of the
534 * powerdomain @pwrdm will enter when the powerdomain enters the ON
535 * state. @bank will be a number from 0 to 3, and represents different
536 * types of memory, depending on the powerdomain. Returns -EINVAL if
537 * the powerdomain pointer is null or the target power state is not
538 * not supported for this memory bank, -EEXIST if the target memory
539 * bank does not exist or is not controllable, or returns 0 upon
540 * success.
541 */
542 static int _pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
543 {
544 int ret = -EINVAL;
546 if (pwrdm->banks < (bank + 1))
547 return -EEXIST;
549 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
550 return -EINVAL;
552 pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n",
553 pwrdm->name, bank, pwrst);
555 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
556 ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
558 return ret;
559 }
561 /**
562 * _pwrdm_set_mem_retst - set memory power state while powerdomain in RET
563 * @pwrdm: struct powerdomain * to set
564 * @bank: memory bank number to set (0-3)
565 * @pwrst: one of the PWRDM_POWER_* macros
566 *
567 * Set the next power state @pwrst that memory bank @bank of the
568 * powerdomain @pwrdm will enter when the powerdomain enters the
569 * RETENTION state. Bank will be a number from 0 to 3, and represents
570 * different types of memory, depending on the powerdomain. @pwrst
571 * will be either RETENTION or OFF, if supported. Returns -EINVAL if
572 * the powerdomain pointer is null or the target power state is not
573 * not supported for this memory bank, -EEXIST if the target memory
574 * bank does not exist or is not controllable, or returns 0 upon
575 * success.
576 */
577 static int _pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
578 {
579 int ret = -EINVAL;
581 if (pwrdm->banks < (bank + 1))
582 return -EEXIST;
584 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
585 return -EINVAL;
587 pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n",
588 pwrdm->name, bank, pwrst);
590 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
591 ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
593 return ret;
594 }
596 /* XXX prev is wrong type */
597 /* XXX is sched_clock() correct to use here? */
598 /* Update timer for previous state */
599 static void _pwrdm_update_pwrst_time(struct powerdomain *pwrdm, int prev)
600 {
601 #ifdef CONFIG_PM_DEBUG
602 s64 t;
604 t = sched_clock();
606 pwrdm->fpwrst_timer[prev - PWRDM_FPWRST_OFFSET] += t - pwrdm->timer;
608 pwrdm->timer = t;
609 #endif
610 }
612 /**
613 * _pwrdm_state_switch - record powerdomain usage data; track power state
614 * (before powerdomain state transition)
615 * @pwrdm: struct powerdomain * to observe
616 *
617 * If the powerdomain @pwrdm's current power state is not what we last
618 * observed it to be, then increment the counter for that power state.
619 * This is used to track context loss events, and for debugging. Also
620 * if CONFIG_PM_DEBUG=y, track the amount of time the powerdomain has
621 * spent in the current power state. Caller must hold pwrdm->_lock.
622 * Intended to be called immediately before the powerdomain's power
623 * state is likely to change. XXX Note that the counts and durations
624 * observed by this function may be inaccurate. Powerdomains can
625 * transition power states automatically, without the kernel being
626 * involved -- for example, a device can DMA data from memory while
627 * the MPU is asleep. This function does not attempt to account for
628 * that. XXX It may be possible to skip this function completely if
629 * PM debugging is not needed and off-mode and OSWR is disabled (e.g.,
630 * no context loss events). No return value.
631 */
632 static void _pwrdm_state_switch(struct powerdomain *pwrdm)
633 {
634 int fpwrst;
636 fpwrst = _pwrdm_read_fpwrst(pwrdm);
637 if (fpwrst != pwrdm->fpwrst)
638 pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
640 _pwrdm_update_pwrst_time(pwrdm, pwrdm->fpwrst);
642 pwrdm->fpwrst = fpwrst;
643 }
645 static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
646 {
647 /*
648 * XXX It should be possible to avoid the clear_all_prev_pwrst
649 * call for powerdomains if we are programming them to stay on,
650 * for example.
651 */
652 pwrdm_clear_all_prev_pwrst(pwrdm);
653 _pwrdm_state_switch(pwrdm);
654 return 0;
655 }
657 /**
658 * _pwrdm_post_transition_cb - record powerdomain usage data; track power state
659 * (after powerdomain power state transition)
660 * @pwrdm: struct powerdomain * to observe
661 *
662 * If the powerdomain @pwrdm's previous power state doesn't match our
663 * recollection of the powerdomain's current power state, then
664 * increment the counter for the previous power state. And if the
665 * powerdomain's previous power state doesn't match the current power
666 * state, increment the counter for the current power state. This
667 * function is used to track context loss events, and for debugging.
668 * Also if CONFIG_PM_DEBUG=y, track the approximate amount of time the
669 * powerdomain has spent in the previous power state. Caller must
670 * hold pwrdm->_lock. XXX Note that the counts and durations observed
671 * by this function may be inaccurate. Powerdomains can transition
672 * power states automatically, without the kernel being involved --
673 * for example, a device can DMA data from memory while the MPU is
674 * asleep. This function does not attempt to account for that. XXX
675 * It may be possible to skip this function completely if PM debugging
676 * is not needed and off-mode and OSWR is disabled (e.g., no context
677 * loss events). No return value.
678 */
679 static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
680 {
681 int prev, fpwrst;
682 int trace_state = 0;
684 prev = (pwrdm->next_fpwrst == PWRDM_FUNC_PWRST_ON) ?
685 PWRDM_FUNC_PWRST_ON : _pwrdm_read_prev_fpwrst(pwrdm);
687 if (pwrdm->fpwrst != prev)
688 pwrdm->fpwrst_counter[prev - PWRDM_FPWRST_OFFSET]++;
690 _pwrdm_update_pwrst_time(pwrdm, prev);
692 /*
693 * If the power domain did not hit the desired state,
694 * generate a trace event with both the desired and hit states
695 */
696 if (pwrdm->next_fpwrst != prev) {
697 trace_state = (PWRDM_TRACE_STATES_FLAG |
698 pwrdm->next_fpwrst << 8 | prev);
699 trace_power_domain_target(pwrdm->name, trace_state,
700 smp_processor_id());
701 }
703 fpwrst = _pwrdm_read_fpwrst(pwrdm);
704 if (fpwrst != prev)
705 pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
707 pwrdm->fpwrst = fpwrst;
709 return 0;
710 }
712 /* Public functions */
714 /**
715 * pwrdm_register_platform_funcs - register powerdomain implementation fns
716 * @po: func pointers for arch specific implementations
717 *
718 * Register the list of function pointers used to implement the
719 * powerdomain functions on different OMAP SoCs. Should be called
720 * before any other pwrdm_register*() function. Several function
721 * pointers in @po are required to be non-null for the powerdomain
722 * code to function: pwrdm_wait_transition, pwrdm_read_next_pwrst,
723 * pwrdm_read_pwrst, pwrdm_set_next_pwrst, pwrdm_set_logic_retst, and
724 * pwrdm_read_prev_pwrst. Returns -EINVAL if @po is null, -EEXIST if
725 * platform functions have already been registered, or 0 upon success.
726 */
727 int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
728 {
729 if (!po)
730 return -EINVAL;
732 if (arch_pwrdm)
733 return -EEXIST;
735 if (!po->pwrdm_wait_transition || !po->pwrdm_read_next_pwrst ||
736 !po->pwrdm_read_pwrst || !po->pwrdm_set_next_pwrst ||
737 !po->pwrdm_set_logic_retst || !po->pwrdm_read_prev_pwrst)
738 return -ENOENT;
740 arch_pwrdm = po;
742 return 0;
743 }
745 /**
746 * pwrdm_register_pwrdms - register SoC powerdomains
747 * @ps: pointer to an array of struct powerdomain to register
748 *
749 * Register the powerdomains available on a particular OMAP SoC. Must
750 * be called after pwrdm_register_platform_funcs(). May be called
751 * multiple times. Returns -EACCES if called before
752 * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
753 * null; or 0 upon success.
754 */
755 int pwrdm_register_pwrdms(struct powerdomain **ps)
756 {
757 struct powerdomain **p = NULL;
759 if (!arch_pwrdm)
760 return -EEXIST;
762 if (!ps)
763 return -EINVAL;
765 for (p = ps; *p; p++)
766 _pwrdm_register(*p);
768 return 0;
769 }
771 /**
772 * pwrdm_complete_init - set up the powerdomain layer
773 *
774 * Do whatever is necessary to initialize registered powerdomains and
775 * powerdomain code. Currently, this programs the next power state
776 * for each powerdomain to ON, and programs the memory bank power
777 * states to follow the powerdomain power states. This prevents
778 * powerdomains from unexpectedly losing context or entering high
779 * wakeup latency modes with non-power-management-enabled kernels.
780 * Must be called after pwrdm_register_pwrdms(). Returns -EACCES if
781 * called before pwrdm_register_pwrdms(), or 0 upon success.
782 */
783 int pwrdm_complete_init(void)
784 {
785 struct powerdomain *temp_p;
786 int i;
788 if (list_empty(&pwrdm_list))
789 return -EACCES;
791 list_for_each_entry(temp_p, &pwrdm_list, node) {
792 for (i = 0; i < temp_p->banks; i++) {
793 _pwrdm_set_mem_onst(temp_p, i, PWRDM_POWER_ON);
794 _pwrdm_set_mem_retst(temp_p, i, PWRDM_POWER_RET);
795 }
796 WARN_ON(pwrdm_set_next_fpwrst(temp_p, PWRDM_FUNC_PWRST_ON));
797 }
799 return 0;
800 }
802 /**
803 * pwrdm_lock - acquire a Linux spinlock on a powerdomain
804 * @pwrdm: struct powerdomain * to lock
805 *
806 * Acquire the powerdomain spinlock on @pwrdm. No return value.
807 */
808 void pwrdm_lock(struct powerdomain *pwrdm)
809 __acquires(&pwrdm->_lock)
810 {
811 spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
812 }
814 /**
815 * pwrdm_unlock - release a Linux spinlock on a powerdomain
816 * @pwrdm: struct powerdomain * to unlock
817 *
818 * Release the powerdomain spinlock on @pwrdm. No return value.
819 */
820 void pwrdm_unlock(struct powerdomain *pwrdm)
821 __releases(&pwrdm->_lock)
822 {
823 spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
824 }
826 /**
827 * pwrdm_lookup - look up a powerdomain by name, return a pointer
828 * @name: name of powerdomain
829 *
830 * Find a registered powerdomain by its name @name. Returns a pointer
831 * to the struct powerdomain if found, or NULL otherwise.
832 */
833 struct powerdomain *pwrdm_lookup(const char *name)
834 {
835 struct powerdomain *pwrdm;
837 if (!name)
838 return NULL;
840 pwrdm = _pwrdm_lookup(name);
842 return pwrdm;
843 }
845 /**
846 * pwrdm_for_each - call function on each registered clockdomain
847 * @fn: callback function *
848 *
849 * Call the supplied function @fn for each registered powerdomain.
850 * The callback function @fn can return anything but 0 to bail out
851 * early from the iterator. Returns the last return value of the
852 * callback function, which should be 0 for success or anything else
853 * to indicate failure; or -EINVAL if the function pointer is null.
854 */
855 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
856 void *user)
857 {
858 struct powerdomain *temp_pwrdm;
859 int ret = 0;
861 if (!fn)
862 return -EINVAL;
864 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
865 ret = (*fn)(temp_pwrdm, user);
866 if (ret)
867 break;
868 }
870 return ret;
871 }
873 /**
874 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
875 * @pwrdm: struct powerdomain * to add the clockdomain to
876 * @clkdm: struct clockdomain * to associate with a powerdomain
877 *
878 * Associate the clockdomain @clkdm with a powerdomain @pwrdm. This
879 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
880 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
881 * or 0 upon success.
882 */
883 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
884 {
885 int i;
886 int ret = -EINVAL;
888 if (!pwrdm || !clkdm)
889 return -EINVAL;
891 pr_debug("powerdomain: %s: associating clockdomain %s\n",
892 pwrdm->name, clkdm->name);
894 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
895 if (!pwrdm->pwrdm_clkdms[i])
896 break;
897 #ifdef DEBUG
898 if (pwrdm->pwrdm_clkdms[i] == clkdm) {
899 ret = -EINVAL;
900 goto pac_exit;
901 }
902 #endif
903 }
905 if (i == PWRDM_MAX_CLKDMS) {
906 pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n",
907 pwrdm->name, clkdm->name);
908 WARN_ON(1);
909 ret = -ENOMEM;
910 goto pac_exit;
911 }
913 pwrdm->pwrdm_clkdms[i] = clkdm;
915 ret = 0;
917 pac_exit:
918 return ret;
919 }
921 /**
922 * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
923 * @pwrdm: struct powerdomain * to add the clockdomain to
924 * @clkdm: struct clockdomain * to associate with a powerdomain
925 *
926 * Dissociate the clockdomain @clkdm from the powerdomain
927 * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
928 * if @clkdm was not associated with the powerdomain, or 0 upon
929 * success.
930 */
931 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
932 {
933 int ret = -EINVAL;
934 int i;
936 if (!pwrdm || !clkdm)
937 return -EINVAL;
939 pr_debug("powerdomain: %s: dissociating clockdomain %s\n",
940 pwrdm->name, clkdm->name);
942 for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
943 if (pwrdm->pwrdm_clkdms[i] == clkdm)
944 break;
946 if (i == PWRDM_MAX_CLKDMS) {
947 pr_debug("powerdomain: %s: clkdm %s not associated?!\n",
948 pwrdm->name, clkdm->name);
949 ret = -ENOENT;
950 goto pdc_exit;
951 }
953 pwrdm->pwrdm_clkdms[i] = NULL;
955 ret = 0;
957 pdc_exit:
958 return ret;
959 }
961 /**
962 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
963 * @pwrdm: struct powerdomain * to iterate over
964 * @fn: callback function *
965 *
966 * Call the supplied function @fn for each clockdomain in the powerdomain
967 * @pwrdm. The callback function can return anything but 0 to bail
968 * out early from the iterator. Returns -EINVAL if presented with
969 * invalid pointers; or passes along the last return value of the
970 * callback function, which should be 0 for success or anything else
971 * to indicate failure.
972 */
973 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
974 int (*fn)(struct powerdomain *pwrdm,
975 struct clockdomain *clkdm))
976 {
977 int ret = 0;
978 int i;
980 if (!fn)
981 return -EINVAL;
983 for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
984 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
986 return ret;
987 }
989 /**
990 * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
991 * @pwrdm: struct powerdomain *
992 *
993 * Return a pointer to the struct voltageomain that the specified powerdomain
994 * @pwrdm exists in.
995 */
996 struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
997 {
998 return pwrdm->voltdm.ptr;
999 }
1001 /**
1002 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
1003 * @pwrdm: struct powerdomain * to clear
1004 *
1005 * Clear the powerdomain's previous power state register @pwrdm.
1006 * Clears the entire register, including logic and memory bank
1007 * previous power states. Returns -EINVAL if the powerdomain pointer
1008 * is null, or returns 0 upon success.
1009 */
1010 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
1011 {
1012 int ret = -EINVAL;
1014 if (!pwrdm)
1015 return ret;
1017 /*
1018 * XXX Is there some way for us to skip powerdomains that
1019 * don't have a prev pwrst register?
1020 */
1022 /*
1023 * XXX should get the powerdomain's current state here;
1024 * warn & fail if it is not ON.
1025 */
1027 pr_debug("powerdomain: %s: clearing previous power state reg\n",
1028 pwrdm->name);
1030 pwrdm->_flags &= ~_PWRDM_PREV_FPWRST_IS_VALID;
1032 if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
1033 ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
1035 return ret;
1036 }
1038 /**
1039 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
1040 * @pwrdm: struct powerdomain *
1041 *
1042 * Enable automatic context save-and-restore upon power state change
1043 * for some devices in the powerdomain @pwrdm. Warning: this only
1044 * affects a subset of devices in a powerdomain; check the TRM
1045 * closely. Returns -EINVAL if the powerdomain pointer is null or if
1046 * the powerdomain does not support automatic save-and-restore, or
1047 * returns 0 upon success.
1048 */
1049 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
1050 {
1051 int ret = -EINVAL;
1053 if (!pwrdm)
1054 return ret;
1056 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
1057 return ret;
1059 pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name);
1061 if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
1062 ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
1064 return ret;
1065 }
1067 /**
1068 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
1069 * @pwrdm: struct powerdomain *
1070 *
1071 * Disable automatic context save-and-restore upon power state change
1072 * for some devices in the powerdomain @pwrdm. Warning: this only
1073 * affects a subset of devices in a powerdomain; check the TRM
1074 * closely. Returns -EINVAL if the powerdomain pointer is null or if
1075 * the powerdomain does not support automatic save-and-restore, or
1076 * returns 0 upon success.
1077 */
1078 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
1079 {
1080 int ret = -EINVAL;
1082 if (!pwrdm)
1083 return ret;
1085 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
1086 return ret;
1088 pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name);
1090 if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
1091 ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
1093 return ret;
1094 }
1096 /**
1097 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
1098 * @pwrdm: struct powerdomain *
1099 *
1100 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
1101 * for some devices, or 0 if it does not.
1102 */
1103 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
1104 {
1105 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
1106 }
1108 int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
1109 {
1110 int ret = 0;
1112 if (!pwrdm || !arch_pwrdm)
1113 return -EINVAL;
1115 if (!(pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL))
1116 ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
1118 if (!ret)
1119 _pwrdm_state_switch(pwrdm);
1121 return ret;
1122 }
1124 int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
1125 {
1126 int ret;
1128 pwrdm_lock(pwrdm);
1129 ret = pwrdm_state_switch_nolock(pwrdm);
1130 pwrdm_unlock(pwrdm);
1132 return ret;
1133 }
1135 int pwrdm_pre_transition(struct powerdomain *pwrdm)
1136 {
1137 if (pwrdm)
1138 _pwrdm_pre_transition_cb(pwrdm, NULL);
1139 else
1140 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
1142 return 0;
1143 }
1145 int pwrdm_post_transition(struct powerdomain *pwrdm)
1146 {
1147 if (pwrdm)
1148 _pwrdm_post_transition_cb(pwrdm, NULL);
1149 else
1150 pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
1152 return 0;
1153 }
1155 /**
1156 * pwrdm_get_context_loss_count - get powerdomain's context loss count
1157 * @pwrdm: struct powerdomain * to wait for
1158 *
1159 * Context loss count is the sum of powerdomain off-mode counter, the
1160 * logic off counter and the per-bank memory off counter. Returns negative
1161 * (and WARNs) upon error, otherwise, returns the context loss count.
1162 */
1163 int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
1164 {
1165 int count;
1167 if (!pwrdm) {
1168 WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
1169 return -ENODEV;
1170 }
1172 count = pwrdm->fpwrst_counter[PWRDM_FUNC_PWRST_OFF -
1173 PWRDM_FPWRST_OFFSET];
1174 count += pwrdm->fpwrst_counter[PWRDM_FUNC_PWRST_OSWR -
1175 PWRDM_FPWRST_OFFSET];
1177 /*
1178 * Context loss count has to be a non-negative value. Clear the sign
1179 * bit to get a value range from 0 to INT_MAX.
1180 */
1181 count &= INT_MAX;
1183 pr_debug("powerdomain: %s: context loss count = %d\n",
1184 pwrdm->name, count);
1186 return count;
1187 }
1189 /**
1190 * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
1191 * @pwrdm: struct powerdomain *
1192 *
1193 * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
1194 * can lose either memory or logic context or if @pwrdm is invalid, or
1195 * returns 0 otherwise. This function is not concerned with how the
1196 * powerdomain registers are programmed (i.e., to go off or not); it's
1197 * concerned with whether it's ever possible for this powerdomain to
1198 * go off while some other part of the chip is active. This function
1199 * assumes that every powerdomain can go to either ON or INACTIVE.
1200 */
1201 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
1202 {
1203 int i;
1205 if (IS_ERR_OR_NULL(pwrdm)) {
1206 pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
1207 __func__);
1208 return 1;
1209 }
1211 if (pwrdm->pwrsts & PWRSTS_OFF)
1212 return 1;
1214 if (pwrdm->pwrsts & PWRSTS_RET) {
1215 if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
1216 return 1;
1218 for (i = 0; i < pwrdm->banks; i++)
1219 if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
1220 return 1;
1221 }
1223 for (i = 0; i < pwrdm->banks; i++)
1224 if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
1225 return 1;
1227 return 0;
1228 }
1230 /* Public functions for functional power state handling */
1232 /**
1233 * pwrdm_convert_fpwrst_to_name - return the name of a functional power state
1234 * @fpwrst: functional power state to return the name of
1235 *
1236 * Return a pointer to a string with the human-readable name of the
1237 * functional power state (e.g., "ON", "CSWR", etc.) Intended for use
1238 * in debugging. Returns NULL if @fpwrst is outside the range of the
1239 * known functional power states.
1240 */
1241 const char *pwrdm_convert_fpwrst_to_name(u8 fpwrst)
1242 {
1243 if (fpwrst < PWRDM_FPWRST_OFFSET || fpwrst >= PWRDM_MAX_FUNC_PWRSTS)
1244 return NULL;
1246 return _fpwrst_names[fpwrst - PWRDM_FPWRST_OFFSET];
1247 }
1249 /**
1250 * pwrdm_set_next_fpwrst - set next powerdomain functional power state
1251 * @pwrdm: struct powerdomain * to set
1252 * @fpwrst: one of the PWRDM_POWER_* macros
1253 *
1254 * Set the powerdomain @pwrdm's next power state to @fpwrst. The
1255 * powerdomain may not enter this state immediately if the
1256 * preconditions for this state have not been satisfied. Returns
1257 * -EINVAL if the powerdomain pointer is null or if the power state is
1258 * invalid for the powerdomin, or returns 0 upon success.
1259 */
1260 int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
1261 {
1262 u8 pwrst, logic;
1263 int ret;
1265 if (!pwrdm || IS_ERR(pwrdm))
1266 return -EINVAL;
1268 /*
1269 * XXX Should return an error, but this means that our PM code
1270 * will need to be much more careful about what it programs
1271 */
1272 if (!_pwrdm_pwrst_is_controllable(pwrdm))
1273 return 0;
1275 ret = _pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst, &pwrst, &logic);
1276 if (ret)
1277 return ret;
1279 if (pwrdm->_flags & _PWRDM_NEXT_FPWRST_IS_VALID &&
1280 pwrdm->next_fpwrst == fpwrst)
1281 return 0;
1283 pr_debug("%s: set fpwrst %0x to pwrdm %s\n", __func__, fpwrst,
1284 pwrdm->name);
1286 /* Trace the pwrdm desired target state */
1287 trace_power_domain_target(pwrdm->name, fpwrst, smp_processor_id());
1289 pwrdm_lock(pwrdm);
1290 ret = _set_logic_retst_and_pwrdm_pwrst(pwrdm, logic, pwrst);
1291 if (!ret) {
1292 pwrdm->next_fpwrst = fpwrst;
1293 pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
1294 }
1295 pwrdm_unlock(pwrdm);
1297 return ret;
1298 }
1300 /**
1301 * pwrdm_read_next_fpwrst - get next powerdomain functional power state
1302 * @pwrdm: struct powerdomain * to get power state
1303 *
1304 * Return the powerdomain @pwrdm's next functional power state.
1305 * Returns -EINVAL if the powerdomain pointer is null or returns
1306 * the next power state upon success.
1307 */
1308 int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
1309 {
1310 int ret;
1312 if (!pwrdm)
1313 return -EINVAL;
1315 pwrdm_lock(pwrdm);
1316 ret = _pwrdm_read_next_fpwrst(pwrdm);
1317 pwrdm_unlock(pwrdm);
1319 return ret;
1320 }
1322 /**
1323 * pwrdm_set_fpwrst - program next powerdomain functional power state
1324 * @pwrdm: struct powerdomain * to set
1325 * @fpwrst: power domain functional state, one of the PWRDM_FUNC_* macros
1326 *
1327 * This programs the pwrdm next functional state, sets the dependencies
1328 * and waits for the state to be applied.
1329 */
1330 int pwrdm_set_fpwrst(struct powerdomain *pwrdm, enum pwrdm_func_state fpwrst)
1331 {
1332 u8 next_fpwrst, pwrst, logic, sleep_switch;
1333 int ret = 0;
1334 bool hwsup = false;
1336 if (!pwrdm || IS_ERR(pwrdm) || !arch_pwrdm)
1337 return -EINVAL;
1339 /*
1340 * XXX Should return an error, but this means that our PM code
1341 * will need to be much more careful about what it programs
1342 */
1343 if (!_pwrdm_pwrst_is_controllable(pwrdm))
1344 return 0;
1346 ret = _pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst, &pwrst, &logic);
1347 if (ret)
1348 return -EINVAL;
1350 pr_debug("%s: pwrdm %s: set fpwrst %0x\n", __func__, pwrdm->name,
1351 fpwrst);
1353 pwrdm_lock(pwrdm);
1355 next_fpwrst = _pwrdm_read_next_fpwrst(pwrdm);
1356 if (next_fpwrst == fpwrst)
1357 goto psf_out;
1359 /* Trace the pwrdm desired target state */
1360 trace_power_domain_target(pwrdm->name, next_fpwrst,
1361 smp_processor_id());
1363 sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, fpwrst,
1364 &hwsup);
1365 if (sleep_switch == ERROR_SWITCH) {
1366 ret = -EINVAL;
1367 goto psf_out;
1368 }
1370 ret = _set_logic_retst_and_pwrdm_pwrst(pwrdm, logic, pwrst);
1371 if (ret) {
1372 pr_err("%s: unable to set power state of powerdomain: %s\n",
1373 __func__, pwrdm->name);
1374 } else {
1375 pwrdm->next_fpwrst = fpwrst;
1376 pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
1377 }
1379 _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup);
1381 psf_out:
1382 pwrdm_unlock(pwrdm);
1384 return ret;
1385 }
1387 /**
1388 * pwrdm_read_fpwrst - get current functional powerdomain power state
1389 * @pwrdm: struct powerdomain * to get current functional power state
1390 *
1391 * Return the powerdomain @pwrdm's current functional power state.
1392 * Returns -EINVAL if the powerdomain pointer is null or returns the
1393 * current power state upon success.
1394 */
1395 int pwrdm_read_fpwrst(struct powerdomain *pwrdm)
1396 {
1397 int ret;
1399 if (!pwrdm || !arch_pwrdm)
1400 return -EINVAL;
1402 if (!_pwrdm_pwrst_can_change(pwrdm))
1403 return PWRDM_FUNC_PWRST_ON;
1405 pwrdm_lock(pwrdm);
1406 ret = _pwrdm_read_fpwrst(pwrdm);
1407 pwrdm_unlock(pwrdm);
1409 return ret;
1410 }
1412 /**
1413 * pwrdm_read_prev_fpwrst - get previous powerdomain functional power state
1414 * @pwrdm: struct powerdomain * to get previous functional power state
1415 *
1416 * Return the powerdomain @pwrdm's previous functional power state.
1417 * Returns -EINVAL if the powerdomain pointer is null or returns the
1418 * previous functional power state upon success.
1419 */
1420 int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
1421 {
1422 int ret = -EINVAL;
1424 if (!pwrdm || !arch_pwrdm)
1425 return -EINVAL;
1427 if (!_pwrdm_pwrst_can_change(pwrdm))
1428 return PWRDM_FUNC_PWRST_ON;
1430 pwrdm_lock(pwrdm);
1431 ret = _pwrdm_read_prev_fpwrst(pwrdm);
1432 pwrdm_unlock(pwrdm);
1434 return ret;
1435 }
1437 /**
1438 * pwrdm_supports_fpwrst - does the powerdomain @pwrdm support the @fpwrst power
1439 * state?
1440 * @pwrdm: struct powerdomain * pointing to a powerdomain to test
1441 * @fpwrst: functional power state
1442 *
1443 * Returns true if the powerdomain pointed to by @pwrdm can enter the
1444 * functional power state @fpwrst, or false if not.
1445 */
1446 bool pwrdm_supports_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
1447 {
1448 u8 pwrst, logic;
1449 int ret;
1451 if (!pwrdm || IS_ERR(pwrdm))
1452 return false;
1454 ret = _pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst, &pwrst, &logic);
1455 if (ret)
1456 return false;
1458 if (pwrdm->pwrsts_logic_ret && pwrst == PWRDM_POWER_RET &&
1459 !(pwrdm->pwrsts_logic_ret & (1 << logic)))
1460 return false;
1462 if (!(pwrdm->pwrsts & (1 << pwrst)))
1463 return false;
1465 return true;
1466 }
1468 /* Powerdomain debugfs-related functions */
1470 /**
1471 * pwrdm_dbg_show_counter - generate debugfs data for the pwrdm pwrst counters
1472 * @pwrdm: struct powerdomain * to generate debugfs data for
1473 * @seq_file: struct seq_file * to write data to
1474 *
1475 * Dump the powerdomain @pwrdm's power state counters (and current
1476 * power state) to the seq_file @seq_file. Currently called by the
1477 * mach-omap2/pm-debug.c code. Returns 0.
1478 */
1479 int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *seq_file)
1480 {
1481 struct seq_file *s = (struct seq_file *)seq_file;
1482 int i;
1483 u8 curr_fpwrst;
1485 if (!_pwrdm_pwrst_can_change(pwrdm))
1486 return 0;
1488 pwrdm_lock(pwrdm);
1490 curr_fpwrst = _pwrdm_read_fpwrst(pwrdm);
1491 if (pwrdm->fpwrst != curr_fpwrst)
1492 pr_err("pwrdm state mismatch(%s) %s != %s\n",
1493 pwrdm->name,
1494 pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst),
1495 pwrdm_convert_fpwrst_to_name(curr_fpwrst));
1497 seq_printf(s, "%s (%s)", pwrdm->name,
1498 pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
1499 for (i = PWRDM_FPWRST_OFFSET; i < PWRDM_MAX_FUNC_PWRSTS; i++)
1500 seq_printf(s, ",%s:%d", pwrdm_convert_fpwrst_to_name(i),
1501 pwrdm->fpwrst_counter[i - PWRDM_FPWRST_OFFSET]);
1503 seq_printf(s, "\n");
1505 pwrdm_unlock(pwrdm);
1507 return 0;
1508 }
1510 /**
1511 * pwrdm_dbg_show_timer - generate debugfs data for the pwrdm pwrst timers
1512 * @pwrdm: struct powerdomain * to generate debugfs data for
1513 * @seq_file: struct seq_file * to write data to
1514 *
1515 * Dump the powerdomain @pwrdm's power state residency duration timings
1516 * to the seq_file @seq_file. Currently called by the mach-omap2/pm-debug.c
1517 * code. Returns 0.
1518 */
1519 int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *seq_file)
1520 {
1521 #ifdef CONFIG_PM_DEBUG
1522 struct seq_file *s = (struct seq_file *)seq_file;
1523 int i;
1525 if (!_pwrdm_pwrst_can_change(pwrdm))
1526 return 0;
1528 pwrdm_lock(pwrdm);
1530 pwrdm_state_switch_nolock(pwrdm);
1532 seq_printf(s, "%s (%s)", pwrdm->name,
1533 pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
1535 for (i = 0; i < PWRDM_FPWRSTS_COUNT; i++)
1536 seq_printf(s, ",%s:%lld",
1537 pwrdm_convert_fpwrst_to_name(i + PWRDM_FPWRST_OFFSET),
1538 pwrdm->fpwrst_timer[i]);
1540 seq_printf(s, "\n");
1542 pwrdm_unlock(pwrdm);
1543 #endif
1544 return 0;
1545 }