Power Management

System PM APIs

group subsys_pm_sys

System Power Management API.

Functions

bool pm_state_force(uint8_t cpu, const struct pm_state_info *info)

Force usage of given power state.

This function overrides decision made by PM policy forcing usage of given power state upon next entry of the idle thread.

Note

This function can only run in thread context

Parameters:
  • cpu – CPU index.

  • info – Power state which should be used in the ongoing suspend operation.

void pm_notifier_register(struct pm_notifier *notifier)

Register a power management notifier.

Register the given notifier from the power management notification list.

Parameters:
int pm_notifier_unregister(struct pm_notifier *notifier)

Unregister a power management notifier.

Remove the given notifier from the power management notification list. After that this object callbacks will not be called.

Parameters:
Returns:

0 if the notifier was successfully removed, a negative value otherwise.

const struct pm_state_info *pm_state_next_get(uint8_t cpu)

Gets the next power state that will be used.

This function returns the next power state that will be used by the SoC.

Parameters:
  • cpu – CPU index.

Returns:

next pm_state_info that will be used

struct pm_notifier
#include <pm.h>

Power management notifier struct

This struct contains callbacks that are called when the target enters and exits power states.

As currently implemented the entry callback is invoked when transitioning from PM_STATE_ACTIVE to another state, and the exit callback is invoked when transitioning from a non-active state to PM_STATE_ACTIVE. This behavior may change in the future.

Note

These callbacks can be called from the ISR of the event that caused the kernel exit from idling.

Note

It is not allowed to call pm_notifier_unregister or pm_notifier_register from these callbacks because they are called with the spin locked in those functions.

Public Members

void (*state_entry)(enum pm_state state)

Application defined function for doing any target specific operations for power state entry.

void (*state_exit)(enum pm_state state)

Application defined function for doing any target specific operations for power state exit.

States

group subsys_pm_states

System Power Management States.

Defines

PM_STATE_INFO_DT_INIT(node_id)

Initializer for struct pm_state_info given a DT node identifier with zephyr,power-state compatible.

Parameters:
  • node_id – A node identifier with compatible zephyr,power-state

PM_STATE_DT_INIT(node_id)

Initializer for enum pm_state given a DT node identifier with zephyr,power-state compatible.

Parameters:
  • node_id – A node identifier with compatible zephyr,power-state

DT_NUM_CPU_POWER_STATES(node_id)

Obtain number of CPU power states supported by the given CPU node identifier.

Parameters:
  • node_id – A CPU node identifier.

Returns:

Number of supported CPU power states.

PM_STATE_INFO_LIST_FROM_DT_CPU(node_id)

Initialize an array of struct pm_state_info with information from all the states present in the given CPU node identifier.

Example devicetree fragment:

cpus {
   ...
   cpu0: cpu@0 {
           device_type = "cpu";
           ...
           cpu-power-states = <&state0 &state1>;
   };
};

...
power-states {
   state0: state0 {
           compatible = "zephyr,power-state";
           power-state-name = "suspend-to-idle";
           min-residency-us = <10000>;
           exit-latency-us = <100>;
   };

   state1: state1 {
           compatible = "zephyr,power-state";
           power-state-name = "suspend-to-ram";
           min-residency-us = <50000>;
           exit-latency-us = <500>;
   };
};

Example usage:

const struct pm_state_info states[] =
     PM_STATE_INFO_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
Parameters:
  • node_id – A CPU node identifier.

PM_STATE_LIST_FROM_DT_CPU(node_id)

Initialize an array of struct pm_state with information from all the states present in the given CPU node identifier.

Example devicetree fragment:

cpus {
   ...
   cpu0: cpu@0 {
           device_type = "cpu";
           ...
           cpu-power-states = <&state0 &state1>;
   };
};

...
power-states {
   state0: state0 {
           compatible = "zephyr,power-state";
           power-state-name = "suspend-to-idle";
           min-residency-us = <10000>;
           exit-latency-us = <100>;
   };

   state1: state1 {
           compatible = "zephyr,power-state";
           power-state-name = "suspend-to-ram";
           min-residency-us = <50000>;
           exit-latency-us = <500>;
   };
};

Example usage:

const enum pm_state states[] = PM_STATE_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
Parameters:
  • node_id – A CPU node identifier.

Enums

enum pm_state

Power management state

Values:

enumerator PM_STATE_ACTIVE

Runtime active state.

The system is fully powered and active.

Note

This state is correlated with ACPI G0/S0 state

enumerator PM_STATE_RUNTIME_IDLE

Runtime idle state.

Runtime idle is a system sleep state in which all of the cores enter deepest possible idle state and wait for interrupts, no requirements for the devices, leaving them at the states where they are.

Note

This state is correlated with ACPI S0ix state

enumerator PM_STATE_SUSPEND_TO_IDLE

Suspend to idle state.

The system goes through a normal platform suspend where it puts all of the cores in deepest possible idle state and may puts peripherals into low-power states. No operating state is lost (ie. the cpu core does not lose execution context), so the system can go back to where it left off easily enough.

Note

This state is correlated with ACPI S1 state

enumerator PM_STATE_STANDBY

Standby state.

In addition to putting peripherals into low-power states all non-boot CPUs are powered off. It should allow more energy to be saved relative to suspend to idle, but the resume latency will generally be greater than for that state. But it should be the same state with suspend to idle state on uniprocessor system.

Note

This state is correlated with ACPI S2 state

enumerator PM_STATE_SUSPEND_TO_RAM

Suspend to ram state.

This state offers significant energy savings by powering off as much of the system as possible, where memory should be placed into the self-refresh mode to retain its contents. The state of devices and CPUs is saved and held in memory, and it may require some boot- strapping code in ROM to resume the system from it.

Note

This state is correlated with ACPI S3 state

enumerator PM_STATE_SUSPEND_TO_DISK

Suspend to disk state.

This state offers significant energy savings by powering off as much of the system as possible, including the memory. The contents of memory are written to disk or other non-volatile storage, and on resume it’s read back into memory with the help of boot-strapping code, restores the system to the same point of execution where it went to suspend to disk.

Note

This state is correlated with ACPI S4 state

enumerator PM_STATE_SOFT_OFF

Soft off state.

This state consumes a minimal amount of power and requires a large latency in order to return to runtime active state. The contents of system(CPU and memory) will not be preserved, so the system will be restarted as if from initial power-up and kernel boot.

Note

This state is correlated with ACPI G2/S5 state

enumerator PM_STATE_COUNT

Number of power management states (internal use)

Functions

uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states)

Obtain information about all supported states by a CPU.

Parameters:
  • cpu – CPU index.

  • states – Where to store the list of supported states.

Returns:

Number of supported states.

struct pm_state_info
#include <state.h>

Information about a power management state

Public Members

uint8_t substate_id

Some platforms have multiple states that map to one Zephyr power state. This property allows the platform distinguish them. e.g:

power-states {
   state0: state0 {
           compatible = "zephyr,power-state";
           power-state-name = "suspend-to-idle";
           substate-id = <1>;
           min-residency-us = <10000>;
           exit-latency-us = <100>;
   };
   state1: state1 {
           compatible = "zephyr,power-state";
           power-state-name = "suspend-to-idle";
           substate-id = <2>;
           min-residency-us = <20000>;
           exit-latency-us = <200>;
   };
};
uint32_t min_residency_us

Minimum residency duration in microseconds. It is the minimum time for a given idle state to be worthwhile energywise.

Note

0 means that this property is not available for this state.

uint32_t exit_latency_us

Worst case latency in microseconds required to exit the idle state.

Note

0 means that this property is not available for this state.

Policy

group subsys_pm_sys_policy

System Power Management Policy API.

Defines

PM_ALL_SUBSTATES

Special value for ‘all substates’.

Typedefs

typedef void (*pm_policy_latency_changed_cb_t)(int32_t latency)

Callback to notify when maximum latency changes.

Param latency:

New maximum latency. Positive value represents latency in microseconds. SYS_FOREVER_US value lifts the latency constraint. Other values are forbidden.

Functions

void pm_policy_state_lock_get(enum pm_state state, uint8_t substate_id)

Increase a power state lock counter.

A power state will not be allowed on the first call of pm_policy_state_lock_get(). Subsequent calls will just increase a reference count, thus meaning this API can be safely used concurrently. A state will be allowed again after pm_policy_state_lock_put() is called as many times as pm_policy_state_lock_get().

Note that the PM_STATE_ACTIVE state is always allowed, so calling this API with PM_STATE_ACTIVE will have no effect.

Parameters:
  • state – Power state.

  • substate_id – Power substate ID. Use PM_ALL_SUBSTATES to affect all the substates in the given power state.

void pm_policy_state_lock_put(enum pm_state state, uint8_t substate_id)

Decrease a power state lock counter.

Parameters:
  • state – Power state.

  • substate_id – Power substate ID. Use PM_ALL_SUBSTATES to affect all the substates in the given power state.

bool pm_policy_state_lock_is_active(enum pm_state state, uint8_t substate_id)

Check if a power state lock is active (not allowed).

Parameters:
  • state – Power state.

  • substate_id – Power substate ID. Use PM_ALL_SUBSTATES to affect all the substates in the given power state.

Return values:
  • true – if power state lock is active.

  • false – if power state lock is not active.

void pm_policy_latency_request_add(struct pm_policy_latency_request *req, uint32_t value)

Add a new latency requirement.

The system will not enter any power state that would make the system to exceed the given latency value.

Parameters:
  • req – Latency request.

  • value – Maximum allowed latency in microseconds.

void pm_policy_latency_request_update(struct pm_policy_latency_request *req, uint32_t value)

Update a latency requirement.

Parameters:
  • req – Latency request.

  • value – New maximum allowed latency in microseconds.

void pm_policy_latency_request_remove(struct pm_policy_latency_request *req)

Remove a latency requirement.

Parameters:
  • req – Latency request.

void pm_policy_latency_changed_subscribe(struct pm_policy_latency_subscription *req, pm_policy_latency_changed_cb_t cb)

Subscribe to maximum latency changes.

Parameters:
  • req – Subscription request.

  • cb – Callback function (NULL to disable).

void pm_policy_latency_changed_unsubscribe(struct pm_policy_latency_subscription *req)

Unsubscribe to maximum latency changes.

Parameters:
  • req – Subscription request.

struct pm_policy_latency_subscription
#include <policy.h>

Latency change subscription.

Public Members

pm_policy_latency_changed_cb_t cb

Notification callback.

struct pm_policy_latency_request
#include <policy.h>

Latency request.

Public Members

uint32_t value

Request value.

Hooks

group subsys_pm_sys_hooks

System Power Management Hooks.

Functions

void pm_state_set(enum pm_state state, uint8_t substate_id)

Put processor into a power state.

This function implements the SoC specific details necessary to put the processor into available power states.

Parameters:
  • state – Power state.

  • substate_id – Power substate id.

void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)

Do any SoC or architecture specific post ops after sleep state exits.

This function is a place holder to do any operations that may be needed to be done after sleep state exits. Currently it enables interrupts after resuming from sleep state. In future, the enabling of interrupts may be moved into the kernel.

Parameters:
  • state – Power state.

  • substate_id – Power substate id.

Device PM APIs

group subsys_pm_device

Device Power Management API.

Defines

PM_DEVICE_DEFINE(dev_id, pm_action_cb)

Define device PM resources for the given device name.

Note

This macro is a no-op if CONFIG_PM_DEVICE is not enabled.

Parameters:
  • dev_id – Device id.

  • pm_action_cb – PM control callback.

PM_DEVICE_DT_DEFINE(node_id, pm_action_cb)

Define device PM resources for the given node identifier.

Note

This macro is a no-op if CONFIG_PM_DEVICE is not enabled.

Parameters:
  • node_id – Node identifier.

  • pm_action_cb – PM control callback.

PM_DEVICE_DT_INST_DEFINE(idx, pm_action_cb)

Define device PM resources for the given instance.

Note

This macro is a no-op if CONFIG_PM_DEVICE is not enabled.

Parameters:
  • idx – Instance index.

  • pm_action_cb – PM control callback.

PM_DEVICE_GET(dev_id)

Obtain a reference to the device PM resources for the given device.

Parameters:
  • dev_id – Device id.

Returns:

Reference to the device PM resources (NULL if device CONFIG_PM_DEVICE is disabled).

PM_DEVICE_DT_GET(node_id)

Obtain a reference to the device PM resources for the given node.

Parameters:
  • node_id – Node identifier.

Returns:

Reference to the device PM resources (NULL if device CONFIG_PM_DEVICE is disabled).

PM_DEVICE_DT_INST_GET(idx)

Obtain a reference to the device PM resources for the given instance.

Parameters:
  • idx – Instance index.

Returns:

Reference to the device PM resources (NULL if device CONFIG_PM_DEVICE is disabled).

Typedefs

typedef int (*pm_device_action_cb_t)(const struct device *dev, enum pm_device_action action)

Device PM action callback.

Param dev:

Device instance.

Param action:

Requested action.

Retval 0:

If successful.

Retval -ENOTSUP:

If the requested action is not supported.

Retval Errno:

Other negative errno on failure.

typedef bool (*pm_device_action_failed_cb_t)(const struct device *dev, int err)

Device PM action failed callback.

Param dev:

Device that failed the action.

Param err:

Return code of action failure.

Return:

True to continue iteration, false to halt iteration.

Enums

enum pm_device_state

Device power states.

Values:

enumerator PM_DEVICE_STATE_ACTIVE

Device is in active or regular state.

enumerator PM_DEVICE_STATE_SUSPENDED

Device is suspended.

Note

Device context may be lost.

enumerator PM_DEVICE_STATE_SUSPENDING

Device is being suspended.

enumerator PM_DEVICE_STATE_OFF

Device is turned off (power removed).

Note

Device context is lost.

enum pm_device_action

Device PM actions.

Values:

enumerator PM_DEVICE_ACTION_SUSPEND

Suspend.

enumerator PM_DEVICE_ACTION_RESUME

Resume.

enumerator PM_DEVICE_ACTION_TURN_OFF

Turn off.

Note

Action triggered only by a power domain.

enumerator PM_DEVICE_ACTION_TURN_ON

Turn on.

Note

Action triggered only by a power domain.

Functions

const char *pm_device_state_str(enum pm_device_state state)

Get name of device PM state.

Parameters:
  • state – State id which name should be returned

int pm_device_action_run(const struct device *dev, enum pm_device_action action)

Run a pm action on a device.

This function calls the device PM control callback so that the device does the necessary operations to execute the given action.

Parameters:
  • dev – Device instance.

  • action – Device pm action.

Return values:
  • 0 – If successful.

  • -ENOTSUP – If requested state is not supported.

  • -EALREADY – If device is already at the requested state.

  • -EBUSY – If device is changing its state.

  • -ENOSYS – If device does not support PM.

  • -EPERM – If device has power state locked.

  • Errno – Other negative errno on failure.

void pm_device_children_action_run(const struct device *dev, enum pm_device_action action, pm_device_action_failed_cb_t failure_cb)

Run a pm action on all children of a device.

This function calls all child devices PM control callback so that the device does the necessary operations to execute the given action.

Parameters:
  • dev – Device instance.

  • action – Device pm action.

  • failure_cb – Function to call if a child fails the action, can be NULL.

int pm_device_state_get(const struct device *dev, enum pm_device_state *state)

Obtain the power state of a device.

Parameters:
  • dev – Device instance.

  • state – Pointer where device power state will be stored.

Return values:
  • 0 – If successful.

  • -ENOSYS – If device does not implement power management.

static inline void pm_device_init_suspended(const struct device *dev)

Initialize a device state to PM_DEVICE_STATE_SUSPENDED.

By default device state is initialized to PM_DEVICE_STATE_ACTIVE. However in order to save power some drivers may choose to only initialize the device to the suspended state, or actively put the device into the suspended state. This function can therefore be used to notify the PM subsystem that the device is in PM_DEVICE_STATE_SUSPENDED instead of the default.

Parameters:
  • dev – Device instance.

static inline void pm_device_init_off(const struct device *dev)

Initialize a device state to PM_DEVICE_STATE_OFF.

By default device state is initialized to PM_DEVICE_STATE_ACTIVE. In general, this makes sense because the device initialization function will resume and configure a device, leaving it operational. However, when power domains are enabled, the device may be connected to a switchable power source, in which case it won’t be powered at boot. This function can therefore be used to notify the PM subsystem that the device is in PM_DEVICE_STATE_OFF instead of the default.

Parameters:
  • dev – Device instance.

void pm_device_busy_set(const struct device *dev)

Mark a device as busy.

Devices marked as busy will not be suspended when the system goes into low-power states. This can be useful if, for example, the device is in the middle of a transaction.

Parameters:
  • dev – Device instance.

void pm_device_busy_clear(const struct device *dev)

Clear a device busy status.

Parameters:
  • dev – Device instance.

bool pm_device_is_any_busy(void)

Check if any device is busy.

Return values:
  • false – If no device is busy

  • true – If one or more devices are busy

bool pm_device_is_busy(const struct device *dev)

Check if a device is busy.

Parameters:
  • dev – Device instance.

Return values:
  • false – If the device is not busy

  • true – If the device is busy

bool pm_device_wakeup_enable(const struct device *dev, bool enable)

Enable or disable a device as a wake up source.

A device marked as a wake up source will not be suspended when the system goes into low-power modes, thus allowing to use it as a wake up source for the system.

Parameters:
  • dev – Device instance.

  • enabletrue to enable or false to disable

Return values:
  • true – If the wakeup source was successfully enabled.

  • false – If the wakeup source was not successfully enabled.

bool pm_device_wakeup_is_enabled(const struct device *dev)

Check if a device is enabled as a wake up source.

Parameters:
  • dev – Device instance.

Return values:
  • true – if the wakeup source is enabled.

  • false – if the wakeup source is not enabled.

bool pm_device_wakeup_is_capable(const struct device *dev)

Check if a device is wake up capable.

Parameters:
  • dev – Device instance.

Return values:
  • true – If the device is wake up capable.

  • false – If the device is not wake up capable.

void pm_device_state_lock(const struct device *dev)

Lock current device state.

This function locks the current device power state. Once locked the device power state will not be changed by system power management or device runtime power management until unlocked.

Note

The given device should not have device runtime enabled.

Parameters:
  • dev – Device instance.

void pm_device_state_unlock(const struct device *dev)

Unlock the current device state.

Unlocks a previously locked device pm.

Parameters:
  • dev – Device instance.

bool pm_device_state_is_locked(const struct device *dev)

Check if the device pm is locked.

Parameters:
  • dev – Device instance.

Return values:
  • true – If device is locked.

  • false – If device is not locked.

bool pm_device_on_power_domain(const struct device *dev)

Check if the device is on a switchable power domain.

Parameters:
  • dev – Device instance.

Return values:
  • true – If device is on a switchable power domain.

  • false – If device is not on a switchable power domain.

int pm_device_power_domain_add(const struct device *dev, const struct device *domain)

Add a device to a power domain.

This function adds a device to a given power domain.

Parameters:
  • dev – Device to be added to the power domain.

  • domain – Power domain.

Return values:
  • 0 – If successful.

  • -EALREADY – If device is already part of the power domain.

  • -ENOSYS – If the application was built without power domain support.

  • -ENOSPC – If there is no space available in the power domain to add the device.

int pm_device_power_domain_remove(const struct device *dev, const struct device *domain)

Remove a device from a power domain.

This function removes a device from a given power domain.

Parameters:
  • dev – Device to be removed from the power domain.

  • domain – Power domain.

Return values:
  • 0 – If successful.

  • -ENOSYS – If the application was built without power domain support.

  • -ENOENT – If device is not in the given domain.

bool pm_device_is_powered(const struct device *dev)

Check if the device is currently powered.

Parameters:
  • dev – Device instance.

Return values:
  • true – If device is currently powered

  • false – If device is not currently powered

struct pm_device
#include <device.h>

Device PM info.

Public Members

const struct device *dev

Pointer to the device

struct k_mutex lock

Lock to synchronize the get/put operations

uint32_t usage

Device usage count

struct k_work_delayable work

Work object for asynchronous calls

struct k_condvar condvar

Event conditional var to listen to the sync request events

enum pm_device_state state

Device power state

pm_device_action_cb_t action_cb

Device PM action callback

Device Runtime PM APIs

group subsys_pm_device_runtime

Device Runtime Power Management API.

Functions

int pm_device_runtime_enable(const struct device *dev)

Enable device runtime PM.

This function will enable runtime PM on the given device. If the device is in PM_DEVICE_STATE_ACTIVE state, the device will be suspended.

Function properties (list may not be complete)

pre-kernel-ok

Parameters:
  • dev – Device instance.

Return values:
  • 0 – If the device runtime PM is enabled successfully.

  • -EPERM – If device has power state locked.

  • -ENOTSUP – If the device does not support PM.

  • -ENOSYS – If the functionality is not available.

  • -errno – Other negative errno, result of suspending the device.

int pm_device_runtime_disable(const struct device *dev)

Disable device runtime PM.

If the device is currently suspended it will be resumed.

Function properties (list may not be complete)

pre-kernel-ok

Parameters:
  • dev – Device instance.

Return values:
  • 0 – If the device runtime PM is disabled successfully.

  • -ENOTSUP – If the device does not support PM.

  • -ENOSYS – If the functionality is not available.

  • -errno – Other negative errno, result of resuming the device.

int pm_device_runtime_get(const struct device *dev)

Resume a device based on usage count.

This function will resume the device if the device is suspended (usage count equal to 0). In case of a resume failure, usage count and device state will be left unchanged. In all other cases, usage count will be incremented.

If the device is still being suspended as a result of calling pm_device_runtime_put_async(), this function will wait for the operation to finish to then resume the device.

Function properties (list may not be complete)

pre-kernel-ok

Parameters:
  • dev – Device instance.

Return values:
  • 0 – If it succeeds. In case device runtime PM is not enabled or not available this function will be a no-op and will also return 0.

  • -ENOTSUP – If the device does not support PM.

  • -errno – Other negative errno, result of the PM action callback.

int pm_device_runtime_put(const struct device *dev)

Suspend a device based on usage count.

This function will suspend the device if the device is no longer required (usage count equal to 0). In case of suspend failure, usage count and device state will be left unchanged. In all other cases, usage count will be decremented (down to 0).

Function properties (list may not be complete)

pre-kernel-ok

Parameters:
  • dev – Device instance.

Return values:
  • 0 – If it succeeds. In case device runtime PM is not enabled or not available this function will be a no-op and will also return 0.

  • -ENOTSUP – If the device does not support PM.

  • -EALREADY – If device is already suspended (can only happen if get/put calls are unbalanced).

  • -errno – Other negative errno, result of the action callback.

int pm_device_runtime_put_async(const struct device *dev)

Suspend a device based on usage count (asynchronously).

This function will schedule the device suspension if the device is no longer required (usage count equal to 0). In all other cases, usage count will be decremented (down to 0).

Function properties (list may not be complete)

pre-kernel-ok , async

Note

Asynchronous operations are not supported when in pre-kernel mode. In this case, the function will be blocking (equivalent to pm_device_runtime_put()).

Parameters:
  • dev – Device instance.

Return values:
  • 0 – If it succeeds. In case device runtime PM is not enabled or not available this function will be a no-op and will also return 0.

  • -ENOTSUP – If the device does not support PM.

  • -EALREADY – If device is already suspended (can only happen if get/put calls are unbalanced).

bool pm_device_runtime_is_enabled(const struct device *dev)

Check if device runtime is enabled for a given device.

Function properties (list may not be complete)

pre-kernel-ok

Parameters:
  • dev – Device instance.

Return values:
  • true – If device has device runtime PM enabled.

  • false – If the device has device runtime PM disabled.