Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * OMAP powerdomain control
0004  *
0005  * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
0006  * Copyright (C) 2007-2011 Nokia Corporation
0007  *
0008  * Written by Paul Walmsley
0009  * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
0010  * State counting code by Tero Kristo <tero.kristo@nokia.com>
0011  */
0012 #undef DEBUG
0013 
0014 #include <linux/cpu_pm.h>
0015 #include <linux/kernel.h>
0016 #include <linux/types.h>
0017 #include <linux/list.h>
0018 #include <linux/errno.h>
0019 #include <linux/string.h>
0020 #include <linux/spinlock.h>
0021 #include <trace/events/power.h>
0022 
0023 #include "cm2xxx_3xxx.h"
0024 #include "prcm44xx.h"
0025 #include "cm44xx.h"
0026 #include "prm2xxx_3xxx.h"
0027 #include "prm44xx.h"
0028 
0029 #include <asm/cpu.h>
0030 
0031 #include "powerdomain.h"
0032 #include "clockdomain.h"
0033 #include "voltage.h"
0034 
0035 #include "soc.h"
0036 #include "pm.h"
0037 
0038 #define PWRDM_TRACE_STATES_FLAG (1<<31)
0039 
0040 void pwrdms_save_context(void);
0041 void pwrdms_restore_context(void);
0042 
0043 enum {
0044     PWRDM_STATE_NOW = 0,
0045     PWRDM_STATE_PREV,
0046 };
0047 
0048 /*
0049  * Types of sleep_switch used internally in omap_set_pwrdm_state()
0050  * and its associated static functions
0051  *
0052  * XXX Better documentation is needed here
0053  */
0054 #define ALREADYACTIVE_SWITCH        0
0055 #define FORCEWAKEUP_SWITCH      1
0056 #define LOWPOWERSTATE_SWITCH        2
0057 
0058 /* pwrdm_list contains all registered struct powerdomains */
0059 static LIST_HEAD(pwrdm_list);
0060 
0061 static struct pwrdm_ops *arch_pwrdm;
0062 
0063 /* Private functions */
0064 
0065 static struct powerdomain *_pwrdm_lookup(const char *name)
0066 {
0067     struct powerdomain *pwrdm, *temp_pwrdm;
0068 
0069     pwrdm = NULL;
0070 
0071     list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
0072         if (!strcmp(name, temp_pwrdm->name)) {
0073             pwrdm = temp_pwrdm;
0074             break;
0075         }
0076     }
0077 
0078     return pwrdm;
0079 }
0080 
0081 /**
0082  * _pwrdm_register - register a powerdomain
0083  * @pwrdm: struct powerdomain * to register
0084  *
0085  * Adds a powerdomain to the internal powerdomain list.  Returns
0086  * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
0087  * already registered by the provided name, or 0 upon success.
0088  */
0089 static int _pwrdm_register(struct powerdomain *pwrdm)
0090 {
0091     int i;
0092     struct voltagedomain *voltdm;
0093 
0094     if (!pwrdm || !pwrdm->name)
0095         return -EINVAL;
0096 
0097     if (cpu_is_omap44xx() &&
0098         pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
0099         pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
0100                pwrdm->name);
0101         return -EINVAL;
0102     }
0103 
0104     if (_pwrdm_lookup(pwrdm->name))
0105         return -EEXIST;
0106 
0107     if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm)
0108         if (!arch_pwrdm->pwrdm_has_voltdm())
0109             goto skip_voltdm;
0110 
0111     voltdm = voltdm_lookup(pwrdm->voltdm.name);
0112     if (!voltdm) {
0113         pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
0114                pwrdm->name, pwrdm->voltdm.name);
0115         return -EINVAL;
0116     }
0117     pwrdm->voltdm.ptr = voltdm;
0118     INIT_LIST_HEAD(&pwrdm->voltdm_node);
0119 skip_voltdm:
0120     spin_lock_init(&pwrdm->_lock);
0121 
0122     list_add(&pwrdm->node, &pwrdm_list);
0123 
0124     /* Initialize the powerdomain's state counter */
0125     for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
0126         pwrdm->state_counter[i] = 0;
0127 
0128     pwrdm->ret_logic_off_counter = 0;
0129     for (i = 0; i < pwrdm->banks; i++)
0130         pwrdm->ret_mem_off_counter[i] = 0;
0131 
0132     if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
0133         arch_pwrdm->pwrdm_wait_transition(pwrdm);
0134     pwrdm->state = pwrdm_read_pwrst(pwrdm);
0135     pwrdm->state_counter[pwrdm->state] = 1;
0136 
0137     pr_debug("powerdomain: registered %s\n", pwrdm->name);
0138 
0139     return 0;
0140 }
0141 
0142 static void _update_logic_membank_counters(struct powerdomain *pwrdm)
0143 {
0144     int i;
0145     u8 prev_logic_pwrst, prev_mem_pwrst;
0146 
0147     prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
0148     if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
0149         (prev_logic_pwrst == PWRDM_POWER_OFF))
0150         pwrdm->ret_logic_off_counter++;
0151 
0152     for (i = 0; i < pwrdm->banks; i++) {
0153         prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
0154 
0155         if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
0156             (prev_mem_pwrst == PWRDM_POWER_OFF))
0157             pwrdm->ret_mem_off_counter[i]++;
0158     }
0159 }
0160 
0161 static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
0162 {
0163 
0164     int prev, next, state, trace_state = 0;
0165 
0166     if (pwrdm == NULL)
0167         return -EINVAL;
0168 
0169     state = pwrdm_read_pwrst(pwrdm);
0170 
0171     switch (flag) {
0172     case PWRDM_STATE_NOW:
0173         prev = pwrdm->state;
0174         break;
0175     case PWRDM_STATE_PREV:
0176         prev = pwrdm_read_prev_pwrst(pwrdm);
0177         if (pwrdm->state != prev)
0178             pwrdm->state_counter[prev]++;
0179         if (prev == PWRDM_POWER_RET)
0180             _update_logic_membank_counters(pwrdm);
0181         /*
0182          * If the power domain did not hit the desired state,
0183          * generate a trace event with both the desired and hit states
0184          */
0185         next = pwrdm_read_next_pwrst(pwrdm);
0186         if (next != prev) {
0187             trace_state = (PWRDM_TRACE_STATES_FLAG |
0188                        ((next & OMAP_POWERSTATE_MASK) << 8) |
0189                        ((prev & OMAP_POWERSTATE_MASK) << 0));
0190             trace_power_domain_target_rcuidle(pwrdm->name,
0191                               trace_state,
0192                               raw_smp_processor_id());
0193         }
0194         break;
0195     default:
0196         return -EINVAL;
0197     }
0198 
0199     if (state != prev)
0200         pwrdm->state_counter[state]++;
0201 
0202     pm_dbg_update_time(pwrdm, prev);
0203 
0204     pwrdm->state = state;
0205 
0206     return 0;
0207 }
0208 
0209 static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
0210 {
0211     pwrdm_clear_all_prev_pwrst(pwrdm);
0212     _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
0213     return 0;
0214 }
0215 
0216 static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
0217 {
0218     _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
0219     return 0;
0220 }
0221 
0222 /**
0223  * _pwrdm_save_clkdm_state_and_activate - prepare for power state change
0224  * @pwrdm: struct powerdomain * to operate on
0225  * @curr_pwrst: current power state of @pwrdm
0226  * @pwrst: power state to switch to
0227  *
0228  * Determine whether the powerdomain needs to be turned on before
0229  * attempting to switch power states.  Called by
0230  * omap_set_pwrdm_state().  NOTE that if the powerdomain contains
0231  * multiple clockdomains, this code assumes that the first clockdomain
0232  * supports software-supervised wakeup mode - potentially a problem.
0233  * Returns the power state switch mode currently in use (see the
0234  * "Types of sleep_switch" comment above).
0235  */
0236 static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
0237                            u8 curr_pwrst, u8 pwrst)
0238 {
0239     u8 sleep_switch;
0240 
0241     if (curr_pwrst < PWRDM_POWER_ON) {
0242         if (curr_pwrst > pwrst &&
0243             pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
0244             arch_pwrdm->pwrdm_set_lowpwrstchange) {
0245             sleep_switch = LOWPOWERSTATE_SWITCH;
0246         } else {
0247             clkdm_deny_idle_nolock(pwrdm->pwrdm_clkdms[0]);
0248             sleep_switch = FORCEWAKEUP_SWITCH;
0249         }
0250     } else {
0251         sleep_switch = ALREADYACTIVE_SWITCH;
0252     }
0253 
0254     return sleep_switch;
0255 }
0256 
0257 /**
0258  * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
0259  * @pwrdm: struct powerdomain * to operate on
0260  * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
0261  *
0262  * Restore the clockdomain state perturbed by
0263  * _pwrdm_save_clkdm_state_and_activate(), and call the power state
0264  * bookkeeping code.  Called by omap_set_pwrdm_state().  NOTE that if
0265  * the powerdomain contains multiple clockdomains, this assumes that
0266  * the first associated clockdomain supports either
0267  * hardware-supervised idle control in the register, or
0268  * software-supervised sleep.  No return value.
0269  */
0270 static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
0271                        u8 sleep_switch)
0272 {
0273     switch (sleep_switch) {
0274     case FORCEWAKEUP_SWITCH:
0275         clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
0276         break;
0277     case LOWPOWERSTATE_SWITCH:
0278         if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
0279             arch_pwrdm->pwrdm_set_lowpwrstchange)
0280             arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
0281         pwrdm_state_switch_nolock(pwrdm);
0282         break;
0283     }
0284 }
0285 
0286 /* Public functions */
0287 
0288 /**
0289  * pwrdm_register_platform_funcs - register powerdomain implementation fns
0290  * @po: func pointers for arch specific implementations
0291  *
0292  * Register the list of function pointers used to implement the
0293  * powerdomain functions on different OMAP SoCs.  Should be called
0294  * before any other pwrdm_register*() function.  Returns -EINVAL if
0295  * @po is null, -EEXIST if platform functions have already been
0296  * registered, or 0 upon success.
0297  */
0298 int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
0299 {
0300     if (!po)
0301         return -EINVAL;
0302 
0303     if (arch_pwrdm)
0304         return -EEXIST;
0305 
0306     arch_pwrdm = po;
0307 
0308     return 0;
0309 }
0310 
0311 /**
0312  * pwrdm_register_pwrdms - register SoC powerdomains
0313  * @ps: pointer to an array of struct powerdomain to register
0314  *
0315  * Register the powerdomains available on a particular OMAP SoC.  Must
0316  * be called after pwrdm_register_platform_funcs().  May be called
0317  * multiple times.  Returns -EACCES if called before
0318  * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
0319  * null; or 0 upon success.
0320  */
0321 int pwrdm_register_pwrdms(struct powerdomain **ps)
0322 {
0323     struct powerdomain **p = NULL;
0324 
0325     if (!arch_pwrdm)
0326         return -EEXIST;
0327 
0328     if (!ps)
0329         return -EINVAL;
0330 
0331     for (p = ps; *p; p++)
0332         _pwrdm_register(*p);
0333 
0334     return 0;
0335 }
0336 
0337 static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
0338 {
0339     switch (cmd) {
0340     case CPU_CLUSTER_PM_ENTER:
0341         if (enable_off_mode)
0342             pwrdms_save_context();
0343         break;
0344     case CPU_CLUSTER_PM_EXIT:
0345         if (enable_off_mode)
0346             pwrdms_restore_context();
0347         break;
0348     }
0349 
0350     return NOTIFY_OK;
0351 }
0352 
0353 /**
0354  * pwrdm_complete_init - set up the powerdomain layer
0355  *
0356  * Do whatever is necessary to initialize registered powerdomains and
0357  * powerdomain code.  Currently, this programs the next power state
0358  * for each powerdomain to ON.  This prevents powerdomains from
0359  * unexpectedly losing context or entering high wakeup latency modes
0360  * with non-power-management-enabled kernels.  Must be called after
0361  * pwrdm_register_pwrdms().  Returns -EACCES if called before
0362  * pwrdm_register_pwrdms(), or 0 upon success.
0363  */
0364 int pwrdm_complete_init(void)
0365 {
0366     struct powerdomain *temp_p;
0367     static struct notifier_block nb;
0368 
0369     if (list_empty(&pwrdm_list))
0370         return -EACCES;
0371 
0372     list_for_each_entry(temp_p, &pwrdm_list, node)
0373         pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
0374 
0375     /* Only AM43XX can lose pwrdm context during rtc-ddr suspend */
0376     if (soc_is_am43xx()) {
0377         nb.notifier_call = cpu_notifier;
0378         cpu_pm_register_notifier(&nb);
0379     }
0380 
0381     return 0;
0382 }
0383 
0384 /**
0385  * pwrdm_lock - acquire a Linux spinlock on a powerdomain
0386  * @pwrdm: struct powerdomain * to lock
0387  *
0388  * Acquire the powerdomain spinlock on @pwrdm.  No return value.
0389  */
0390 void pwrdm_lock(struct powerdomain *pwrdm)
0391     __acquires(&pwrdm->_lock)
0392 {
0393     spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
0394 }
0395 
0396 /**
0397  * pwrdm_unlock - release a Linux spinlock on a powerdomain
0398  * @pwrdm: struct powerdomain * to unlock
0399  *
0400  * Release the powerdomain spinlock on @pwrdm.  No return value.
0401  */
0402 void pwrdm_unlock(struct powerdomain *pwrdm)
0403     __releases(&pwrdm->_lock)
0404 {
0405     spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
0406 }
0407 
0408 /**
0409  * pwrdm_lookup - look up a powerdomain by name, return a pointer
0410  * @name: name of powerdomain
0411  *
0412  * Find a registered powerdomain by its name @name.  Returns a pointer
0413  * to the struct powerdomain if found, or NULL otherwise.
0414  */
0415 struct powerdomain *pwrdm_lookup(const char *name)
0416 {
0417     struct powerdomain *pwrdm;
0418 
0419     if (!name)
0420         return NULL;
0421 
0422     pwrdm = _pwrdm_lookup(name);
0423 
0424     return pwrdm;
0425 }
0426 
0427 /**
0428  * pwrdm_for_each - call function on each registered clockdomain
0429  * @fn: callback function *
0430  *
0431  * Call the supplied function @fn for each registered powerdomain.
0432  * The callback function @fn can return anything but 0 to bail out
0433  * early from the iterator.  Returns the last return value of the
0434  * callback function, which should be 0 for success or anything else
0435  * to indicate failure; or -EINVAL if the function pointer is null.
0436  */
0437 int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
0438            void *user)
0439 {
0440     struct powerdomain *temp_pwrdm;
0441     int ret = 0;
0442 
0443     if (!fn)
0444         return -EINVAL;
0445 
0446     list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
0447         ret = (*fn)(temp_pwrdm, user);
0448         if (ret)
0449             break;
0450     }
0451 
0452     return ret;
0453 }
0454 
0455 /**
0456  * pwrdm_add_clkdm - add a clockdomain to a powerdomain
0457  * @pwrdm: struct powerdomain * to add the clockdomain to
0458  * @clkdm: struct clockdomain * to associate with a powerdomain
0459  *
0460  * Associate the clockdomain @clkdm with a powerdomain @pwrdm.  This
0461  * enables the use of pwrdm_for_each_clkdm().  Returns -EINVAL if
0462  * presented with invalid pointers; -ENOMEM if memory could not be allocated;
0463  * or 0 upon success.
0464  */
0465 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
0466 {
0467     int i;
0468     int ret = -EINVAL;
0469 
0470     if (!pwrdm || !clkdm)
0471         return -EINVAL;
0472 
0473     pr_debug("powerdomain: %s: associating clockdomain %s\n",
0474          pwrdm->name, clkdm->name);
0475 
0476     for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
0477         if (!pwrdm->pwrdm_clkdms[i])
0478             break;
0479 #ifdef DEBUG
0480         if (pwrdm->pwrdm_clkdms[i] == clkdm) {
0481             ret = -EINVAL;
0482             goto pac_exit;
0483         }
0484 #endif
0485     }
0486 
0487     if (i == PWRDM_MAX_CLKDMS) {
0488         pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n",
0489              pwrdm->name, clkdm->name);
0490         WARN_ON(1);
0491         ret = -ENOMEM;
0492         goto pac_exit;
0493     }
0494 
0495     pwrdm->pwrdm_clkdms[i] = clkdm;
0496 
0497     ret = 0;
0498 
0499 pac_exit:
0500     return ret;
0501 }
0502 
0503 /**
0504  * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
0505  * @pwrdm: struct powerdomain *
0506  *
0507  * Return the number of controllable memory banks in powerdomain @pwrdm,
0508  * starting with 1.  Returns -EINVAL if the powerdomain pointer is null.
0509  */
0510 int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
0511 {
0512     if (!pwrdm)
0513         return -EINVAL;
0514 
0515     return pwrdm->banks;
0516 }
0517 
0518 /**
0519  * pwrdm_set_next_pwrst - set next powerdomain power state
0520  * @pwrdm: struct powerdomain * to set
0521  * @pwrst: one of the PWRDM_POWER_* macros
0522  *
0523  * Set the powerdomain @pwrdm's next power state to @pwrst.  The powerdomain
0524  * may not enter this state immediately if the preconditions for this state
0525  * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
0526  * null or if the power state is invalid for the powerdomin, or returns 0
0527  * upon success.
0528  */
0529 int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
0530 {
0531     int ret = -EINVAL;
0532 
0533     if (!pwrdm)
0534         return -EINVAL;
0535 
0536     if (!(pwrdm->pwrsts & (1 << pwrst)))
0537         return -EINVAL;
0538 
0539     pr_debug("powerdomain: %s: setting next powerstate to %0x\n",
0540          pwrdm->name, pwrst);
0541 
0542     if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
0543         /* Trace the pwrdm desired target state */
0544         trace_power_domain_target_rcuidle(pwrdm->name, pwrst,
0545                           raw_smp_processor_id());
0546         /* Program the pwrdm desired target state */
0547         ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
0548     }
0549 
0550     return ret;
0551 }
0552 
0553 /**
0554  * pwrdm_read_next_pwrst - get next powerdomain power state
0555  * @pwrdm: struct powerdomain * to get power state
0556  *
0557  * Return the powerdomain @pwrdm's next power state.  Returns -EINVAL
0558  * if the powerdomain pointer is null or returns the next power state
0559  * upon success.
0560  */
0561 int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
0562 {
0563     int ret = -EINVAL;
0564 
0565     if (!pwrdm)
0566         return -EINVAL;
0567 
0568     if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
0569         ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
0570 
0571     return ret;
0572 }
0573 
0574 /**
0575  * pwrdm_read_pwrst - get current powerdomain power state
0576  * @pwrdm: struct powerdomain * to get power state
0577  *
0578  * Return the powerdomain @pwrdm's current power state. Returns -EINVAL
0579  * if the powerdomain pointer is null or returns the current power state
0580  * upon success. Note that if the power domain only supports the ON state
0581  * then just return ON as the current state.
0582  */
0583 int pwrdm_read_pwrst(struct powerdomain *pwrdm)
0584 {
0585     int ret = -EINVAL;
0586 
0587     if (!pwrdm)
0588         return -EINVAL;
0589 
0590     if (pwrdm->pwrsts == PWRSTS_ON)
0591         return PWRDM_POWER_ON;
0592 
0593     if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
0594         ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
0595 
0596     return ret;
0597 }
0598 
0599 /**
0600  * pwrdm_read_prev_pwrst - get previous powerdomain power state
0601  * @pwrdm: struct powerdomain * to get previous power state
0602  *
0603  * Return the powerdomain @pwrdm's previous power state.  Returns -EINVAL
0604  * if the powerdomain pointer is null or returns the previous power state
0605  * upon success.
0606  */
0607 int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
0608 {
0609     int ret = -EINVAL;
0610 
0611     if (!pwrdm)
0612         return -EINVAL;
0613 
0614     if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst)
0615         ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
0616 
0617     return ret;
0618 }
0619 
0620 /**
0621  * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
0622  * @pwrdm: struct powerdomain * to set
0623  * @pwrst: one of the PWRDM_POWER_* macros
0624  *
0625  * Set the next power state @pwrst that the logic portion of the
0626  * powerdomain @pwrdm will enter when the powerdomain enters retention.
0627  * This will be either RETENTION or OFF, if supported.  Returns
0628  * -EINVAL if the powerdomain pointer is null or the target power
0629  * state is not supported, or returns 0 upon success.
0630  */
0631 int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
0632 {
0633     int ret = -EINVAL;
0634 
0635     if (!pwrdm)
0636         return -EINVAL;
0637 
0638     if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
0639         return -EINVAL;
0640 
0641     pr_debug("powerdomain: %s: setting next logic powerstate to %0x\n",
0642          pwrdm->name, pwrst);
0643 
0644     if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
0645         ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
0646 
0647     return ret;
0648 }
0649 
0650 /**
0651  * pwrdm_set_mem_onst - set memory power state while powerdomain ON
0652  * @pwrdm: struct powerdomain * to set
0653  * @bank: memory bank number to set (0-3)
0654  * @pwrst: one of the PWRDM_POWER_* macros
0655  *
0656  * Set the next power state @pwrst that memory bank @bank of the
0657  * powerdomain @pwrdm will enter when the powerdomain enters the ON
0658  * state.  @bank will be a number from 0 to 3, and represents different
0659  * types of memory, depending on the powerdomain.  Returns -EINVAL if
0660  * the powerdomain pointer is null or the target power state is not
0661  * supported for this memory bank, -EEXIST if the target memory
0662  * bank does not exist or is not controllable, or returns 0 upon
0663  * success.
0664  */
0665 int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
0666 {
0667     int ret = -EINVAL;
0668 
0669     if (!pwrdm)
0670         return -EINVAL;
0671 
0672     if (pwrdm->banks < (bank + 1))
0673         return -EEXIST;
0674 
0675     if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
0676         return -EINVAL;
0677 
0678     pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n",
0679          pwrdm->name, bank, pwrst);
0680 
0681     if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
0682         ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
0683 
0684     return ret;
0685 }
0686 
0687 /**
0688  * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
0689  * @pwrdm: struct powerdomain * to set
0690  * @bank: memory bank number to set (0-3)
0691  * @pwrst: one of the PWRDM_POWER_* macros
0692  *
0693  * Set the next power state @pwrst that memory bank @bank of the
0694  * powerdomain @pwrdm will enter when the powerdomain enters the
0695  * RETENTION state.  Bank will be a number from 0 to 3, and represents
0696  * different types of memory, depending on the powerdomain.  @pwrst
0697  * will be either RETENTION or OFF, if supported.  Returns -EINVAL if
0698  * the powerdomain pointer is null or the target power state is not
0699  * supported for this memory bank, -EEXIST if the target memory
0700  * bank does not exist or is not controllable, or returns 0 upon
0701  * success.
0702  */
0703 int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
0704 {
0705     int ret = -EINVAL;
0706 
0707     if (!pwrdm)
0708         return -EINVAL;
0709 
0710     if (pwrdm->banks < (bank + 1))
0711         return -EEXIST;
0712 
0713     if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
0714         return -EINVAL;
0715 
0716     pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n",
0717          pwrdm->name, bank, pwrst);
0718 
0719     if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
0720         ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
0721 
0722     return ret;
0723 }
0724 
0725 /**
0726  * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
0727  * @pwrdm: struct powerdomain * to get current logic retention power state
0728  *
0729  * Return the power state that the logic portion of powerdomain @pwrdm
0730  * will enter when the powerdomain enters retention.  Returns -EINVAL
0731  * if the powerdomain pointer is null or returns the logic retention
0732  * power state upon success.
0733  */
0734 int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
0735 {
0736     int ret = -EINVAL;
0737 
0738     if (!pwrdm)
0739         return -EINVAL;
0740 
0741     if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
0742         ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
0743 
0744     return ret;
0745 }
0746 
0747 /**
0748  * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
0749  * @pwrdm: struct powerdomain * to get previous logic power state
0750  *
0751  * Return the powerdomain @pwrdm's previous logic power state.  Returns
0752  * -EINVAL if the powerdomain pointer is null or returns the previous
0753  * logic power state upon success.
0754  */
0755 int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
0756 {
0757     int ret = -EINVAL;
0758 
0759     if (!pwrdm)
0760         return -EINVAL;
0761 
0762     if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
0763         ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
0764 
0765     return ret;
0766 }
0767 
0768 /**
0769  * pwrdm_read_logic_retst - get next powerdomain logic power state
0770  * @pwrdm: struct powerdomain * to get next logic power state
0771  *
0772  * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
0773  * if the powerdomain pointer is null or returns the next logic
0774  * power state upon success.
0775  */
0776 int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
0777 {
0778     int ret = -EINVAL;
0779 
0780     if (!pwrdm)
0781         return -EINVAL;
0782 
0783     if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
0784         ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
0785 
0786     return ret;
0787 }
0788 
0789 /**
0790  * pwrdm_read_mem_pwrst - get current memory bank power state
0791  * @pwrdm: struct powerdomain * to get current memory bank power state
0792  * @bank: memory bank number (0-3)
0793  *
0794  * Return the powerdomain @pwrdm's current memory power state for bank
0795  * @bank.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
0796  * the target memory bank does not exist or is not controllable, or
0797  * returns the current memory power state upon success.
0798  */
0799 int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
0800 {
0801     int ret = -EINVAL;
0802 
0803     if (!pwrdm)
0804         return ret;
0805 
0806     if (pwrdm->banks < (bank + 1))
0807         return ret;
0808 
0809     if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
0810         bank = 1;
0811 
0812     if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst)
0813         ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank);
0814 
0815     return ret;
0816 }
0817 
0818 /**
0819  * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
0820  * @pwrdm: struct powerdomain * to get previous memory bank power state
0821  * @bank: memory bank number (0-3)
0822  *
0823  * Return the powerdomain @pwrdm's previous memory power state for
0824  * bank @bank.  Returns -EINVAL if the powerdomain pointer is null,
0825  * -EEXIST if the target memory bank does not exist or is not
0826  * controllable, or returns the previous memory power state upon
0827  * success.
0828  */
0829 int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
0830 {
0831     int ret = -EINVAL;
0832 
0833     if (!pwrdm)
0834         return ret;
0835 
0836     if (pwrdm->banks < (bank + 1))
0837         return ret;
0838 
0839     if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
0840         bank = 1;
0841 
0842     if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst)
0843         ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank);
0844 
0845     return ret;
0846 }
0847 
0848 /**
0849  * pwrdm_read_mem_retst - get next memory bank power state
0850  * @pwrdm: struct powerdomain * to get mext memory bank power state
0851  * @bank: memory bank number (0-3)
0852  *
0853  * Return the powerdomain pwrdm's next memory power state for bank
0854  * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
0855  * the target memory bank does not exist or is not controllable, or
0856  * returns the next memory power state upon success.
0857  */
0858 int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
0859 {
0860     int ret = -EINVAL;
0861 
0862     if (!pwrdm)
0863         return ret;
0864 
0865     if (pwrdm->banks < (bank + 1))
0866         return ret;
0867 
0868     if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
0869         ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
0870 
0871     return ret;
0872 }
0873 
0874 /**
0875  * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
0876  * @pwrdm: struct powerdomain * to clear
0877  *
0878  * Clear the powerdomain's previous power state register @pwrdm.
0879  * Clears the entire register, including logic and memory bank
0880  * previous power states.  Returns -EINVAL if the powerdomain pointer
0881  * is null, or returns 0 upon success.
0882  */
0883 int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
0884 {
0885     int ret = -EINVAL;
0886 
0887     if (!pwrdm)
0888         return ret;
0889 
0890     /*
0891      * XXX should get the powerdomain's current state here;
0892      * warn & fail if it is not ON.
0893      */
0894 
0895     pr_debug("powerdomain: %s: clearing previous power state reg\n",
0896          pwrdm->name);
0897 
0898     if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
0899         ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
0900 
0901     return ret;
0902 }
0903 
0904 /**
0905  * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
0906  * @pwrdm: struct powerdomain *
0907  *
0908  * Enable automatic context save-and-restore upon power state change
0909  * for some devices in the powerdomain @pwrdm.  Warning: this only
0910  * affects a subset of devices in a powerdomain; check the TRM
0911  * closely.  Returns -EINVAL if the powerdomain pointer is null or if
0912  * the powerdomain does not support automatic save-and-restore, or
0913  * returns 0 upon success.
0914  */
0915 int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
0916 {
0917     int ret = -EINVAL;
0918 
0919     if (!pwrdm)
0920         return ret;
0921 
0922     if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
0923         return ret;
0924 
0925     pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name);
0926 
0927     if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
0928         ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
0929 
0930     return ret;
0931 }
0932 
0933 /**
0934  * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
0935  * @pwrdm: struct powerdomain *
0936  *
0937  * Disable automatic context save-and-restore upon power state change
0938  * for some devices in the powerdomain @pwrdm.  Warning: this only
0939  * affects a subset of devices in a powerdomain; check the TRM
0940  * closely.  Returns -EINVAL if the powerdomain pointer is null or if
0941  * the powerdomain does not support automatic save-and-restore, or
0942  * returns 0 upon success.
0943  */
0944 int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
0945 {
0946     int ret = -EINVAL;
0947 
0948     if (!pwrdm)
0949         return ret;
0950 
0951     if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
0952         return ret;
0953 
0954     pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name);
0955 
0956     if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
0957         ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
0958 
0959     return ret;
0960 }
0961 
0962 /**
0963  * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
0964  * @pwrdm: struct powerdomain *
0965  *
0966  * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
0967  * for some devices, or 0 if it does not.
0968  */
0969 bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
0970 {
0971     return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
0972 }
0973 
0974 int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
0975 {
0976     int ret;
0977 
0978     if (!pwrdm || !arch_pwrdm)
0979         return -EINVAL;
0980 
0981     ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
0982     if (!ret)
0983         ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
0984 
0985     return ret;
0986 }
0987 
0988 int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
0989 {
0990     int ret;
0991 
0992     pwrdm_lock(pwrdm);
0993     ret = pwrdm_state_switch_nolock(pwrdm);
0994     pwrdm_unlock(pwrdm);
0995 
0996     return ret;
0997 }
0998 
0999 int pwrdm_pre_transition(struct powerdomain *pwrdm)
1000 {
1001     if (pwrdm)
1002         _pwrdm_pre_transition_cb(pwrdm, NULL);
1003     else
1004         pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
1005 
1006     return 0;
1007 }
1008 
1009 int pwrdm_post_transition(struct powerdomain *pwrdm)
1010 {
1011     if (pwrdm)
1012         _pwrdm_post_transition_cb(pwrdm, NULL);
1013     else
1014         pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
1015 
1016     return 0;
1017 }
1018 
1019 /**
1020  * pwrdm_get_valid_lp_state() - Find best match deep power state
1021  * @pwrdm:  power domain for which we want to find best match
1022  * @is_logic_state: Are we looking for logic state match here? Should
1023  *          be one of PWRDM_xxx macro values
1024  * @req_state:  requested power state
1025  *
1026  * Returns: closest match for requested power state. default fallback
1027  * is RET for logic state and ON for power state.
1028  *
1029  * This does a search from the power domain data looking for the
1030  * closest valid power domain state that the hardware can achieve.
1031  * PRCM definitions for PWRSTCTRL allows us to program whatever
1032  * configuration we'd like, and PRCM will actually attempt such
1033  * a transition, however if the powerdomain does not actually support it,
1034  * we endup with a hung system. The valid power domain states are already
1035  * available in our powerdomain data files. So this function tries to do
1036  * the following:
1037  * a) find if we have an exact match to the request - no issues.
1038  * b) else find if a deeper power state is possible.
1039  * c) failing which, it tries to find closest higher power state for the
1040  * request.
1041  */
1042 u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
1043                 bool is_logic_state, u8 req_state)
1044 {
1045     u8 pwrdm_states = is_logic_state ? pwrdm->pwrsts_logic_ret :
1046             pwrdm->pwrsts;
1047     /* For logic, ret is highest and others, ON is highest */
1048     u8 default_pwrst = is_logic_state ? PWRDM_POWER_RET : PWRDM_POWER_ON;
1049     u8 new_pwrst;
1050     bool found;
1051 
1052     /* If it is already supported, nothing to search */
1053     if (pwrdm_states & BIT(req_state))
1054         return req_state;
1055 
1056     if (!req_state)
1057         goto up_search;
1058 
1059     /*
1060      * So, we dont have a exact match
1061      * Can we get a deeper power state match?
1062      */
1063     new_pwrst = req_state - 1;
1064     found = true;
1065     while (!(pwrdm_states & BIT(new_pwrst))) {
1066         /* No match even at OFF? Not available */
1067         if (new_pwrst == PWRDM_POWER_OFF) {
1068             found = false;
1069             break;
1070         }
1071         new_pwrst--;
1072     }
1073 
1074     if (found)
1075         goto done;
1076 
1077 up_search:
1078     /* OK, no deeper ones, can we get a higher match? */
1079     new_pwrst = req_state + 1;
1080     while (!(pwrdm_states & BIT(new_pwrst))) {
1081         if (new_pwrst > PWRDM_POWER_ON) {
1082             WARN(1, "powerdomain: %s: Fix max powerstate to ON\n",
1083                  pwrdm->name);
1084             return PWRDM_POWER_ON;
1085         }
1086 
1087         if (new_pwrst == default_pwrst)
1088             break;
1089         new_pwrst++;
1090     }
1091 done:
1092     return new_pwrst;
1093 }
1094 
1095 /**
1096  * omap_set_pwrdm_state - change a powerdomain's current power state
1097  * @pwrdm: struct powerdomain * to change the power state of
1098  * @pwrst: power state to change to
1099  *
1100  * Change the current hardware power state of the powerdomain
1101  * represented by @pwrdm to the power state represented by @pwrst.
1102  * Returns -EINVAL if @pwrdm is null or invalid or if the
1103  * powerdomain's current power state could not be read, or returns 0
1104  * upon success or if @pwrdm does not support @pwrst or any
1105  * lower-power state.  XXX Should not return 0 if the @pwrdm does not
1106  * support @pwrst or any lower-power state: this should be an error.
1107  */
1108 int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
1109 {
1110     u8 next_pwrst, sleep_switch;
1111     int curr_pwrst;
1112     int ret = 0;
1113 
1114     if (!pwrdm || IS_ERR(pwrdm))
1115         return -EINVAL;
1116 
1117     while (!(pwrdm->pwrsts & (1 << pwrst))) {
1118         if (pwrst == PWRDM_POWER_OFF)
1119             return ret;
1120         pwrst--;
1121     }
1122 
1123     pwrdm_lock(pwrdm);
1124 
1125     curr_pwrst = pwrdm_read_pwrst(pwrdm);
1126     if (curr_pwrst < 0) {
1127         ret = -EINVAL;
1128         goto osps_out;
1129     }
1130 
1131     next_pwrst = pwrdm_read_next_pwrst(pwrdm);
1132     if (curr_pwrst == pwrst && next_pwrst == pwrst)
1133         goto osps_out;
1134 
1135     sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
1136                                 pwrst);
1137 
1138     ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
1139     if (ret)
1140         pr_err("%s: unable to set power state of powerdomain: %s\n",
1141                __func__, pwrdm->name);
1142 
1143     _pwrdm_restore_clkdm_state(pwrdm, sleep_switch);
1144 
1145 osps_out:
1146     pwrdm_unlock(pwrdm);
1147 
1148     return ret;
1149 }
1150 
1151 /**
1152  * pwrdm_get_context_loss_count - get powerdomain's context loss count
1153  * @pwrdm: struct powerdomain * to wait for
1154  *
1155  * Context loss count is the sum of powerdomain off-mode counter, the
1156  * logic off counter and the per-bank memory off counter.  Returns negative
1157  * (and WARNs) upon error, otherwise, returns the context loss count.
1158  */
1159 int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
1160 {
1161     int i, count;
1162 
1163     if (!pwrdm) {
1164         WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
1165         return -ENODEV;
1166     }
1167 
1168     count = pwrdm->state_counter[PWRDM_POWER_OFF];
1169     count += pwrdm->ret_logic_off_counter;
1170 
1171     for (i = 0; i < pwrdm->banks; i++)
1172         count += pwrdm->ret_mem_off_counter[i];
1173 
1174     /*
1175      * Context loss count has to be a non-negative value. Clear the sign
1176      * bit to get a value range from 0 to INT_MAX.
1177      */
1178     count &= INT_MAX;
1179 
1180     pr_debug("powerdomain: %s: context loss count = %d\n",
1181          pwrdm->name, count);
1182 
1183     return count;
1184 }
1185 
1186 /**
1187  * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
1188  * @pwrdm: struct powerdomain *
1189  *
1190  * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
1191  * can lose either memory or logic context or if @pwrdm is invalid, or
1192  * returns 0 otherwise.  This function is not concerned with how the
1193  * powerdomain registers are programmed (i.e., to go off or not); it's
1194  * concerned with whether it's ever possible for this powerdomain to
1195  * go off while some other part of the chip is active.  This function
1196  * assumes that every powerdomain can go to either ON or INACTIVE.
1197  */
1198 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
1199 {
1200     int i;
1201 
1202     if (!pwrdm) {
1203         pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
1204              __func__);
1205         return true;
1206     }
1207 
1208     if (pwrdm->pwrsts & PWRSTS_OFF)
1209         return true;
1210 
1211     if (pwrdm->pwrsts & PWRSTS_RET) {
1212         if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
1213             return true;
1214 
1215         for (i = 0; i < pwrdm->banks; i++)
1216             if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
1217                 return true;
1218     }
1219 
1220     for (i = 0; i < pwrdm->banks; i++)
1221         if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
1222             return true;
1223 
1224     return false;
1225 }
1226 
1227 /**
1228  * pwrdm_save_context - save powerdomain registers
1229  *
1230  * Register state is going to be lost due to a suspend or hibernate
1231  * event. Save the powerdomain registers.
1232  */
1233 static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused)
1234 {
1235     if (arch_pwrdm && arch_pwrdm->pwrdm_save_context)
1236         arch_pwrdm->pwrdm_save_context(pwrdm);
1237     return 0;
1238 }
1239 
1240 /**
1241  * pwrdm_save_context - restore powerdomain registers
1242  *
1243  * Restore powerdomain control registers after a suspend or resume
1244  * event.
1245  */
1246 static int pwrdm_restore_context(struct powerdomain *pwrdm, void *unused)
1247 {
1248     if (arch_pwrdm && arch_pwrdm->pwrdm_restore_context)
1249         arch_pwrdm->pwrdm_restore_context(pwrdm);
1250     return 0;
1251 }
1252 
1253 static int pwrdm_lost_power(struct powerdomain *pwrdm, void *unused)
1254 {
1255     int state;
1256 
1257     /*
1258      * Power has been lost across all powerdomains, increment the
1259      * counter.
1260      */
1261 
1262     state = pwrdm_read_pwrst(pwrdm);
1263     if (state != PWRDM_POWER_OFF) {
1264         pwrdm->state_counter[state]++;
1265         pwrdm->state_counter[PWRDM_POWER_OFF]++;
1266     }
1267     pwrdm->state = state;
1268 
1269     return 0;
1270 }
1271 
1272 void pwrdms_save_context(void)
1273 {
1274     pwrdm_for_each(pwrdm_save_context, NULL);
1275 }
1276 
1277 void pwrdms_restore_context(void)
1278 {
1279     pwrdm_for_each(pwrdm_restore_context, NULL);
1280 }
1281 
1282 void pwrdms_lost_power(void)
1283 {
1284     pwrdm_for_each(pwrdm_lost_power, NULL);
1285 }