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 if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm)
112 if (!arch_pwrdm->pwrdm_has_voltdm())
113 goto skip_voltdm;
115 voltdm = voltdm_lookup(pwrdm->voltdm.name);
116 if (!voltdm) {
117 pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
118 pwrdm->name, pwrdm->voltdm.name);
119 return -EINVAL;
120 }
121 pwrdm->voltdm.ptr = voltdm;
122 INIT_LIST_HEAD(&pwrdm->voltdm_node);
123 voltdm_add_pwrdm(voltdm, pwrdm);
125 skip_voltdm:
126 spin_lock_init(&pwrdm->_lock);
127 list_add(&pwrdm->node, &pwrdm_list);
129 /* Initialize the powerdomain's state counter */
130 for (i = 0; i < PWRDM_FPWRSTS_COUNT; i++)
131 pwrdm->fpwrst_counter[i] = 0;
133 arch_pwrdm->pwrdm_wait_transition(pwrdm);
134 pwrdm->fpwrst = pwrdm_read_fpwrst(pwrdm);
135 pwrdm->fpwrst_counter[pwrdm->fpwrst - PWRDM_FPWRST_OFFSET] = 1;
136 #ifdef CONFIG_PM_DEBUG
137 pwrdm->timer = sched_clock();
138 #endif
140 return 0;
141 }
143 /**
144 * _pwrdm_save_clkdm_state_and_activate - prepare for power state change
145 * @pwrdm: struct powerdomain * to operate on
146 * @pwrst: power state to switch to
147 * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised
148 *
149 * Determine whether the powerdomain needs to be turned on before
150 * attempting to switch power states. Called by
151 * pwrdm_set_fpwrst(). NOTE that if the powerdomain contains
152 * multiple clockdomains, this code assumes that the first clockdomain
153 * supports software-supervised wakeup mode - potentially a problem.
154 * Returns the power state switch mode currently in use (see the
155 * "Types of sleep_switch" comment above).
156 */
157 static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
158 u8 pwrst, bool *hwsup)
159 {
160 int curr_pwrst;
161 u8 sleep_switch;
163 curr_pwrst = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
164 if (curr_pwrst < 0) {
165 WARN_ON(1);
166 sleep_switch = ERROR_SWITCH;
167 } else if (curr_pwrst < PWRDM_POWER_ON) {
168 if (curr_pwrst > pwrst &&
169 pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
170 arch_pwrdm->pwrdm_set_lowpwrstchange) {
171 sleep_switch = LOWPOWERSTATE_SWITCH;
172 } else {
173 *hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]);
174 clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]);
175 sleep_switch = FORCEWAKEUP_SWITCH;
176 }
177 } else {
178 sleep_switch = ALREADYACTIVE_SWITCH;
179 }
181 return sleep_switch;
182 }
184 /**
185 * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
186 * @pwrdm: struct powerdomain * to operate on
187 * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
188 * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode?
189 *
190 * Restore the clockdomain state perturbed by
191 * _pwrdm_save_clkdm_state_and_activate(), and call the power state
192 * bookkeeping code. Called by pwrdm_set_fpwrst(). NOTE that if
193 * the powerdomain contains multiple clockdomains, this assumes that
194 * the first associated clockdomain supports either
195 * hardware-supervised idle control in the register, or
196 * software-supervised sleep. No return value.
197 */
198 static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
199 u8 sleep_switch, bool hwsup)
200 {
201 switch (sleep_switch) {
202 case FORCEWAKEUP_SWITCH:
203 if (hwsup)
204 clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
205 else
206 clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]);
207 break;
208 case LOWPOWERSTATE_SWITCH:
209 if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
210 arch_pwrdm->pwrdm_set_lowpwrstchange)
211 arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
212 pwrdm_state_switch_nolock(pwrdm);
213 break;
214 }
215 }
217 /**
218 * _pwrdm_pwrst_is_controllable - can software change the powerdomain pwrst?
219 * @pwrdm: struct powerdomain * to test
220 *
221 * If the kernel can program the power state that the powerdomain
222 * @pwrdm should enter next, return 1; otherwise, return 0.
223 */
224 static bool _pwrdm_pwrst_is_controllable(struct powerdomain *pwrdm)
225 {
226 return (!pwrdm->pwrsts || pwrdm->pwrsts == PWRSTS_ON) ? 0 : 1;
227 }
229 /**
230 * _pwrdm_pwrst_can_change - can the power state of @pwrdm change?
231 * @pwrdm: struct powerdomain * to test
232 *
233 * If the power state of the powerdomain represented by @pwrdm can
234 * change (i.e., is not always on), and the kernel has some way to
235 * detect this, return 1; otherwise, return 0. XXX The current
236 * implementation of this is based on an assumption and has not been
237 * verified against all OMAPs.
238 */
239 static bool _pwrdm_pwrst_can_change(struct powerdomain *pwrdm)
240 {
241 return _pwrdm_pwrst_is_controllable(pwrdm);
242 }
244 /**
245 * _pwrdm_logic_retst_is_controllable - can software change the logic retst?
246 * @pwrdm: struct powerdomain * to test
247 *
248 * If the kernel can program the power state that the powerdomain
249 * @pwrdm logic should enter when the @pwrdm enters the RETENTION
250 * power state, return 1; otherwise, return 0.
251 */
252 static bool _pwrdm_logic_retst_is_controllable(struct powerdomain *pwrdm)
253 {
254 return (!pwrdm->pwrsts_logic_ret ||
255 pwrdm->pwrsts_logic_ret == PWRSTS_RET) ? 0 : 1;
256 }
258 /**
259 * _pwrdm_logic_retst_can_change - can the logic retst change on @pwrdm?
260 * @pwrdm: struct powerdomain * to test
261 *
262 * If the logic powerstate for the powerdomain represented by @pwrdm
263 * can ever be something other than the powerdomain's powerstate, and
264 * the kernel has some way to detect this, return 1; otherwise, return
265 * 0. XXX The current implementation of this is based on an
266 * assumption and has not been verified against all OMAPs.
267 */
268 static bool _pwrdm_logic_retst_can_change(struct powerdomain *pwrdm)
269 {
270 return _pwrdm_logic_retst_is_controllable(pwrdm);
271 }
273 /**
274 * Search down then up for a valid state from a list of allowed
275 * states. Used by states conversion functions (_pwrdm_fpwrst_to_*)
276 * to look for allowed power and logic states for a powerdomain.
277 * _pwrdm_fpwrst_to_pwrst - Convert functional (i.e. logical) to
278 * internal (i.e. registers) values for the power domains states.
279 * @pwrdm: struct powerdomain * to convert the values for
280 * @fpwrst: functional power state
281 * @pwrdm_pwrst: ptr to u8 to return the power state in
282 * @logic_retst: ptr to u8 to return the logic retention state in
283 *
284 * Returns the internal power state value for the power domain, or
285 * -EINVAL in case of invalid parameters passed in.
286 */
287 static int _pwrdm_fpwrst_to_pwrst(struct powerdomain *pwrdm, u8 fpwrst,
288 u8 *pwrdm_pwrst, u8 *logic_retst)
289 {
290 switch (fpwrst) {
291 case PWRDM_FUNC_PWRST_ON:
292 *pwrdm_pwrst = PWRDM_POWER_ON;
293 *logic_retst = PWRDM_POWER_RET;
294 break;
295 case PWRDM_FUNC_PWRST_INACTIVE:
296 *pwrdm_pwrst = PWRDM_POWER_INACTIVE;
297 *logic_retst = PWRDM_POWER_RET;
298 break;
299 case PWRDM_FUNC_PWRST_CSWR:
300 *pwrdm_pwrst = PWRDM_POWER_RET;
301 *logic_retst = PWRDM_POWER_RET;
302 break;
303 case PWRDM_FUNC_PWRST_OSWR:
304 *pwrdm_pwrst = PWRDM_POWER_RET;
305 *logic_retst = PWRDM_POWER_OFF;
306 break;
307 case PWRDM_FUNC_PWRST_OFF:
308 *pwrdm_pwrst = PWRDM_POWER_OFF;
309 /*
310 * logic_retst is set to PWRDM_POWER_RET in this case
311 * since the actual value does not matter, and because
312 * some powerdomains don't support a logic_retst of
313 * OFF. XXX Maybe there's some way to indicate a
314 * 'don't care' value here?
315 */
316 *logic_retst = PWRDM_POWER_RET;
317 break;
318 default:
319 return -EINVAL;
320 }
322 pr_debug("powerdomain %s: convert fpwrst %0x to pwrst %0x\n",
323 pwrdm->name, fpwrst, *pwrdm_pwrst);
325 return 0;
326 }
328 /**
329 * _pwrdm_pwrst_to_fpwrst - Convert internal (i.e. registers) to
330 * functional (i.e. logical) values for the power domains states.
331 * @pwrdm: struct powerdomain * to convert the values for
332 * @pwrst: internal powerdomain power state
333 * @logic: internal powerdomain logic power state
334 * @fpwrst: pointer to a u8 to store the corresponding functional power state to
335 *
336 * Returns the functional power state value for the power domain, or
337 * -EINVAL in case of invalid parameters passed in. @pwrdm, @logic, and @pwrst
338 * are passed in, along with a pointer to the location to store the fpwrst to
339 * in @fpwrst.
340 */
341 static int _pwrdm_pwrst_to_fpwrst(struct powerdomain *pwrdm, u8 pwrst, u8 logic,
342 u8 *fpwrst)
343 {
344 switch (pwrst) {
345 case PWRDM_POWER_ON:
346 *fpwrst = PWRDM_FUNC_PWRST_ON;
347 break;
348 case PWRDM_POWER_INACTIVE:
349 *fpwrst = PWRDM_FUNC_PWRST_INACTIVE;
350 break;
351 case PWRDM_POWER_RET:
352 if (logic == PWRDM_POWER_OFF)
353 *fpwrst = PWRDM_FUNC_PWRST_OSWR;
354 else if (logic == PWRDM_POWER_RET)
355 *fpwrst = PWRDM_FUNC_PWRST_CSWR;
356 else
357 return -EINVAL;
358 break;
359 case PWRDM_POWER_OFF:
360 *fpwrst = PWRDM_FUNC_PWRST_OFF;
361 break;
362 default:
363 return -EINVAL;
364 }
366 pr_debug("powerdomain: convert pwrst (%0x,%0x) to fpwrst %0x\n",
367 pwrst, logic, *fpwrst);
369 return 0;
370 }
372 /**
373 * _set_logic_retst_and_pwrdm_pwrst - program logic retst and pwrdm next pwrst
374 * @pwrdm: struct powerdomain * to program
375 * @logic: logic retention state to attempt to program
376 * @pwrst: powerdomain next-power-state to program
377 *
378 * Program the next-power-state and logic retention power state of the
379 * powerdomain represented by @pwrdm to @pwrst and @logic,
380 * respectively. If the powerdomain next-power-state is not
381 * software-controllable, returns 0; otherwise, passes along the
382 * return value from pwrdm_set_logic_retst() if there is an error
383 * returned by that function, otherwise, passes along the return value
384 * from pwrdm_set_next_fpwrst()
385 */
386 static int _set_logic_retst_and_pwrdm_pwrst(struct powerdomain *pwrdm,
387 u8 logic, u8 pwrst)
388 {
389 int ret;
391 /*
392 * XXX Should return an error, but this means that our PM code
393 * will need to be much more careful about what it programs
394 */
395 if (!_pwrdm_pwrst_is_controllable(pwrdm))
396 return 0;
398 if (!(pwrdm->pwrsts & (1 << pwrst)))
399 return -EINVAL;
401 if (pwrdm->pwrsts_logic_ret && pwrst == PWRDM_POWER_RET) {
402 if (!(pwrdm->pwrsts_logic_ret & (1 << logic)))
403 return -EINVAL;
405 ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, logic);
406 if (ret) {
407 pr_err("%s: unable to set logic state %0x of powerdomain: %s\n",
408 __func__, logic, pwrdm->name);
409 return ret;
410 }
411 }
413 ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
414 if (ret)
415 pr_err("%s: unable to set power state %0x of powerdomain: %s\n",
416 __func__, pwrst, pwrdm->name);
418 return ret;
419 }
421 /**
422 * _pwrdm_read_next_fpwrst - get next powerdomain func power state (lockless)
423 * @pwrdm: struct powerdomain * to get power state
424 *
425 * Return the powerdomain @pwrdm's next functional power state.
426 * Caller must hold @pwrdm->_lock. Returns -EINVAL if the powerdomain
427 * pointer is null or returns the next power state upon success.
428 */
429 static int _pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
430 {
431 int next_pwrst, next_logic, ret;
432 u8 fpwrst;
434 if (pwrdm->_flags & _PWRDM_NEXT_FPWRST_IS_VALID)
435 return pwrdm->next_fpwrst;
437 next_pwrst = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
438 if (next_pwrst < 0)
439 return next_pwrst;
441 next_logic = next_pwrst;
442 if (_pwrdm_logic_retst_can_change(pwrdm) &&
443 arch_pwrdm->pwrdm_read_logic_pwrst) {
444 next_logic = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
445 if (next_logic < 0)
446 return next_logic;
447 }
448 ret = _pwrdm_pwrst_to_fpwrst(pwrdm, next_pwrst, next_logic, &fpwrst);
449 if (!ret) {
450 pwrdm->next_fpwrst = fpwrst;
451 pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
452 }
454 return (ret) ? ret : fpwrst;
455 }
457 /**
458 * _pwrdm_read_fpwrst - get current func powerdomain power state (lockless)
459 * @pwrdm: struct powerdomain * to get current functional power state
460 *
461 * Return the powerdomain @pwrdm's current functional power state.
462 * Returns -EINVAL if the powerdomain pointer is null or returns the
463 * current power state upon success.
464 */
465 static int _pwrdm_read_fpwrst(struct powerdomain *pwrdm)
466 {
467 int pwrst, logic_pwrst, ret;
468 u8 fpwrst;
470 if (!_pwrdm_pwrst_can_change(pwrdm) ||
471 pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL)
472 return PWRDM_FUNC_PWRST_ON;
474 pwrst = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
475 if (pwrst < 0)
476 return pwrst;
478 logic_pwrst = pwrst;
479 if (_pwrdm_logic_retst_can_change(pwrdm) &&
480 arch_pwrdm->pwrdm_read_logic_pwrst) {
481 logic_pwrst = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
482 if (logic_pwrst < 0)
483 return logic_pwrst;
484 }
486 ret = _pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic_pwrst, &fpwrst);
488 return (ret) ? ret : fpwrst;
489 }
491 /**
492 * _pwrdm_read_prev_fpwrst - get previous powerdomain func pwr state (lockless)
493 * @pwrdm: struct powerdomain * to get previous functional power state
494 *
495 * Return the powerdomain @pwrdm's previous functional power state.
496 * Returns -EINVAL if the powerdomain pointer is null or returns the
497 * previous functional power state upon success.
498 */
499 static int _pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
500 {
501 int ret = -EINVAL;
502 int pwrst, logic_pwrst;
503 u8 fpwrst;
505 if (!_pwrdm_pwrst_can_change(pwrdm))
506 return PWRDM_FUNC_PWRST_ON;
508 if (pwrdm->_flags & _PWRDM_PREV_FPWRST_IS_VALID)
509 return pwrdm->prev_fpwrst;
511 pwrst = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
512 if (pwrst < 0)
513 return pwrst;
515 logic_pwrst = pwrst;
516 if (_pwrdm_logic_retst_can_change(pwrdm) &&
517 arch_pwrdm->pwrdm_read_prev_logic_pwrst) {
518 logic_pwrst = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
519 if (logic_pwrst < 0)
520 return logic_pwrst;
521 }
523 ret = _pwrdm_pwrst_to_fpwrst(pwrdm, pwrst, logic_pwrst, &fpwrst);
524 if (!ret) {
525 pwrdm->prev_fpwrst = fpwrst;
526 pwrdm->_flags |= _PWRDM_PREV_FPWRST_IS_VALID;
527 }
529 return (ret) ? ret : fpwrst;
530 }
532 /**
533 * _pwrdm_set_mem_onst - set memory power state while powerdomain ON
534 * @pwrdm: struct powerdomain * to set
535 * @bank: memory bank number to set (0-3)
536 * @pwrst: one of the PWRDM_POWER_* macros
537 *
538 * Set the next power state @pwrst that memory bank @bank of the
539 * powerdomain @pwrdm will enter when the powerdomain enters the ON
540 * state. @bank will be a number from 0 to 3, and represents different
541 * types of memory, depending on the powerdomain. Returns -EINVAL if
542 * the powerdomain pointer is null or the target power state is not
543 * not supported for this memory bank, -EEXIST if the target memory
544 * bank does not exist or is not controllable, or returns 0 upon
545 * success.
546 */
547 static int _pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
548 {
549 int ret = -EINVAL;
551 if (pwrdm->banks < (bank + 1))
552 return -EEXIST;
554 if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
555 return -EINVAL;
557 pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n",
558 pwrdm->name, bank, pwrst);
560 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
561 ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
563 return ret;
564 }
566 /**
567 * _pwrdm_set_mem_retst - set memory power state while powerdomain in RET
568 * @pwrdm: struct powerdomain * to set
569 * @bank: memory bank number to set (0-3)
570 * @pwrst: one of the PWRDM_POWER_* macros
571 *
572 * Set the next power state @pwrst that memory bank @bank of the
573 * powerdomain @pwrdm will enter when the powerdomain enters the
574 * RETENTION state. Bank will be a number from 0 to 3, and represents
575 * different types of memory, depending on the powerdomain. @pwrst
576 * will be either RETENTION or OFF, if supported. Returns -EINVAL if
577 * the powerdomain pointer is null or the target power state is not
578 * not supported for this memory bank, -EEXIST if the target memory
579 * bank does not exist or is not controllable, or returns 0 upon
580 * success.
581 */
582 static int _pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
583 {
584 int ret = -EINVAL;
586 if (pwrdm->banks < (bank + 1))
587 return -EEXIST;
589 if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
590 return -EINVAL;
592 pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n",
593 pwrdm->name, bank, pwrst);
595 if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
596 ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
598 return ret;
599 }
601 /* XXX prev is wrong type */
602 /* XXX is sched_clock() correct to use here? */
603 /* Update timer for previous state */
604 static void _pwrdm_update_pwrst_time(struct powerdomain *pwrdm, int prev)
605 {
606 #ifdef CONFIG_PM_DEBUG
607 s64 t;
609 t = sched_clock();
611 pwrdm->fpwrst_timer[prev - PWRDM_FPWRST_OFFSET] += t - pwrdm->timer;
613 pwrdm->timer = t;
614 #endif
615 }
617 /**
618 * _pwrdm_state_switch - record powerdomain usage data; track power state
619 * (before powerdomain state transition)
620 * @pwrdm: struct powerdomain * to observe
621 *
622 * If the powerdomain @pwrdm's current power state is not what we last
623 * observed it to be, then increment the counter for that power state.
624 * This is used to track context loss events, and for debugging. Also
625 * if CONFIG_PM_DEBUG=y, track the amount of time the powerdomain has
626 * spent in the current power state. Caller must hold pwrdm->_lock.
627 * Intended to be called immediately before the powerdomain's power
628 * state is likely to change. XXX Note that the counts and durations
629 * observed by this function may be inaccurate. Powerdomains can
630 * transition power states automatically, without the kernel being
631 * involved -- for example, a device can DMA data from memory while
632 * the MPU is asleep. This function does not attempt to account for
633 * that. XXX It may be possible to skip this function completely if
634 * PM debugging is not needed and off-mode and OSWR is disabled (e.g.,
635 * no context loss events). No return value.
636 */
637 static void _pwrdm_state_switch(struct powerdomain *pwrdm)
638 {
639 int fpwrst;
641 fpwrst = _pwrdm_read_fpwrst(pwrdm);
642 if (fpwrst != pwrdm->fpwrst)
643 pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
645 _pwrdm_update_pwrst_time(pwrdm, pwrdm->fpwrst);
647 pwrdm->fpwrst = fpwrst;
648 }
650 static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
651 {
652 /*
653 * XXX It should be possible to avoid the clear_all_prev_pwrst
654 * call for powerdomains if we are programming them to stay on,
655 * for example.
656 */
657 pwrdm_clear_all_prev_pwrst(pwrdm);
658 _pwrdm_state_switch(pwrdm);
659 return 0;
660 }
662 /**
663 * _pwrdm_post_transition_cb - record powerdomain usage data; track power state
664 * (after powerdomain power state transition)
665 * @pwrdm: struct powerdomain * to observe
666 *
667 * If the powerdomain @pwrdm's previous power state doesn't match our
668 * recollection of the powerdomain's current power state, then
669 * increment the counter for the previous power state. And if the
670 * powerdomain's previous power state doesn't match the current power
671 * state, increment the counter for the current power state. This
672 * function is used to track context loss events, and for debugging.
673 * Also if CONFIG_PM_DEBUG=y, track the approximate amount of time the
674 * powerdomain has spent in the previous power state. Caller must
675 * hold pwrdm->_lock. XXX Note that the counts and durations observed
676 * by this function may be inaccurate. Powerdomains can transition
677 * power states automatically, without the kernel being involved --
678 * for example, a device can DMA data from memory while the MPU is
679 * asleep. This function does not attempt to account for that. XXX
680 * It may be possible to skip this function completely if PM debugging
681 * is not needed and off-mode and OSWR is disabled (e.g., no context
682 * loss events). No return value.
683 */
684 static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
685 {
686 int prev, fpwrst;
687 int trace_state = 0;
689 prev = (pwrdm->next_fpwrst == PWRDM_FUNC_PWRST_ON) ?
690 PWRDM_FUNC_PWRST_ON : _pwrdm_read_prev_fpwrst(pwrdm);
692 if (pwrdm->fpwrst != prev)
693 pwrdm->fpwrst_counter[prev - PWRDM_FPWRST_OFFSET]++;
695 _pwrdm_update_pwrst_time(pwrdm, prev);
697 /*
698 * If the power domain did not hit the desired state,
699 * generate a trace event with both the desired and hit states
700 */
701 if (pwrdm->next_fpwrst != prev) {
702 trace_state = (PWRDM_TRACE_STATES_FLAG |
703 pwrdm->next_fpwrst << 8 | prev);
704 trace_power_domain_target(pwrdm->name, trace_state,
705 smp_processor_id());
706 }
708 fpwrst = _pwrdm_read_fpwrst(pwrdm);
709 if (fpwrst != prev)
710 pwrdm->fpwrst_counter[fpwrst - PWRDM_FPWRST_OFFSET]++;
712 pwrdm->fpwrst = fpwrst;
714 return 0;
715 }
717 /* Public functions */
719 /**
720 * pwrdm_register_platform_funcs - register powerdomain implementation fns
721 * @po: func pointers for arch specific implementations
722 *
723 * Register the list of function pointers used to implement the
724 * powerdomain functions on different OMAP SoCs. Should be called
725 * before any other pwrdm_register*() function. Several function
726 * pointers in @po are required to be non-null for the powerdomain
727 * code to function: pwrdm_wait_transition, pwrdm_read_next_pwrst,
728 * pwrdm_read_pwrst, pwrdm_set_next_pwrst, pwrdm_set_logic_retst, and
729 * pwrdm_read_prev_pwrst. Returns -EINVAL if @po is null, -EEXIST if
730 * platform functions have already been registered, or 0 upon success.
731 */
732 int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
733 {
734 if (!po)
735 return -EINVAL;
737 if (arch_pwrdm)
738 return -EEXIST;
740 if (!po->pwrdm_wait_transition || !po->pwrdm_read_next_pwrst ||
741 !po->pwrdm_read_pwrst || !po->pwrdm_set_next_pwrst ||
742 !po->pwrdm_set_logic_retst || !po->pwrdm_read_prev_pwrst)
743 return -ENOENT;
745 arch_pwrdm = po;
747 return 0;
748 }
750 /**
751 * pwrdm_register_pwrdms - register SoC powerdomains
752 * @ps: pointer to an array of struct powerdomain to register
753 *
754 * Register the powerdomains available on a particular OMAP SoC. Must
755 * be called after pwrdm_register_platform_funcs(). May be called
756 * multiple times. Returns -EACCES if called before
757 * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
758 * null; or 0 upon success.
759 */
760 int pwrdm_register_pwrdms(struct powerdomain **ps)
761 {
762 struct powerdomain **p = NULL;
764 if (!arch_pwrdm)
765 return -EEXIST;
767 if (!ps)
768 return -EINVAL;
770 for (p = ps; *p; p++)
771 _pwrdm_register(*p);
773 return 0;
774 }
776 /**
777 * pwrdm_complete_init - set up the powerdomain layer
778 *
779 * Do whatever is necessary to initialize registered powerdomains and
780 * powerdomain code. Currently, this programs the next power state
781 * for each powerdomain to ON, and programs the memory bank power
782 * states to follow the powerdomain power states. This prevents
783 * powerdomains from unexpectedly losing context or entering high
784 * wakeup latency modes with non-power-management-enabled kernels.
785 * Must be called after pwrdm_register_pwrdms(). Returns -EACCES if
786 * called before pwrdm_register_pwrdms(), or 0 upon success.
787 */
788 int pwrdm_complete_init(void)
789 {
790 struct powerdomain *temp_p;
791 int i;
793 if (list_empty(&pwrdm_list))
794 return -EACCES;
796 list_for_each_entry(temp_p, &pwrdm_list, node) {
797 for (i = 0; i < temp_p->banks; i++) {
798 _pwrdm_set_mem_onst(temp_p, i, PWRDM_POWER_ON);
799 _pwrdm_set_mem_retst(temp_p, i, PWRDM_POWER_RET);
800 }
801 WARN_ON(pwrdm_set_next_fpwrst(temp_p, PWRDM_FUNC_PWRST_ON));
802 }
804 return 0;
805 }
807 /**
808 * pwrdm_lock - acquire a Linux spinlock on a powerdomain
809 * @pwrdm: struct powerdomain * to lock
810 *
811 * Acquire the powerdomain spinlock on @pwrdm. No return value.
812 */
813 void pwrdm_lock(struct powerdomain *pwrdm)
814 __acquires(&pwrdm->_lock)
815 {
816 spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
817 }
819 /**
820 * pwrdm_unlock - release a Linux spinlock on a powerdomain
821 * @pwrdm: struct powerdomain * to unlock
822 *
823 * Release the powerdomain spinlock on @pwrdm. No return value.
824 */
825 void pwrdm_unlock(struct powerdomain *pwrdm)
826 __releases(&pwrdm->_lock)
827 {
828 spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
829 }
831 /**
832 * pwrdm_lookup - look up a powerdomain by name, return a pointer
833 * @name: name of powerdomain
834 *
835 * Find a registered powerdomain by its name @name. Returns a pointer
836 * to the struct powerdomain if found, or NULL otherwise.
837 */
838 struct powerdomain *pwrdm_lookup(const char *name)
839 {
840 struct powerdomain *pwrdm;
842 if (!name)
843 return NULL;
845 pwrdm = _pwrdm_lookup(name);
847 return pwrdm;
848 }
850 /**
851 * pwrdm_for_each - call function on each registered clockdomain
852 * @fn: callback function *
853 *
854 * Call the supplied function @fn for each registered powerdomain.
855 * The callback function @fn can return anything but 0 to bail out
856 * early from the iterator. Returns the last return value of the
857 * callback function, which should be 0 for success or anything else
858 * to indicate failure; or -EINVAL if the function pointer is null.
859 */
860 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
861 void *user)
862 {
863 struct powerdomain *temp_pwrdm;
864 int ret = 0;
866 if (!fn)
867 return -EINVAL;
869 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
870 ret = (*fn)(temp_pwrdm, user);
871 if (ret)
872 break;
873 }
875 return ret;
876 }
878 /**
879 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
880 * @pwrdm: struct powerdomain * to add the clockdomain to
881 * @clkdm: struct clockdomain * to associate with a powerdomain
882 *
883 * Associate the clockdomain @clkdm with a powerdomain @pwrdm. This
884 * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
885 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
886 * or 0 upon success.
887 */
888 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
889 {
890 int i;
891 int ret = -EINVAL;
893 if (!pwrdm || !clkdm)
894 return -EINVAL;
896 pr_debug("powerdomain: %s: associating clockdomain %s\n",
897 pwrdm->name, clkdm->name);
899 for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
900 if (!pwrdm->pwrdm_clkdms[i])
901 break;
902 #ifdef DEBUG
903 if (pwrdm->pwrdm_clkdms[i] == clkdm) {
904 ret = -EINVAL;
905 goto pac_exit;
906 }
907 #endif
908 }
910 if (i == PWRDM_MAX_CLKDMS) {
911 pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n",
912 pwrdm->name, clkdm->name);
913 WARN_ON(1);
914 ret = -ENOMEM;
915 goto pac_exit;
916 }
918 pwrdm->pwrdm_clkdms[i] = clkdm;
920 ret = 0;
922 pac_exit:
923 return ret;
924 }
926 /**
927 * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
928 * @pwrdm: struct powerdomain * to add the clockdomain to
929 * @clkdm: struct clockdomain * to associate with a powerdomain
930 *
931 * Dissociate the clockdomain @clkdm from the powerdomain
932 * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
933 * if @clkdm was not associated with the powerdomain, or 0 upon
934 * success.
935 */
936 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
937 {
938 int ret = -EINVAL;
939 int i;
941 if (!pwrdm || !clkdm)
942 return -EINVAL;
944 pr_debug("powerdomain: %s: dissociating clockdomain %s\n",
945 pwrdm->name, clkdm->name);
947 for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
948 if (pwrdm->pwrdm_clkdms[i] == clkdm)
949 break;
951 if (i == PWRDM_MAX_CLKDMS) {
952 pr_debug("powerdomain: %s: clkdm %s not associated?!\n",
953 pwrdm->name, clkdm->name);
954 ret = -ENOENT;
955 goto pdc_exit;
956 }
958 pwrdm->pwrdm_clkdms[i] = NULL;
960 ret = 0;
962 pdc_exit:
963 return ret;
964 }
966 /**
967 * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
968 * @pwrdm: struct powerdomain * to iterate over
969 * @fn: callback function *
970 *
971 * Call the supplied function @fn for each clockdomain in the powerdomain
972 * @pwrdm. The callback function can return anything but 0 to bail
973 * out early from the iterator. Returns -EINVAL if presented with
974 * invalid pointers; or passes along the last return value of the
975 * callback function, which should be 0 for success or anything else
976 * to indicate failure.
977 */
978 int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
979 int (*fn)(struct powerdomain *pwrdm,
980 struct clockdomain *clkdm))
981 {
982 int ret = 0;
983 int i;
985 if (!fn)
986 return -EINVAL;
988 for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
989 ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
991 return ret;
992 }
994 /**
995 * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
996 * @pwrdm: struct powerdomain *
997 *
998 * Return a pointer to the struct voltageomain that the specified powerdomain
999 * @pwrdm exists in.
1000 */
1001 struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
1002 {
1003 return pwrdm->voltdm.ptr;
1004 }
1006 /**
1007 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
1008 * @pwrdm: struct powerdomain * to clear
1009 *
1010 * Clear the powerdomain's previous power state register @pwrdm.
1011 * Clears the entire register, including logic and memory bank
1012 * previous power states. Returns -EINVAL if the powerdomain pointer
1013 * is null, or returns 0 upon success.
1014 */
1015 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
1016 {
1017 int ret = -EINVAL;
1019 if (!pwrdm)
1020 return ret;
1022 /*
1023 * XXX Is there some way for us to skip powerdomains that
1024 * don't have a prev pwrst register?
1025 */
1027 /*
1028 * XXX should get the powerdomain's current state here;
1029 * warn & fail if it is not ON.
1030 */
1032 pr_debug("powerdomain: %s: clearing previous power state reg\n",
1033 pwrdm->name);
1035 pwrdm->_flags &= ~_PWRDM_PREV_FPWRST_IS_VALID;
1037 if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
1038 ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
1040 return ret;
1041 }
1043 /**
1044 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
1045 * @pwrdm: struct powerdomain *
1046 *
1047 * Enable automatic context save-and-restore upon power state change
1048 * for some devices in the powerdomain @pwrdm. Warning: this only
1049 * affects a subset of devices in a powerdomain; check the TRM
1050 * closely. Returns -EINVAL if the powerdomain pointer is null or if
1051 * the powerdomain does not support automatic save-and-restore, or
1052 * returns 0 upon success.
1053 */
1054 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
1055 {
1056 int ret = -EINVAL;
1058 if (!pwrdm)
1059 return ret;
1061 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
1062 return ret;
1064 pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name);
1066 if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
1067 ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
1069 return ret;
1070 }
1072 /**
1073 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
1074 * @pwrdm: struct powerdomain *
1075 *
1076 * Disable automatic context save-and-restore upon power state change
1077 * for some devices in the powerdomain @pwrdm. Warning: this only
1078 * affects a subset of devices in a powerdomain; check the TRM
1079 * closely. Returns -EINVAL if the powerdomain pointer is null or if
1080 * the powerdomain does not support automatic save-and-restore, or
1081 * returns 0 upon success.
1082 */
1083 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
1084 {
1085 int ret = -EINVAL;
1087 if (!pwrdm)
1088 return ret;
1090 if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
1091 return ret;
1093 pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name);
1095 if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
1096 ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
1098 return ret;
1099 }
1101 /**
1102 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
1103 * @pwrdm: struct powerdomain *
1104 *
1105 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
1106 * for some devices, or 0 if it does not.
1107 */
1108 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
1109 {
1110 return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
1111 }
1113 int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
1114 {
1115 int ret = 0;
1117 if (!pwrdm || !arch_pwrdm)
1118 return -EINVAL;
1120 if (!(pwrdm->flags & PWRDM_ACTIVE_WITH_KERNEL))
1121 ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
1123 if (!ret)
1124 _pwrdm_state_switch(pwrdm);
1126 return ret;
1127 }
1129 int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
1130 {
1131 int ret;
1133 pwrdm_lock(pwrdm);
1134 ret = pwrdm_state_switch_nolock(pwrdm);
1135 pwrdm_unlock(pwrdm);
1137 return ret;
1138 }
1140 int pwrdm_pre_transition(struct powerdomain *pwrdm)
1141 {
1142 if (pwrdm)
1143 _pwrdm_pre_transition_cb(pwrdm, NULL);
1144 else
1145 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
1147 return 0;
1148 }
1150 int pwrdm_post_transition(struct powerdomain *pwrdm)
1151 {
1152 if (pwrdm)
1153 _pwrdm_post_transition_cb(pwrdm, NULL);
1154 else
1155 pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
1157 return 0;
1158 }
1160 /**
1161 * pwrdm_get_context_loss_count - get powerdomain's context loss count
1162 * @pwrdm: struct powerdomain * to wait for
1163 *
1164 * Context loss count is the sum of powerdomain off-mode counter, the
1165 * logic off counter and the per-bank memory off counter. Returns negative
1166 * (and WARNs) upon error, otherwise, returns the context loss count.
1167 */
1168 int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
1169 {
1170 int count;
1172 if (!pwrdm) {
1173 WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
1174 return -ENODEV;
1175 }
1177 count = pwrdm->fpwrst_counter[PWRDM_FUNC_PWRST_OFF -
1178 PWRDM_FPWRST_OFFSET];
1179 count += pwrdm->fpwrst_counter[PWRDM_FUNC_PWRST_OSWR -
1180 PWRDM_FPWRST_OFFSET];
1182 /*
1183 * Context loss count has to be a non-negative value. Clear the sign
1184 * bit to get a value range from 0 to INT_MAX.
1185 */
1186 count &= INT_MAX;
1188 pr_debug("powerdomain: %s: context loss count = %d\n",
1189 pwrdm->name, count);
1191 return count;
1192 }
1194 /**
1195 * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
1196 * @pwrdm: struct powerdomain *
1197 *
1198 * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
1199 * can lose either memory or logic context or if @pwrdm is invalid, or
1200 * returns 0 otherwise. This function is not concerned with how the
1201 * powerdomain registers are programmed (i.e., to go off or not); it's
1202 * concerned with whether it's ever possible for this powerdomain to
1203 * go off while some other part of the chip is active. This function
1204 * assumes that every powerdomain can go to either ON or INACTIVE.
1205 */
1206 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
1207 {
1208 int i;
1210 if (IS_ERR_OR_NULL(pwrdm)) {
1211 pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
1212 __func__);
1213 return 1;
1214 }
1216 if (pwrdm->pwrsts & PWRSTS_OFF)
1217 return 1;
1219 if (pwrdm->pwrsts & PWRSTS_RET) {
1220 if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
1221 return 1;
1223 for (i = 0; i < pwrdm->banks; i++)
1224 if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
1225 return 1;
1226 }
1228 for (i = 0; i < pwrdm->banks; i++)
1229 if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
1230 return 1;
1232 return 0;
1233 }
1235 /* Public functions for functional power state handling */
1237 /**
1238 * pwrdm_convert_fpwrst_to_name - return the name of a functional power state
1239 * @fpwrst: functional power state to return the name of
1240 *
1241 * Return a pointer to a string with the human-readable name of the
1242 * functional power state (e.g., "ON", "CSWR", etc.) Intended for use
1243 * in debugging. Returns NULL if @fpwrst is outside the range of the
1244 * known functional power states.
1245 */
1246 const char *pwrdm_convert_fpwrst_to_name(u8 fpwrst)
1247 {
1248 if (fpwrst < PWRDM_FPWRST_OFFSET || fpwrst >= PWRDM_MAX_FUNC_PWRSTS)
1249 return NULL;
1251 return _fpwrst_names[fpwrst - PWRDM_FPWRST_OFFSET];
1252 }
1254 /**
1255 * pwrdm_set_next_fpwrst - set next powerdomain functional power state
1256 * @pwrdm: struct powerdomain * to set
1257 * @fpwrst: one of the PWRDM_POWER_* macros
1258 *
1259 * Set the powerdomain @pwrdm's next power state to @fpwrst. The
1260 * powerdomain may not enter this state immediately if the
1261 * preconditions for this state have not been satisfied. Returns
1262 * -EINVAL if the powerdomain pointer is null or if the power state is
1263 * invalid for the powerdomin, or returns 0 upon success.
1264 */
1265 int pwrdm_set_next_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
1266 {
1267 u8 pwrst, logic;
1268 int ret;
1270 if (!pwrdm || IS_ERR(pwrdm))
1271 return -EINVAL;
1273 /*
1274 * XXX Should return an error, but this means that our PM code
1275 * will need to be much more careful about what it programs
1276 */
1277 if (!_pwrdm_pwrst_is_controllable(pwrdm))
1278 return 0;
1280 ret = _pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst, &pwrst, &logic);
1281 if (ret)
1282 return ret;
1284 if (pwrdm->_flags & _PWRDM_NEXT_FPWRST_IS_VALID &&
1285 pwrdm->next_fpwrst == fpwrst)
1286 return 0;
1288 pr_debug("%s: set fpwrst %0x to pwrdm %s\n", __func__, fpwrst,
1289 pwrdm->name);
1291 /* Trace the pwrdm desired target state */
1292 trace_power_domain_target(pwrdm->name, fpwrst, smp_processor_id());
1294 pwrdm_lock(pwrdm);
1295 ret = _set_logic_retst_and_pwrdm_pwrst(pwrdm, logic, pwrst);
1296 if (!ret) {
1297 pwrdm->next_fpwrst = fpwrst;
1298 pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
1299 }
1300 pwrdm_unlock(pwrdm);
1302 return ret;
1303 }
1305 /**
1306 * pwrdm_read_next_fpwrst - get next powerdomain functional power state
1307 * @pwrdm: struct powerdomain * to get power state
1308 *
1309 * Return the powerdomain @pwrdm's next functional power state.
1310 * Returns -EINVAL if the powerdomain pointer is null or returns
1311 * the next power state upon success.
1312 */
1313 int pwrdm_read_next_fpwrst(struct powerdomain *pwrdm)
1314 {
1315 int ret;
1317 if (!pwrdm)
1318 return -EINVAL;
1320 pwrdm_lock(pwrdm);
1321 ret = _pwrdm_read_next_fpwrst(pwrdm);
1322 pwrdm_unlock(pwrdm);
1324 return ret;
1325 }
1327 /**
1328 * pwrdm_set_fpwrst - program next powerdomain functional power state
1329 * @pwrdm: struct powerdomain * to set
1330 * @fpwrst: power domain functional state, one of the PWRDM_FUNC_* macros
1331 *
1332 * This programs the pwrdm next functional state, sets the dependencies
1333 * and waits for the state to be applied.
1334 */
1335 int pwrdm_set_fpwrst(struct powerdomain *pwrdm, enum pwrdm_func_state fpwrst)
1336 {
1337 u8 next_fpwrst, pwrst, logic, sleep_switch;
1338 int ret = 0;
1339 bool hwsup = false;
1341 if (!pwrdm || IS_ERR(pwrdm) || !arch_pwrdm)
1342 return -EINVAL;
1344 /*
1345 * XXX Should return an error, but this means that our PM code
1346 * will need to be much more careful about what it programs
1347 */
1348 if (!_pwrdm_pwrst_is_controllable(pwrdm))
1349 return 0;
1351 ret = _pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst, &pwrst, &logic);
1352 if (ret)
1353 return -EINVAL;
1355 pr_debug("%s: pwrdm %s: set fpwrst %0x\n", __func__, pwrdm->name,
1356 fpwrst);
1358 pwrdm_lock(pwrdm);
1360 next_fpwrst = _pwrdm_read_next_fpwrst(pwrdm);
1361 if (next_fpwrst == fpwrst)
1362 goto psf_out;
1364 /* Trace the pwrdm desired target state */
1365 trace_power_domain_target(pwrdm->name, next_fpwrst,
1366 smp_processor_id());
1368 sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, fpwrst,
1369 &hwsup);
1370 if (sleep_switch == ERROR_SWITCH) {
1371 ret = -EINVAL;
1372 goto psf_out;
1373 }
1375 ret = _set_logic_retst_and_pwrdm_pwrst(pwrdm, logic, pwrst);
1376 if (ret) {
1377 pr_err("%s: unable to set power state of powerdomain: %s\n",
1378 __func__, pwrdm->name);
1379 } else {
1380 pwrdm->next_fpwrst = fpwrst;
1381 pwrdm->_flags |= _PWRDM_NEXT_FPWRST_IS_VALID;
1382 }
1384 _pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup);
1386 psf_out:
1387 pwrdm_unlock(pwrdm);
1389 return ret;
1390 }
1392 /**
1393 * pwrdm_read_fpwrst - get current functional powerdomain power state
1394 * @pwrdm: struct powerdomain * to get current functional power state
1395 *
1396 * Return the powerdomain @pwrdm's current functional power state.
1397 * Returns -EINVAL if the powerdomain pointer is null or returns the
1398 * current power state upon success.
1399 */
1400 int pwrdm_read_fpwrst(struct powerdomain *pwrdm)
1401 {
1402 int ret;
1404 if (!pwrdm || !arch_pwrdm)
1405 return -EINVAL;
1407 if (!_pwrdm_pwrst_can_change(pwrdm))
1408 return PWRDM_FUNC_PWRST_ON;
1410 pwrdm_lock(pwrdm);
1411 ret = _pwrdm_read_fpwrst(pwrdm);
1412 pwrdm_unlock(pwrdm);
1414 return ret;
1415 }
1417 /**
1418 * pwrdm_read_prev_fpwrst - get previous powerdomain functional power state
1419 * @pwrdm: struct powerdomain * to get previous functional power state
1420 *
1421 * Return the powerdomain @pwrdm's previous functional power state.
1422 * Returns -EINVAL if the powerdomain pointer is null or returns the
1423 * previous functional power state upon success.
1424 */
1425 int pwrdm_read_prev_fpwrst(struct powerdomain *pwrdm)
1426 {
1427 int ret = -EINVAL;
1429 if (!pwrdm || !arch_pwrdm)
1430 return -EINVAL;
1432 if (!_pwrdm_pwrst_can_change(pwrdm))
1433 return PWRDM_FUNC_PWRST_ON;
1435 pwrdm_lock(pwrdm);
1436 ret = _pwrdm_read_prev_fpwrst(pwrdm);
1437 pwrdm_unlock(pwrdm);
1439 return ret;
1440 }
1442 /**
1443 * pwrdm_supports_fpwrst - does the powerdomain @pwrdm support the @fpwrst power
1444 * state?
1445 * @pwrdm: struct powerdomain * pointing to a powerdomain to test
1446 * @fpwrst: functional power state
1447 *
1448 * Returns true if the powerdomain pointed to by @pwrdm can enter the
1449 * functional power state @fpwrst, or false if not.
1450 */
1451 bool pwrdm_supports_fpwrst(struct powerdomain *pwrdm, u8 fpwrst)
1452 {
1453 u8 pwrst, logic;
1454 int ret;
1456 if (!pwrdm || IS_ERR(pwrdm))
1457 return false;
1459 ret = _pwrdm_fpwrst_to_pwrst(pwrdm, fpwrst, &pwrst, &logic);
1460 if (ret)
1461 return false;
1463 if (pwrdm->pwrsts_logic_ret && pwrst == PWRDM_POWER_RET &&
1464 !(pwrdm->pwrsts_logic_ret & (1 << logic)))
1465 return false;
1467 if (!(pwrdm->pwrsts & (1 << pwrst)))
1468 return false;
1470 return true;
1471 }
1473 /* Powerdomain debugfs-related functions */
1475 /**
1476 * pwrdm_dbg_show_counter - generate debugfs data for the pwrdm pwrst counters
1477 * @pwrdm: struct powerdomain * to generate debugfs data for
1478 * @seq_file: struct seq_file * to write data to
1479 *
1480 * Dump the powerdomain @pwrdm's power state counters (and current
1481 * power state) to the seq_file @seq_file. Currently called by the
1482 * mach-omap2/pm-debug.c code. Returns 0.
1483 */
1484 int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *seq_file)
1485 {
1486 struct seq_file *s = (struct seq_file *)seq_file;
1487 int i;
1488 u8 curr_fpwrst;
1490 if (!_pwrdm_pwrst_can_change(pwrdm))
1491 return 0;
1493 pwrdm_lock(pwrdm);
1495 curr_fpwrst = _pwrdm_read_fpwrst(pwrdm);
1496 if (pwrdm->fpwrst != curr_fpwrst)
1497 pr_err("pwrdm state mismatch(%s) %s != %s\n",
1498 pwrdm->name,
1499 pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst),
1500 pwrdm_convert_fpwrst_to_name(curr_fpwrst));
1502 seq_printf(s, "%s (%s)", pwrdm->name,
1503 pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
1504 for (i = PWRDM_FPWRST_OFFSET; i < PWRDM_MAX_FUNC_PWRSTS; i++)
1505 seq_printf(s, ",%s:%d", pwrdm_convert_fpwrst_to_name(i),
1506 pwrdm->fpwrst_counter[i - PWRDM_FPWRST_OFFSET]);
1508 seq_printf(s, "\n");
1510 pwrdm_unlock(pwrdm);
1512 return 0;
1513 }
1515 /**
1516 * pwrdm_dbg_show_timer - generate debugfs data for the pwrdm pwrst timers
1517 * @pwrdm: struct powerdomain * to generate debugfs data for
1518 * @seq_file: struct seq_file * to write data to
1519 *
1520 * Dump the powerdomain @pwrdm's power state residency duration timings
1521 * to the seq_file @seq_file. Currently called by the mach-omap2/pm-debug.c
1522 * code. Returns 0.
1523 */
1524 int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *seq_file)
1525 {
1526 #ifdef CONFIG_PM_DEBUG
1527 struct seq_file *s = (struct seq_file *)seq_file;
1528 int i;
1530 if (!_pwrdm_pwrst_can_change(pwrdm))
1531 return 0;
1533 pwrdm_lock(pwrdm);
1535 pwrdm_state_switch_nolock(pwrdm);
1537 seq_printf(s, "%s (%s)", pwrdm->name,
1538 pwrdm_convert_fpwrst_to_name(pwrdm->fpwrst));
1540 for (i = 0; i < PWRDM_FPWRSTS_COUNT; i++)
1541 seq_printf(s, ",%s:%lld",
1542 pwrdm_convert_fpwrst_to_name(i + PWRDM_FPWRST_OFFSET),
1543 pwrdm->fpwrst_timer[i]);
1545 seq_printf(s, "\n");
1547 pwrdm_unlock(pwrdm);
1548 #endif
1549 return 0;
1550 }