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