Power Management APIs
Power Management Hook Interface
-
void
_sys_soc_resume
(void) Hook function to notify exit of a power policy.
The purpose of this function is to notify exit from deep sleep, low power state or device suspend only policy. States altered at _sys_soc_suspend() should be restored in this function. Exit from each policy requires different handling as follows.
Deep sleep policy exit: App should save information in SoC at _sys_soc_suspend() that will persist across deep sleep. This function should check that information to identify deep sleep recovery. In this case this function will restore states and resume execution at the point were system entered deep sleep. In this mode, this function is called with the interrupt stack. It is important that this function, before interrupts are enabled, restores the stack that was in use when system went to deep sleep. This is to avoid interfering interrupt handlers use of this stack.
Cold boot and deep sleep recovery happen at the same location. Since kernel does not store deep sleep state, kernel will call this function in both cases. It is the responsibility of the power manager application to identify whether it is cold boot or deep sleep exit using state information that it stores. If the function detects cold boot, then it returns immediately.
Low power state policy exit: Low power state policy does a CPU idle wait using a low power CPU idle state supported by the processor. This state is exited by an interrupt. In this case this function would be called from the interrupt’s ISR context. Any state altered at _sys_soc_suspend should be restored and the function should return quickly.
Device suspend only policy exit: This function will be called at the exit of kernel’s CPU idle wait if device suspend only policy was used. Resume operations should be done for devices that were suspended in _sys_soc_suspend(). This function is called in ISR context and it should return quickly.
- Return
- will not return to caller in deep sleep recovery
-
int
_sys_soc_suspend
(int32_t ticks) Hook function to allow power policy entry.
This function is called by the kernel when it is about to idle. It is passed the number of clock ticks that the kernel calculated as available time to idle. This function should compare this time with the wake latency of various power saving schemes that the power manager application implements and use the one that fits best. The power saving schemes can be mapped to following policies.
Deep sleep policy: This turns off the core voltage rail and system clock, while RAM is retained. This would save most power but would also have a high wake latency. CPU loses state so this function should save CPU states in RAM and the location in this function where system should resume execution at resume. It should re-enable interrupts and return SYS_PM_DEEP_SLEEP.
Low power state policy: Peripherals can be turned off and clocks can be gated depending on time available. Then switches to CPU low power state. In this state the CPU is still active but in a low power state and does not lose any state. This state is exited by an interrupt from where the _sys_soc_resume() will be called. To allow interrupts to occur, this function should ensure that interrupts are atomically enabled before going to the low power CPU idle state. The atomicity of enabling interrupts before entering cpu idle wait is essential to avoid a task switch away from the kernel idle task before the cpu idle wait is reached. This function should return SYS_PM_LOW_POWER_STATE.
Device suspend only policy: This function can take advantage of the kernel’s idling logic by turning off peripherals and clocks depending on available time. It can return SYS_PM_DEVICE_SUSPEND_ONLY to indicate the kernel should do its own CPU idle wait. After the Kernel’s idle wait is completed or if any interrupt occurs, the _sys_soc_resume() function will be called to allow restoring of altered states. Interrupts should not be turned on in this case.
If this function decides to not do any operation then it should return SYS_PM_NOT_HANDLED to let kernel do its normal idle processing.
This function is entered with interrupts disabled. It should re-enable interrupts if it does CPU low power wait or deep sleep.
- Parameters
ticks
: the upcoming kernel idle time
- Return Value
SYS_PM_NOT_HANDLED
: If No PM operations done.SYS_PM_DEVICE_SUSPEND_ONLY
: If only devices were suspended.SYS_PM_LOW_POWER_STATE
: If LPS policy entered.SYS_PM_DEEP_SLEEP
: If Deep Sleep policy entered.
Device Power Management APIs
-
void
device_busy_set
(struct device *busy_dev) Indicate that the device is in the middle of a transaction.
Called by a device driver to indicate that it is in the middle of a transaction.
- Parameters
busy_dev
: Pointer to device structure of the driver instance.
-
void
device_busy_clear
(struct device *busy_dev) Indicate that the device has completed its transaction.
Called by a device driver to indicate the end of a transaction.
- Parameters
busy_dev
: Pointer to device structure of the driver instance.
-
int
device_pm_nop
(struct device *unused_device, int unused_policy) No-op function to initialize unimplemented pm hooks.
This function should be used to initialize device pm hooks for which a device has no operation.
- Parameters
unused_device
: Unusedunused_policy
: Unused
- Return Value
0
: Always returns 0
-
static int
device_suspend
(struct device *device, int pm_policy) Call the suspend function of a device.
Called by the Power Manager application to let the device do any policy based PM suspend operations.
- Parameters
device
: Pointer to device structure of the driver instance.pm_policy
: PM policy for which this call is made.
- Return Value
0
: If successful.Errno
: Negative errno code if failure.
-
static int
device_resume
(struct device *device, int pm_policy) Call the resume function of a device.
Called by the Power Manager application to let the device do any policy based PM resume operations.
- Parameters
device
: Pointer to device structure of the driver instance.pm_policy
: PM policy for which this call is made.
- Return Value
0
: If successful.Errno
: Negative errno code if failure.
-
void
device_list_get
(struct device **device_list, int *device_count) Gets the device structure list array and device count.
Called by the Power Manager application to get the list of device structures associated with the devices in the system. The PM app would use this list to create its own sorted list based on the order it wishes to suspend or resume the devices.
- Parameters
device_list
: Pointer to receive the device list arraydevice_count
: Pointer to receive the device count
-
int
device_any_busy_check
(void) Check if any device is in the middle of a transaction.
Called by an application to see if any device is in the middle of a critical transaction that cannot be interrupted.
- Return Value
0
: if no device is busy-EBUSY
: if any device is busy
-
int
device_busy_check
(struct device *chk_dev) Check if a specific device is in the middle of a transaction.
Called by an application to see if a particular device is in the middle of a critical transaction that cannot be interrupted.
- Parameters
chk_dev
: Pointer to device structure of the specific device driver the caller is interested in.
- Return Value
0
: if the device is not busy-EBUSY
: if the device is busy
-
DEFINE_DEVICE_PM_OPS
(_name, _suspend, _resume) struct device_pm_ops _name##_dev_pm_ops = { \ .suspend = _suspend, \ .resume = _resume, \ } Helper macro to define the device_pm_ops structure.
- Parameters
_name
: name of the device_suspend
: name of the suspend function_resume
: name of the resume function
-
DEVICE_PM_OPS_GET
(_name) (&_name##_dev_pm_ops) Macro to get a pointer to the device_ops_structure.
Will return the name of the structure that was created using DEFINE_PM_OPS macro if CONFIG_DEVICE_POWER_MANAGEMENT is defined. Otherwise, will return NULL.
- Parameters
_name
: name of the device
-
DEVICE_PM_OPS_DECLARE
(_name) extern struct device_pm_ops _name##_dev_pm_ops Macro to declare the device_pm_ops structure.
The declaration would be added if CONFIG_DEVICE_POWER_MANAGEMENT is defined. Otherwise this macro will not add anything.
- Parameters
_name
: name of the device
-
struct
device_pm_ops
- #include <device.h>
Structure holding handlers for device PM operations.
- Parameters
suspend
: Pointer to the handler for suspend operationsresume
: Pointer to the handler for resume operations