|  | /* | 
|  | * Copyright (c) 2012-2014 Wind River Systems, Inc. | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | #ifndef ZEPHYR_INCLUDE_POWER_POWER_H_ | 
|  | #define ZEPHYR_INCLUDE_POWER_POWER_H_ | 
|  |  | 
|  | #include <zephyr/types.h> | 
|  | #include <stdbool.h> | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | /** | 
|  | * @defgroup power_management_api Power Management | 
|  | * @{ | 
|  | * @} | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief System power states. | 
|  | */ | 
|  | enum power_states { | 
|  | SYS_POWER_STATE_AUTO	= (-2), | 
|  | SYS_POWER_STATE_ACTIVE	= (-1), | 
|  | #ifdef CONFIG_SYS_POWER_SLEEP_STATES | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_1 | 
|  | SYS_POWER_STATE_SLEEP_1, | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_2 | 
|  | SYS_POWER_STATE_SLEEP_2, | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_3 | 
|  | SYS_POWER_STATE_SLEEP_3, | 
|  | # endif | 
|  | #endif /* CONFIG_SYS_POWER_SLEEP_STATES */ | 
|  |  | 
|  | #ifdef CONFIG_SYS_POWER_DEEP_SLEEP_STATES | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_1 | 
|  | SYS_POWER_STATE_DEEP_SLEEP_1, | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_2 | 
|  | SYS_POWER_STATE_DEEP_SLEEP_2, | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_3 | 
|  | SYS_POWER_STATE_DEEP_SLEEP_3, | 
|  | # endif | 
|  | #endif /* CONFIG_SYS_POWER_DEEP_SLEEP_STATES */ | 
|  | SYS_POWER_STATE_MAX | 
|  | }; | 
|  |  | 
|  | #ifdef CONFIG_SYS_POWER_MANAGEMENT | 
|  |  | 
|  | extern unsigned char sys_pm_idle_exit_notify; | 
|  |  | 
|  | /** | 
|  | * @brief System Power Management API | 
|  | * | 
|  | * @defgroup system_power_management_api System Power Management API | 
|  | * @ingroup power_management_api | 
|  | * @{ | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief Check if particular power state is a sleep state. | 
|  | * | 
|  | * This function returns true if given power state is a sleep state. | 
|  | */ | 
|  | static inline bool sys_pm_is_sleep_state(enum power_states state) | 
|  | { | 
|  | bool ret = true; | 
|  |  | 
|  | switch (state) { | 
|  | #ifdef CONFIG_SYS_POWER_SLEEP_STATES | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_1 | 
|  | case SYS_POWER_STATE_SLEEP_1: | 
|  | break; | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_2 | 
|  | case SYS_POWER_STATE_SLEEP_2: | 
|  | break; | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_SLEEP_3 | 
|  | case SYS_POWER_STATE_SLEEP_3: | 
|  | break; | 
|  | # endif | 
|  | #endif /* CONFIG_SYS_POWER_SLEEP_STATES */ | 
|  | default: | 
|  | ret = false; | 
|  | break; | 
|  | } | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Check if particular power state is a deep sleep state. | 
|  | * | 
|  | * This function returns true if given power state is a deep sleep state. | 
|  | */ | 
|  | static inline bool sys_pm_is_deep_sleep_state(enum power_states state) | 
|  | { | 
|  | bool ret = true; | 
|  |  | 
|  | switch (state) { | 
|  | #ifdef CONFIG_SYS_POWER_DEEP_SLEEP_STATES | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_1 | 
|  | case SYS_POWER_STATE_DEEP_SLEEP_1: | 
|  | break; | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_2 | 
|  | case SYS_POWER_STATE_DEEP_SLEEP_2: | 
|  | break; | 
|  | # endif | 
|  | # ifdef CONFIG_HAS_SYS_POWER_STATE_DEEP_SLEEP_3 | 
|  | case SYS_POWER_STATE_DEEP_SLEEP_3: | 
|  | break; | 
|  | # endif | 
|  | #endif /* CONFIG_SYS_POWER_DEEP_SLEEP_STATES */ | 
|  |  | 
|  | default: | 
|  | ret = false; | 
|  | break; | 
|  | } | 
|  |  | 
|  | return ret; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Function to disable power management idle exit notification | 
|  | * | 
|  | * The _sys_resume() would be called from the ISR of the event that caused | 
|  | * exit from kernel idling after PM operations. For some power operations, | 
|  | * this notification may not be necessary. This function can be called in | 
|  | * _sys_suspend to disable the corresponding _sys_resume notification. | 
|  | * | 
|  | */ | 
|  | static inline void _sys_pm_idle_exit_notification_disable(void) | 
|  | { | 
|  | sys_pm_idle_exit_notify = 0U; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Force usage of given power state. | 
|  | * | 
|  | * This function overrides decision made by PM policy forcing | 
|  | * usage of given power state in the ongoing suspend operation. | 
|  | * And before the end of suspend, the state of forced_pm_state | 
|  | * is cleared with interrupt disabled. | 
|  | * | 
|  | * If enabled SYS_PM_DIRECT_FORCE_MODE, this function can only | 
|  | * run in thread context. | 
|  | * | 
|  | * @param state Power state which should be used in the ongoing | 
|  | *		suspend operation or SYS_POWER_STATE_AUTO. | 
|  | */ | 
|  | void sys_pm_force_power_state(enum power_states state); | 
|  |  | 
|  | /** | 
|  | * @brief Put processor into a power state. | 
|  | * | 
|  | * This function implements the SoC specific details necessary | 
|  | * to put the processor into available power states. | 
|  | */ | 
|  | void sys_set_power_state(enum power_states state); | 
|  |  | 
|  | #ifdef CONFIG_SYS_PM_DEBUG | 
|  | /** | 
|  | * @brief Dump Low Power states related debug info | 
|  | * | 
|  | * Dump Low Power states debug info like LPS entry count and residencies. | 
|  | */ | 
|  | void sys_pm_dump_debug_info(void); | 
|  |  | 
|  | #endif /* CONFIG_SYS_PM_DEBUG */ | 
|  |  | 
|  | #ifdef CONFIG_SYS_PM_STATE_LOCK | 
|  | /** | 
|  | * @brief Disable particular power state | 
|  | * | 
|  | * @details Disabled state cannot be selected by the Zephyr power | 
|  | *	    management policies. Application defined policy should | 
|  | *	    use the @ref sys_pm_ctrl_is_state_enabled function to | 
|  | *	    check if given state could is enabled and could be used. | 
|  | * | 
|  | * @param [in] state Power state to be disabled. | 
|  | */ | 
|  | void sys_pm_ctrl_disable_state(enum power_states state); | 
|  |  | 
|  | /** | 
|  | * @brief Enable particular power state | 
|  | * | 
|  | * @details Enabled state can be selected by the Zephyr power | 
|  | *	    management policies. Application defined policy should | 
|  | *	    use the @ref sys_pm_ctrl_is_state_enabled function to | 
|  | *	    check if given state could is enabled and could be used. | 
|  | *	    By default all power states are enabled. | 
|  | * | 
|  | * @param [in] state Power state to be enabled. | 
|  | */ | 
|  | void sys_pm_ctrl_enable_state(enum power_states state); | 
|  |  | 
|  | /** | 
|  | * @brief Check if particular power state is enabled | 
|  | * | 
|  | * This function returns true if given power state is enabled. | 
|  | * | 
|  | * @param [in] state Power state. | 
|  | */ | 
|  | bool sys_pm_ctrl_is_state_enabled(enum power_states state); | 
|  |  | 
|  | #endif /* CONFIG_SYS_PM_STATE_LOCK */ | 
|  |  | 
|  | /** | 
|  | * @} | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief Power Management Hooks | 
|  | * | 
|  | * @defgroup power_management_hook_interface Power Management Hooks | 
|  | * @ingroup power_management_api | 
|  | * @{ | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief Restore context to the point where system entered the deep sleep | 
|  | * state. | 
|  | * | 
|  | * This function is optionally called when exiting from deep sleep if the SOC | 
|  | * interface does not have bootloader support to handle resume from deep sleep. | 
|  | * This function should restore context to the point where system entered | 
|  | * the deep sleep state. | 
|  | * | 
|  | * If the function is called at cold boot it should return immediately. | 
|  | * | 
|  | * @note This function is not supported on all architectures. | 
|  | */ | 
|  | void _sys_resume_from_deep_sleep(void); | 
|  |  | 
|  | /** | 
|  | * @brief Notify exit from kernel idling after PM operations | 
|  | * | 
|  | * This function would notify exit from kernel idling if a corresponding | 
|  | * _sys_suspend() notification was handled and did not return | 
|  | * SYS_POWER_STATE_ACTIVE. | 
|  | * | 
|  | * This function would be called from the ISR context of the event | 
|  | * that caused the exit from kernel idling. This will be called immediately | 
|  | * after interrupts are enabled. This is called to give a chance to do | 
|  | * any operations before the kernel would switch tasks or processes nested | 
|  | * interrupts. This is required for cpu low power states that would require | 
|  | * interrupts to be enabled while entering low power states. e.g. C1 in x86. In | 
|  | * those cases, the ISR would be invoked immediately after the event wakes up | 
|  | * the CPU, before code following the CPU wait, gets a chance to execute. This | 
|  | * can be ignored if no operation needs to be done at the wake event | 
|  | * notification. Alternatively _sys_pm_idle_exit_notification_disable() can | 
|  | * be called in _sys_suspend to disable this notification. | 
|  | */ | 
|  | void _sys_resume(void); | 
|  |  | 
|  | /** | 
|  | * @brief Allow entry to power state | 
|  | * | 
|  | * When the kernel is about to go idle, it calls this function to notify the | 
|  | * power management subsystem, that the kernel is ready to enter the idle state. | 
|  | * | 
|  | * At this point, the kernel has disabled interrupts and computed the maximum | 
|  | * time the system can remain idle. The function passes the time that the system | 
|  | * can remain idle. The SOC interface performs power operations that can be done | 
|  | * in the available time. The power management operations must halt execution of | 
|  | * the CPU. | 
|  | * | 
|  | * This function assumes that a wake up event has already been set up by the | 
|  | * application. | 
|  | * | 
|  | * This function is entered with interrupts disabled. It should re-enable | 
|  | * interrupts if it had entered a power state. | 
|  | * | 
|  | * @param ticks The upcoming kernel idle time. | 
|  | * | 
|  | * @return Power state which was entered or SYS_POWER_STATE_ACTIVE if SoC was | 
|  | *         kept in the active state. | 
|  | */ | 
|  | enum power_states _sys_suspend(s32_t ticks); | 
|  |  | 
|  | /** | 
|  | * @brief 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. | 
|  | */ | 
|  | void _sys_pm_power_state_exit_post_ops(enum power_states state); | 
|  |  | 
|  | /** | 
|  | * @brief Application defined function for power state entry | 
|  | * | 
|  | * Application defined function for doing any target specific operations | 
|  | * for power state entry. | 
|  | */ | 
|  | void sys_pm_notify_power_state_entry(enum power_states state); | 
|  |  | 
|  | /** | 
|  | * @brief Application defined function for sleep state exit | 
|  | * | 
|  | * Application defined function for doing any target specific operations | 
|  | * for sleep state exit. | 
|  | */ | 
|  | void sys_pm_notify_power_state_exit(enum power_states state); | 
|  |  | 
|  | /** | 
|  | * @} | 
|  | */ | 
|  |  | 
|  | #endif /* CONFIG_SYS_POWER_MANAGEMENT */ | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #endif /* ZEPHYR_INCLUDE_POWER_POWER_H_ */ |