cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

powerdomain.c (33999B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * OMAP powerdomain control
      4 *
      5 * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
      6 * Copyright (C) 2007-2011 Nokia Corporation
      7 *
      8 * Written by Paul Walmsley
      9 * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
     10 * State counting code by Tero Kristo <tero.kristo@nokia.com>
     11 */
     12#undef DEBUG
     13
     14#include <linux/cpu_pm.h>
     15#include <linux/kernel.h>
     16#include <linux/types.h>
     17#include <linux/list.h>
     18#include <linux/errno.h>
     19#include <linux/string.h>
     20#include <linux/spinlock.h>
     21#include <trace/events/power.h>
     22
     23#include "cm2xxx_3xxx.h"
     24#include "prcm44xx.h"
     25#include "cm44xx.h"
     26#include "prm2xxx_3xxx.h"
     27#include "prm44xx.h"
     28
     29#include <asm/cpu.h>
     30
     31#include "powerdomain.h"
     32#include "clockdomain.h"
     33#include "voltage.h"
     34
     35#include "soc.h"
     36#include "pm.h"
     37
     38#define PWRDM_TRACE_STATES_FLAG	(1<<31)
     39
     40void pwrdms_save_context(void);
     41void pwrdms_restore_context(void);
     42
     43enum {
     44	PWRDM_STATE_NOW = 0,
     45	PWRDM_STATE_PREV,
     46};
     47
     48/*
     49 * Types of sleep_switch used internally in omap_set_pwrdm_state()
     50 * and its associated static functions
     51 *
     52 * XXX Better documentation is needed here
     53 */
     54#define ALREADYACTIVE_SWITCH		0
     55#define FORCEWAKEUP_SWITCH		1
     56#define LOWPOWERSTATE_SWITCH		2
     57
     58/* pwrdm_list contains all registered struct powerdomains */
     59static LIST_HEAD(pwrdm_list);
     60
     61static struct pwrdm_ops *arch_pwrdm;
     62
     63/* Private functions */
     64
     65static struct powerdomain *_pwrdm_lookup(const char *name)
     66{
     67	struct powerdomain *pwrdm, *temp_pwrdm;
     68
     69	pwrdm = NULL;
     70
     71	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
     72		if (!strcmp(name, temp_pwrdm->name)) {
     73			pwrdm = temp_pwrdm;
     74			break;
     75		}
     76	}
     77
     78	return pwrdm;
     79}
     80
     81/**
     82 * _pwrdm_register - register a powerdomain
     83 * @pwrdm: struct powerdomain * to register
     84 *
     85 * Adds a powerdomain to the internal powerdomain list.  Returns
     86 * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
     87 * already registered by the provided name, or 0 upon success.
     88 */
     89static int _pwrdm_register(struct powerdomain *pwrdm)
     90{
     91	int i;
     92	struct voltagedomain *voltdm;
     93
     94	if (!pwrdm || !pwrdm->name)
     95		return -EINVAL;
     96
     97	if (cpu_is_omap44xx() &&
     98	    pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
     99		pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
    100		       pwrdm->name);
    101		return -EINVAL;
    102	}
    103
    104	if (_pwrdm_lookup(pwrdm->name))
    105		return -EEXIST;
    106
    107	if (arch_pwrdm && arch_pwrdm->pwrdm_has_voltdm)
    108		if (!arch_pwrdm->pwrdm_has_voltdm())
    109			goto skip_voltdm;
    110
    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);
    119skip_voltdm:
    120	spin_lock_init(&pwrdm->_lock);
    121
    122	list_add(&pwrdm->node, &pwrdm_list);
    123
    124	/* Initialize the powerdomain's state counter */
    125	for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
    126		pwrdm->state_counter[i] = 0;
    127
    128	pwrdm->ret_logic_off_counter = 0;
    129	for (i = 0; i < pwrdm->banks; i++)
    130		pwrdm->ret_mem_off_counter[i] = 0;
    131
    132	if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
    133		arch_pwrdm->pwrdm_wait_transition(pwrdm);
    134	pwrdm->state = pwrdm_read_pwrst(pwrdm);
    135	pwrdm->state_counter[pwrdm->state] = 1;
    136
    137	pr_debug("powerdomain: registered %s\n", pwrdm->name);
    138
    139	return 0;
    140}
    141
    142static void _update_logic_membank_counters(struct powerdomain *pwrdm)
    143{
    144	int i;
    145	u8 prev_logic_pwrst, prev_mem_pwrst;
    146
    147	prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
    148	if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
    149	    (prev_logic_pwrst == PWRDM_POWER_OFF))
    150		pwrdm->ret_logic_off_counter++;
    151
    152	for (i = 0; i < pwrdm->banks; i++) {
    153		prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
    154
    155		if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
    156		    (prev_mem_pwrst == PWRDM_POWER_OFF))
    157			pwrdm->ret_mem_off_counter[i]++;
    158	}
    159}
    160
    161static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
    162{
    163
    164	int prev, next, state, trace_state = 0;
    165
    166	if (pwrdm == NULL)
    167		return -EINVAL;
    168
    169	state = pwrdm_read_pwrst(pwrdm);
    170
    171	switch (flag) {
    172	case PWRDM_STATE_NOW:
    173		prev = pwrdm->state;
    174		break;
    175	case PWRDM_STATE_PREV:
    176		prev = pwrdm_read_prev_pwrst(pwrdm);
    177		if (pwrdm->state != prev)
    178			pwrdm->state_counter[prev]++;
    179		if (prev == PWRDM_POWER_RET)
    180			_update_logic_membank_counters(pwrdm);
    181		/*
    182		 * If the power domain did not hit the desired state,
    183		 * generate a trace event with both the desired and hit states
    184		 */
    185		next = pwrdm_read_next_pwrst(pwrdm);
    186		if (next != prev) {
    187			trace_state = (PWRDM_TRACE_STATES_FLAG |
    188				       ((next & OMAP_POWERSTATE_MASK) << 8) |
    189				       ((prev & OMAP_POWERSTATE_MASK) << 0));
    190			trace_power_domain_target_rcuidle(pwrdm->name,
    191							  trace_state,
    192							  raw_smp_processor_id());
    193		}
    194		break;
    195	default:
    196		return -EINVAL;
    197	}
    198
    199	if (state != prev)
    200		pwrdm->state_counter[state]++;
    201
    202	pm_dbg_update_time(pwrdm, prev);
    203
    204	pwrdm->state = state;
    205
    206	return 0;
    207}
    208
    209static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
    210{
    211	pwrdm_clear_all_prev_pwrst(pwrdm);
    212	_pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
    213	return 0;
    214}
    215
    216static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
    217{
    218	_pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
    219	return 0;
    220}
    221
    222/**
    223 * _pwrdm_save_clkdm_state_and_activate - prepare for power state change
    224 * @pwrdm: struct powerdomain * to operate on
    225 * @curr_pwrst: current power state of @pwrdm
    226 * @pwrst: power state to switch to
    227 *
    228 * Determine whether the powerdomain needs to be turned on before
    229 * attempting to switch power states.  Called by
    230 * omap_set_pwrdm_state().  NOTE that if the powerdomain contains
    231 * multiple clockdomains, this code assumes that the first clockdomain
    232 * supports software-supervised wakeup mode - potentially a problem.
    233 * Returns the power state switch mode currently in use (see the
    234 * "Types of sleep_switch" comment above).
    235 */
    236static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
    237					       u8 curr_pwrst, u8 pwrst)
    238{
    239	u8 sleep_switch;
    240
    241	if (curr_pwrst < PWRDM_POWER_ON) {
    242		if (curr_pwrst > pwrst &&
    243		    pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
    244		    arch_pwrdm->pwrdm_set_lowpwrstchange) {
    245			sleep_switch = LOWPOWERSTATE_SWITCH;
    246		} else {
    247			clkdm_deny_idle_nolock(pwrdm->pwrdm_clkdms[0]);
    248			sleep_switch = FORCEWAKEUP_SWITCH;
    249		}
    250	} else {
    251		sleep_switch = ALREADYACTIVE_SWITCH;
    252	}
    253
    254	return sleep_switch;
    255}
    256
    257/**
    258 * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change
    259 * @pwrdm: struct powerdomain * to operate on
    260 * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate()
    261 *
    262 * Restore the clockdomain state perturbed by
    263 * _pwrdm_save_clkdm_state_and_activate(), and call the power state
    264 * bookkeeping code.  Called by omap_set_pwrdm_state().  NOTE that if
    265 * the powerdomain contains multiple clockdomains, this assumes that
    266 * the first associated clockdomain supports either
    267 * hardware-supervised idle control in the register, or
    268 * software-supervised sleep.  No return value.
    269 */
    270static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm,
    271				       u8 sleep_switch)
    272{
    273	switch (sleep_switch) {
    274	case FORCEWAKEUP_SWITCH:
    275		clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]);
    276		break;
    277	case LOWPOWERSTATE_SWITCH:
    278		if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
    279		    arch_pwrdm->pwrdm_set_lowpwrstchange)
    280			arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
    281		pwrdm_state_switch_nolock(pwrdm);
    282		break;
    283	}
    284}
    285
    286/* Public functions */
    287
    288/**
    289 * pwrdm_register_platform_funcs - register powerdomain implementation fns
    290 * @po: func pointers for arch specific implementations
    291 *
    292 * Register the list of function pointers used to implement the
    293 * powerdomain functions on different OMAP SoCs.  Should be called
    294 * before any other pwrdm_register*() function.  Returns -EINVAL if
    295 * @po is null, -EEXIST if platform functions have already been
    296 * registered, or 0 upon success.
    297 */
    298int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
    299{
    300	if (!po)
    301		return -EINVAL;
    302
    303	if (arch_pwrdm)
    304		return -EEXIST;
    305
    306	arch_pwrdm = po;
    307
    308	return 0;
    309}
    310
    311/**
    312 * pwrdm_register_pwrdms - register SoC powerdomains
    313 * @ps: pointer to an array of struct powerdomain to register
    314 *
    315 * Register the powerdomains available on a particular OMAP SoC.  Must
    316 * be called after pwrdm_register_platform_funcs().  May be called
    317 * multiple times.  Returns -EACCES if called before
    318 * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
    319 * null; or 0 upon success.
    320 */
    321int pwrdm_register_pwrdms(struct powerdomain **ps)
    322{
    323	struct powerdomain **p = NULL;
    324
    325	if (!arch_pwrdm)
    326		return -EEXIST;
    327
    328	if (!ps)
    329		return -EINVAL;
    330
    331	for (p = ps; *p; p++)
    332		_pwrdm_register(*p);
    333
    334	return 0;
    335}
    336
    337static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
    338{
    339	switch (cmd) {
    340	case CPU_CLUSTER_PM_ENTER:
    341		if (enable_off_mode)
    342			pwrdms_save_context();
    343		break;
    344	case CPU_CLUSTER_PM_EXIT:
    345		if (enable_off_mode)
    346			pwrdms_restore_context();
    347		break;
    348	}
    349
    350	return NOTIFY_OK;
    351}
    352
    353/**
    354 * pwrdm_complete_init - set up the powerdomain layer
    355 *
    356 * Do whatever is necessary to initialize registered powerdomains and
    357 * powerdomain code.  Currently, this programs the next power state
    358 * for each powerdomain to ON.  This prevents powerdomains from
    359 * unexpectedly losing context or entering high wakeup latency modes
    360 * with non-power-management-enabled kernels.  Must be called after
    361 * pwrdm_register_pwrdms().  Returns -EACCES if called before
    362 * pwrdm_register_pwrdms(), or 0 upon success.
    363 */
    364int pwrdm_complete_init(void)
    365{
    366	struct powerdomain *temp_p;
    367	static struct notifier_block nb;
    368
    369	if (list_empty(&pwrdm_list))
    370		return -EACCES;
    371
    372	list_for_each_entry(temp_p, &pwrdm_list, node)
    373		pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
    374
    375	/* Only AM43XX can lose pwrdm context during rtc-ddr suspend */
    376	if (soc_is_am43xx()) {
    377		nb.notifier_call = cpu_notifier;
    378		cpu_pm_register_notifier(&nb);
    379	}
    380
    381	return 0;
    382}
    383
    384/**
    385 * pwrdm_lock - acquire a Linux spinlock on a powerdomain
    386 * @pwrdm: struct powerdomain * to lock
    387 *
    388 * Acquire the powerdomain spinlock on @pwrdm.  No return value.
    389 */
    390void pwrdm_lock(struct powerdomain *pwrdm)
    391	__acquires(&pwrdm->_lock)
    392{
    393	spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags);
    394}
    395
    396/**
    397 * pwrdm_unlock - release a Linux spinlock on a powerdomain
    398 * @pwrdm: struct powerdomain * to unlock
    399 *
    400 * Release the powerdomain spinlock on @pwrdm.  No return value.
    401 */
    402void pwrdm_unlock(struct powerdomain *pwrdm)
    403	__releases(&pwrdm->_lock)
    404{
    405	spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags);
    406}
    407
    408/**
    409 * pwrdm_lookup - look up a powerdomain by name, return a pointer
    410 * @name: name of powerdomain
    411 *
    412 * Find a registered powerdomain by its name @name.  Returns a pointer
    413 * to the struct powerdomain if found, or NULL otherwise.
    414 */
    415struct powerdomain *pwrdm_lookup(const char *name)
    416{
    417	struct powerdomain *pwrdm;
    418
    419	if (!name)
    420		return NULL;
    421
    422	pwrdm = _pwrdm_lookup(name);
    423
    424	return pwrdm;
    425}
    426
    427/**
    428 * pwrdm_for_each - call function on each registered clockdomain
    429 * @fn: callback function *
    430 *
    431 * Call the supplied function @fn for each registered powerdomain.
    432 * The callback function @fn can return anything but 0 to bail out
    433 * early from the iterator.  Returns the last return value of the
    434 * callback function, which should be 0 for success or anything else
    435 * to indicate failure; or -EINVAL if the function pointer is null.
    436 */
    437int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
    438		   void *user)
    439{
    440	struct powerdomain *temp_pwrdm;
    441	int ret = 0;
    442
    443	if (!fn)
    444		return -EINVAL;
    445
    446	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
    447		ret = (*fn)(temp_pwrdm, user);
    448		if (ret)
    449			break;
    450	}
    451
    452	return ret;
    453}
    454
    455/**
    456 * pwrdm_add_clkdm - add a clockdomain to a powerdomain
    457 * @pwrdm: struct powerdomain * to add the clockdomain to
    458 * @clkdm: struct clockdomain * to associate with a powerdomain
    459 *
    460 * Associate the clockdomain @clkdm with a powerdomain @pwrdm.  This
    461 * enables the use of pwrdm_for_each_clkdm().  Returns -EINVAL if
    462 * presented with invalid pointers; -ENOMEM if memory could not be allocated;
    463 * or 0 upon success.
    464 */
    465int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
    466{
    467	int i;
    468	int ret = -EINVAL;
    469
    470	if (!pwrdm || !clkdm)
    471		return -EINVAL;
    472
    473	pr_debug("powerdomain: %s: associating clockdomain %s\n",
    474		 pwrdm->name, clkdm->name);
    475
    476	for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
    477		if (!pwrdm->pwrdm_clkdms[i])
    478			break;
    479#ifdef DEBUG
    480		if (pwrdm->pwrdm_clkdms[i] == clkdm) {
    481			ret = -EINVAL;
    482			goto pac_exit;
    483		}
    484#endif
    485	}
    486
    487	if (i == PWRDM_MAX_CLKDMS) {
    488		pr_debug("powerdomain: %s: increase PWRDM_MAX_CLKDMS for clkdm %s\n",
    489			 pwrdm->name, clkdm->name);
    490		WARN_ON(1);
    491		ret = -ENOMEM;
    492		goto pac_exit;
    493	}
    494
    495	pwrdm->pwrdm_clkdms[i] = clkdm;
    496
    497	ret = 0;
    498
    499pac_exit:
    500	return ret;
    501}
    502
    503/**
    504 * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
    505 * @pwrdm: struct powerdomain *
    506 *
    507 * Return the number of controllable memory banks in powerdomain @pwrdm,
    508 * starting with 1.  Returns -EINVAL if the powerdomain pointer is null.
    509 */
    510int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
    511{
    512	if (!pwrdm)
    513		return -EINVAL;
    514
    515	return pwrdm->banks;
    516}
    517
    518/**
    519 * pwrdm_set_next_pwrst - set next powerdomain power state
    520 * @pwrdm: struct powerdomain * to set
    521 * @pwrst: one of the PWRDM_POWER_* macros
    522 *
    523 * Set the powerdomain @pwrdm's next power state to @pwrst.  The powerdomain
    524 * may not enter this state immediately if the preconditions for this state
    525 * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
    526 * null or if the power state is invalid for the powerdomin, or returns 0
    527 * upon success.
    528 */
    529int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
    530{
    531	int ret = -EINVAL;
    532
    533	if (!pwrdm)
    534		return -EINVAL;
    535
    536	if (!(pwrdm->pwrsts & (1 << pwrst)))
    537		return -EINVAL;
    538
    539	pr_debug("powerdomain: %s: setting next powerstate to %0x\n",
    540		 pwrdm->name, pwrst);
    541
    542	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
    543		/* Trace the pwrdm desired target state */
    544		trace_power_domain_target_rcuidle(pwrdm->name, pwrst,
    545						  raw_smp_processor_id());
    546		/* Program the pwrdm desired target state */
    547		ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
    548	}
    549
    550	return ret;
    551}
    552
    553/**
    554 * pwrdm_read_next_pwrst - get next powerdomain power state
    555 * @pwrdm: struct powerdomain * to get power state
    556 *
    557 * Return the powerdomain @pwrdm's next power state.  Returns -EINVAL
    558 * if the powerdomain pointer is null or returns the next power state
    559 * upon success.
    560 */
    561int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
    562{
    563	int ret = -EINVAL;
    564
    565	if (!pwrdm)
    566		return -EINVAL;
    567
    568	if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
    569		ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
    570
    571	return ret;
    572}
    573
    574/**
    575 * pwrdm_read_pwrst - get current powerdomain power state
    576 * @pwrdm: struct powerdomain * to get power state
    577 *
    578 * Return the powerdomain @pwrdm's current power state.	Returns -EINVAL
    579 * if the powerdomain pointer is null or returns the current power state
    580 * upon success. Note that if the power domain only supports the ON state
    581 * then just return ON as the current state.
    582 */
    583int pwrdm_read_pwrst(struct powerdomain *pwrdm)
    584{
    585	int ret = -EINVAL;
    586
    587	if (!pwrdm)
    588		return -EINVAL;
    589
    590	if (pwrdm->pwrsts == PWRSTS_ON)
    591		return PWRDM_POWER_ON;
    592
    593	if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
    594		ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
    595
    596	return ret;
    597}
    598
    599/**
    600 * pwrdm_read_prev_pwrst - get previous powerdomain power state
    601 * @pwrdm: struct powerdomain * to get previous power state
    602 *
    603 * Return the powerdomain @pwrdm's previous power state.  Returns -EINVAL
    604 * if the powerdomain pointer is null or returns the previous power state
    605 * upon success.
    606 */
    607int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
    608{
    609	int ret = -EINVAL;
    610
    611	if (!pwrdm)
    612		return -EINVAL;
    613
    614	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst)
    615		ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
    616
    617	return ret;
    618}
    619
    620/**
    621 * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
    622 * @pwrdm: struct powerdomain * to set
    623 * @pwrst: one of the PWRDM_POWER_* macros
    624 *
    625 * Set the next power state @pwrst that the logic portion of the
    626 * powerdomain @pwrdm will enter when the powerdomain enters retention.
    627 * This will be either RETENTION or OFF, if supported.  Returns
    628 * -EINVAL if the powerdomain pointer is null or the target power
    629 * state is not supported, or returns 0 upon success.
    630 */
    631int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
    632{
    633	int ret = -EINVAL;
    634
    635	if (!pwrdm)
    636		return -EINVAL;
    637
    638	if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
    639		return -EINVAL;
    640
    641	pr_debug("powerdomain: %s: setting next logic powerstate to %0x\n",
    642		 pwrdm->name, pwrst);
    643
    644	if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
    645		ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
    646
    647	return ret;
    648}
    649
    650/**
    651 * pwrdm_set_mem_onst - set memory power state while powerdomain ON
    652 * @pwrdm: struct powerdomain * to set
    653 * @bank: memory bank number to set (0-3)
    654 * @pwrst: one of the PWRDM_POWER_* macros
    655 *
    656 * Set the next power state @pwrst that memory bank @bank of the
    657 * powerdomain @pwrdm will enter when the powerdomain enters the ON
    658 * state.  @bank will be a number from 0 to 3, and represents different
    659 * types of memory, depending on the powerdomain.  Returns -EINVAL if
    660 * the powerdomain pointer is null or the target power state is not
    661 * supported for this memory bank, -EEXIST if the target memory
    662 * bank does not exist or is not controllable, or returns 0 upon
    663 * success.
    664 */
    665int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
    666{
    667	int ret = -EINVAL;
    668
    669	if (!pwrdm)
    670		return -EINVAL;
    671
    672	if (pwrdm->banks < (bank + 1))
    673		return -EEXIST;
    674
    675	if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
    676		return -EINVAL;
    677
    678	pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-ON to %0x\n",
    679		 pwrdm->name, bank, pwrst);
    680
    681	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
    682		ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
    683
    684	return ret;
    685}
    686
    687/**
    688 * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
    689 * @pwrdm: struct powerdomain * to set
    690 * @bank: memory bank number to set (0-3)
    691 * @pwrst: one of the PWRDM_POWER_* macros
    692 *
    693 * Set the next power state @pwrst that memory bank @bank of the
    694 * powerdomain @pwrdm will enter when the powerdomain enters the
    695 * RETENTION state.  Bank will be a number from 0 to 3, and represents
    696 * different types of memory, depending on the powerdomain.  @pwrst
    697 * will be either RETENTION or OFF, if supported.  Returns -EINVAL if
    698 * the powerdomain pointer is null or the target power state is not
    699 * supported for this memory bank, -EEXIST if the target memory
    700 * bank does not exist or is not controllable, or returns 0 upon
    701 * success.
    702 */
    703int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
    704{
    705	int ret = -EINVAL;
    706
    707	if (!pwrdm)
    708		return -EINVAL;
    709
    710	if (pwrdm->banks < (bank + 1))
    711		return -EEXIST;
    712
    713	if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
    714		return -EINVAL;
    715
    716	pr_debug("powerdomain: %s: setting next memory powerstate for bank %0x while pwrdm-RET to %0x\n",
    717		 pwrdm->name, bank, pwrst);
    718
    719	if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
    720		ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
    721
    722	return ret;
    723}
    724
    725/**
    726 * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
    727 * @pwrdm: struct powerdomain * to get current logic retention power state
    728 *
    729 * Return the power state that the logic portion of powerdomain @pwrdm
    730 * will enter when the powerdomain enters retention.  Returns -EINVAL
    731 * if the powerdomain pointer is null or returns the logic retention
    732 * power state upon success.
    733 */
    734int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
    735{
    736	int ret = -EINVAL;
    737
    738	if (!pwrdm)
    739		return -EINVAL;
    740
    741	if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
    742		ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
    743
    744	return ret;
    745}
    746
    747/**
    748 * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
    749 * @pwrdm: struct powerdomain * to get previous logic power state
    750 *
    751 * Return the powerdomain @pwrdm's previous logic power state.  Returns
    752 * -EINVAL if the powerdomain pointer is null or returns the previous
    753 * logic power state upon success.
    754 */
    755int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
    756{
    757	int ret = -EINVAL;
    758
    759	if (!pwrdm)
    760		return -EINVAL;
    761
    762	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
    763		ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
    764
    765	return ret;
    766}
    767
    768/**
    769 * pwrdm_read_logic_retst - get next powerdomain logic power state
    770 * @pwrdm: struct powerdomain * to get next logic power state
    771 *
    772 * Return the powerdomain pwrdm's logic power state.  Returns -EINVAL
    773 * if the powerdomain pointer is null or returns the next logic
    774 * power state upon success.
    775 */
    776int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
    777{
    778	int ret = -EINVAL;
    779
    780	if (!pwrdm)
    781		return -EINVAL;
    782
    783	if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
    784		ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
    785
    786	return ret;
    787}
    788
    789/**
    790 * pwrdm_read_mem_pwrst - get current memory bank power state
    791 * @pwrdm: struct powerdomain * to get current memory bank power state
    792 * @bank: memory bank number (0-3)
    793 *
    794 * Return the powerdomain @pwrdm's current memory power state for bank
    795 * @bank.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
    796 * the target memory bank does not exist or is not controllable, or
    797 * returns the current memory power state upon success.
    798 */
    799int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
    800{
    801	int ret = -EINVAL;
    802
    803	if (!pwrdm)
    804		return ret;
    805
    806	if (pwrdm->banks < (bank + 1))
    807		return ret;
    808
    809	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
    810		bank = 1;
    811
    812	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst)
    813		ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank);
    814
    815	return ret;
    816}
    817
    818/**
    819 * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
    820 * @pwrdm: struct powerdomain * to get previous memory bank power state
    821 * @bank: memory bank number (0-3)
    822 *
    823 * Return the powerdomain @pwrdm's previous memory power state for
    824 * bank @bank.  Returns -EINVAL if the powerdomain pointer is null,
    825 * -EEXIST if the target memory bank does not exist or is not
    826 * controllable, or returns the previous memory power state upon
    827 * success.
    828 */
    829int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
    830{
    831	int ret = -EINVAL;
    832
    833	if (!pwrdm)
    834		return ret;
    835
    836	if (pwrdm->banks < (bank + 1))
    837		return ret;
    838
    839	if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
    840		bank = 1;
    841
    842	if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst)
    843		ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank);
    844
    845	return ret;
    846}
    847
    848/**
    849 * pwrdm_read_mem_retst - get next memory bank power state
    850 * @pwrdm: struct powerdomain * to get mext memory bank power state
    851 * @bank: memory bank number (0-3)
    852 *
    853 * Return the powerdomain pwrdm's next memory power state for bank
    854 * x.  Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
    855 * the target memory bank does not exist or is not controllable, or
    856 * returns the next memory power state upon success.
    857 */
    858int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
    859{
    860	int ret = -EINVAL;
    861
    862	if (!pwrdm)
    863		return ret;
    864
    865	if (pwrdm->banks < (bank + 1))
    866		return ret;
    867
    868	if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
    869		ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
    870
    871	return ret;
    872}
    873
    874/**
    875 * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
    876 * @pwrdm: struct powerdomain * to clear
    877 *
    878 * Clear the powerdomain's previous power state register @pwrdm.
    879 * Clears the entire register, including logic and memory bank
    880 * previous power states.  Returns -EINVAL if the powerdomain pointer
    881 * is null, or returns 0 upon success.
    882 */
    883int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
    884{
    885	int ret = -EINVAL;
    886
    887	if (!pwrdm)
    888		return ret;
    889
    890	/*
    891	 * XXX should get the powerdomain's current state here;
    892	 * warn & fail if it is not ON.
    893	 */
    894
    895	pr_debug("powerdomain: %s: clearing previous power state reg\n",
    896		 pwrdm->name);
    897
    898	if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
    899		ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
    900
    901	return ret;
    902}
    903
    904/**
    905 * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
    906 * @pwrdm: struct powerdomain *
    907 *
    908 * Enable automatic context save-and-restore upon power state change
    909 * for some devices in the powerdomain @pwrdm.  Warning: this only
    910 * affects a subset of devices in a powerdomain; check the TRM
    911 * closely.  Returns -EINVAL if the powerdomain pointer is null or if
    912 * the powerdomain does not support automatic save-and-restore, or
    913 * returns 0 upon success.
    914 */
    915int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
    916{
    917	int ret = -EINVAL;
    918
    919	if (!pwrdm)
    920		return ret;
    921
    922	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
    923		return ret;
    924
    925	pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n", pwrdm->name);
    926
    927	if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
    928		ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
    929
    930	return ret;
    931}
    932
    933/**
    934 * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
    935 * @pwrdm: struct powerdomain *
    936 *
    937 * Disable automatic context save-and-restore upon power state change
    938 * for some devices in the powerdomain @pwrdm.  Warning: this only
    939 * affects a subset of devices in a powerdomain; check the TRM
    940 * closely.  Returns -EINVAL if the powerdomain pointer is null or if
    941 * the powerdomain does not support automatic save-and-restore, or
    942 * returns 0 upon success.
    943 */
    944int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
    945{
    946	int ret = -EINVAL;
    947
    948	if (!pwrdm)
    949		return ret;
    950
    951	if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
    952		return ret;
    953
    954	pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n", pwrdm->name);
    955
    956	if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
    957		ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
    958
    959	return ret;
    960}
    961
    962/**
    963 * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
    964 * @pwrdm: struct powerdomain *
    965 *
    966 * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
    967 * for some devices, or 0 if it does not.
    968 */
    969bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
    970{
    971	return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
    972}
    973
    974int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
    975{
    976	int ret;
    977
    978	if (!pwrdm || !arch_pwrdm)
    979		return -EINVAL;
    980
    981	ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
    982	if (!ret)
    983		ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
    984
    985	return ret;
    986}
    987
    988int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
    989{
    990	int ret;
    991
    992	pwrdm_lock(pwrdm);
    993	ret = pwrdm_state_switch_nolock(pwrdm);
    994	pwrdm_unlock(pwrdm);
    995
    996	return ret;
    997}
    998
    999int 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
   1009int 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 */
   1042u8 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
   1077up_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	}
   1091done:
   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 */
   1108int 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
   1145osps_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 */
   1159int 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 */
   1198bool 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 */
   1233static 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 */
   1246static 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
   1253static 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
   1272void pwrdms_save_context(void)
   1273{
   1274	pwrdm_for_each(pwrdm_save_context, NULL);
   1275}
   1276
   1277void pwrdms_restore_context(void)
   1278{
   1279	pwrdm_for_each(pwrdm_restore_context, NULL);
   1280}
   1281
   1282void pwrdms_lost_power(void)
   1283{
   1284	pwrdm_for_each(pwrdm_lost_power, NULL);
   1285}