]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/blob - arch/arm/mach-omap2/powerdomain.c
ARM: OMAP5/DRA7: hwmod: add ADDR_TYPE_RT to bb2d address flags
[android-sdk/kernel-video.git] / arch / arm / mach-omap2 / powerdomain.c
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;
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)
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;
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)
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         }
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)
226         return (!pwrdm->pwrsts || pwrdm->pwrsts == PWRSTS_ON) ? 0 : 1;
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)
241         return _pwrdm_pwrst_is_controllable(pwrdm);
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)
254         return (!pwrdm->pwrsts_logic_ret ||
255                 pwrdm->pwrsts_logic_ret == PWRSTS_RET) ? 0 : 1;
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)
270         return _pwrdm_logic_retst_is_controllable(pwrdm);
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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
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)
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;
650 static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
816         spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
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)
828         spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
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)
840         struct powerdomain *pwrdm;
842         if (!name)
843                 return NULL;
845         pwrdm = _pwrdm_lookup(name);
847         return pwrdm;
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)
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;
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)
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;
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)
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;
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))
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;
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)
1003         return pwrdm->voltdm.ptr;
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)
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;
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)
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;
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)
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;
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)
1110         return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
1113 int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
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;
1129 int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
1131         int ret;
1133         pwrdm_lock(pwrdm);
1134         ret = pwrdm_state_switch_nolock(pwrdm);
1135         pwrdm_unlock(pwrdm);
1137         return ret;
1140 int pwrdm_pre_transition(struct powerdomain *pwrdm)
1142         if (pwrdm)
1143                 _pwrdm_pre_transition_cb(pwrdm, NULL);
1144         else
1145                 pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
1147         return 0;
1150 int pwrdm_post_transition(struct powerdomain *pwrdm)
1152         if (pwrdm)
1153                 _pwrdm_post_transition_cb(pwrdm, NULL);
1154         else
1155                 pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
1157         return 0;
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)
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;
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)
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;
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)
1248         if (fpwrst < PWRDM_FPWRST_OFFSET || fpwrst >= PWRDM_MAX_FUNC_PWRSTS)
1249                 return NULL;
1251         return _fpwrst_names[fpwrst - PWRDM_FPWRST_OFFSET];
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;
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)
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;