LCOV - code coverage report
Current view: top level - zephyr/pm - state.h Coverage Total Hit
Test: new.info Lines: 90.0 % 20 18
Test Date: 2025-09-25 19:22:35

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2020 Intel corporation
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_PM_STATE_H_
       8              : #define ZEPHYR_INCLUDE_PM_STATE_H_
       9              : 
      10              : #include <zephyr/sys/util.h>
      11              : #include <zephyr/devicetree.h>
      12              : #include <errno.h>
      13              : 
      14              : #ifdef __cplusplus
      15              : extern "C" {
      16              : #endif
      17              : 
      18              : /**
      19              :  * @brief System Power Management States
      20              :  * @defgroup subsys_pm_states States
      21              :  * @ingroup subsys_pm
      22              :  * @{
      23              :  */
      24              : 
      25              : /**
      26              :  * @enum pm_state Power management state
      27              :  */
      28            1 : enum pm_state {
      29              :         /**
      30              :          * @brief Runtime active state
      31              :          *
      32              :          * The system is fully powered and active.
      33              :          *
      34              :          * @note This state is correlated with ACPI G0/S0 state
      35              :          */
      36              :         PM_STATE_ACTIVE,
      37              :         /**
      38              :          * @brief Runtime idle state
      39              :          *
      40              :          * Runtime idle is a system sleep state in which all of the cores
      41              :          * enter deepest possible idle state and wait for interrupts, no
      42              :          * requirements for the devices, leaving them at the states where
      43              :          * they are.
      44              :          *
      45              :          * @note This state is correlated with ACPI S0ix state
      46              :          */
      47              :         PM_STATE_RUNTIME_IDLE,
      48              :         /**
      49              :          * @brief Suspend to idle state
      50              :          *
      51              :          * The system goes through a normal platform suspend where it puts
      52              :          * all of the cores in deepest possible idle state and *may* puts
      53              :          * peripherals into low-power states. No operating state is lost (ie.
      54              :          * the cpu core does not lose execution context), so the system can go
      55              :          * back to where it left off easily enough.
      56              :          *
      57              :          * @note This state is correlated with ACPI S1 state
      58              :          */
      59              :         PM_STATE_SUSPEND_TO_IDLE,
      60              :         /**
      61              :          * @brief Standby state
      62              :          *
      63              :          * In addition to putting peripherals into low-power states all
      64              :          * non-boot CPUs are powered off. It should allow more energy to be
      65              :          * saved relative to suspend to idle, but the resume latency will
      66              :          * generally be greater than for that state. But it should be the same
      67              :          * state with suspend to idle state on uniprocessor system.
      68              :          *
      69              :          * @note This state is correlated with ACPI S2 state
      70              :          */
      71              :         PM_STATE_STANDBY,
      72              :         /**
      73              :          * @brief Suspend to ram state
      74              :          *
      75              :          * This state offers significant energy savings by powering off as much
      76              :          * of the system as possible, where memory should be placed into the
      77              :          * self-refresh mode to retain its contents. The state of devices and
      78              :          * CPUs is saved and held in memory, and it may require some boot-
      79              :          * strapping code in ROM to resume the system from it.
      80              :          *
      81              :          * @note This state is correlated with ACPI S3 state
      82              :          */
      83              :         PM_STATE_SUSPEND_TO_RAM,
      84              :         /**
      85              :          * @brief Suspend to disk state
      86              :          *
      87              :          * This state offers significant energy savings by powering off as much
      88              :          * of the system as possible, including the memory. The contents of
      89              :          * memory are written to disk or other non-volatile storage, and on
      90              :          * resume it's read back into memory with the help of boot-strapping
      91              :          * code, restores the system to the same point of execution where it
      92              :          * went to suspend to disk.
      93              :          *
      94              :          * @note This state is correlated with ACPI S4 state
      95              :          */
      96              :         PM_STATE_SUSPEND_TO_DISK,
      97              :         /**
      98              :          * @brief Soft off state
      99              :          *
     100              :          * This state consumes a minimal amount of power and requires a large
     101              :          * latency in order to return to runtime active state. The contents of
     102              :          * system(CPU and memory) will not be preserved, so the system will be
     103              :          * restarted as if from initial power-up and kernel boot.
     104              :          *
     105              :          * @note This state is correlated with ACPI G2/S5 state
     106              :          */
     107              :         PM_STATE_SOFT_OFF,
     108              :         /** Number of power management states (internal use) */
     109              :         PM_STATE_COUNT,
     110              : };
     111              : 
     112              : /**
     113              :  * Information about a power management state
     114              :  */
     115            1 : struct pm_state_info {
     116            0 :         enum pm_state state;
     117              : 
     118              :         /**
     119              :          * Some platforms have multiple states that map to
     120              :          * one Zephyr power state. This property allows the platform
     121              :          * distinguish them. e.g:
     122              :          *
     123              :          * @code{.dts}
     124              :          *      power-states {
     125              :          *              state0: state0 {
     126              :          *                      compatible = "zephyr,power-state";
     127              :          *                      power-state-name = "suspend-to-idle";
     128              :          *                      substate-id = <1>;
     129              :          *                      min-residency-us = <10000>;
     130              :          *                      exit-latency-us = <100>;
     131              :          *              };
     132              :          *              state1: state1 {
     133              :          *                      compatible = "zephyr,power-state";
     134              :          *                      power-state-name = "suspend-to-idle";
     135              :          *                      substate-id = <2>;
     136              :          *                      min-residency-us = <20000>;
     137              :          *                      exit-latency-us = <200>;
     138              :          *                      zephyr,pm-device-disabled;
     139              :          *              };
     140              :          *      };
     141              :          * @endcode
     142              :          */
     143            1 :         uint8_t substate_id;
     144              : 
     145              :         /**
     146              :          * Whether or not this state triggers device power management.
     147              :          *
     148              :          * When this property is false the power management subsystem
     149              :          * will suspend devices before entering this state and will
     150              :          * properly resume them when leaving it.
     151              :          */
     152            1 :         bool pm_device_disabled;
     153              : 
     154              :         /**
     155              :          * Minimum residency duration in microseconds. It is the minimum
     156              :          * time for a given idle state to be worthwhile energywise.
     157              :          *
     158              :          * @note 0 means that this property is not available for this state.
     159              :          */
     160            1 :         uint32_t min_residency_us;
     161              : 
     162              :         /**
     163              :          * Worst case latency in microseconds required to exit the idle state.
     164              :          *
     165              :          * @note 0 means that this property is not available for this state.
     166              :          */
     167            1 :         uint32_t exit_latency_us;
     168              : };
     169              : 
     170              : /**
     171              :  * Power state information needed to lock a power state.
     172              :  */
     173            1 : struct pm_state_constraint {
     174              :          /**
     175              :           * Power management state
     176              :           *
     177              :           * @see pm_state
     178              :           **/
     179            1 :         enum pm_state state;
     180              :          /**
     181              :           * Power management sub-state
     182              :           *
     183              :           * @see pm_state
     184              :           **/
     185            1 :         uint8_t substate_id;
     186              : };
     187              : 
     188              : /** @cond INTERNAL_HIDDEN */
     189              : 
     190              : /**
     191              :  * @brief Helper macro that expands to 1 if a phandle node is enabled, 0 otherwise.
     192              :  *
     193              :  * @param node_id Node identifier.
     194              :  * @param prop Property holding phandle-array.
     195              :  * @param idx Index within the array.
     196              :  */
     197              : #define Z_DT_PHANDLE_01(node_id, prop, idx) \
     198              :         COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE_BY_IDX(node_id, prop, idx)), \
     199              :                     (1), (0))
     200              : 
     201              : /**
     202              :  * @brief Helper macro to initialize an entry of a struct pm_state_info array
     203              :  * when using UTIL_LISTIFY in PM_STATE_INFO_LIST_FROM_DT_CPU.
     204              :  *
     205              :  * @note Only enabled states are initialized.
     206              :  *
     207              :  * @param i UTIL_LISTIFY entry index.
     208              :  * @param node_id A node identifier with compatible zephyr,power-state
     209              :  */
     210              : #define Z_PM_STATE_INFO_FROM_DT_CPU(i, node_id)                                                   \
     211              :         COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),     \
     212              :                     (PM_STATE_INFO_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),), ())
     213              : 
     214              : /**
     215              :  * @brief Helper macro to initialize an entry of a struct pm_state array when
     216              :  * using UTIL_LISTIFY in PM_STATE_LIST_FROM_DT_CPU.
     217              :  *
     218              :  * @note Only enabled states are initialized.
     219              :  *
     220              :  * @param i UTIL_LISTIFY entry index.
     221              :  * @param node_id A node identifier with compatible zephyr,power-state
     222              :  */
     223              : #define Z_PM_STATE_FROM_DT_CPU(i, node_id)                                                        \
     224              :         COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),     \
     225              :                     (PM_STATE_DT_INIT(DT_PHANDLE_BY_IDX(node_id, cpu_power_states, i)),), ())
     226              : 
     227              : /** @endcond */
     228              : 
     229              : /**
     230              :  * @brief Initializer for struct pm_state_info given a DT node identifier with
     231              :  * zephyr,power-state compatible.
     232              :  *
     233              :  * @param node_id A node identifier with compatible zephyr,power-state
     234              :  */
     235            1 : #define PM_STATE_INFO_DT_INIT(node_id)                                         \
     236              :         {                                                                      \
     237              :                 .state = PM_STATE_DT_INIT(node_id),                            \
     238              :                 .substate_id = DT_PROP_OR(node_id, substate_id, 0),            \
     239              :                 .min_residency_us = DT_PROP_OR(node_id, min_residency_us, 0),  \
     240              :                 .exit_latency_us = DT_PROP_OR(node_id, exit_latency_us, 0),    \
     241              :                 .pm_device_disabled = DT_PROP(node_id, zephyr_pm_device_disabled),    \
     242              :         }
     243              : 
     244              : /**
     245              :  * @brief Initializer for enum pm_state given a DT node identifier with
     246              :  * zephyr,power-state compatible.
     247              :  *
     248              :  * @param node_id A node identifier with compatible zephyr,power-state
     249              :  */
     250            1 : #define PM_STATE_DT_INIT(node_id) \
     251              :         DT_ENUM_IDX(node_id, power_state_name)
     252              : 
     253              : /**
     254              :  * @brief Obtain number of CPU power states supported and enabled by the given
     255              :  * CPU node identifier.
     256              :  *
     257              :  * @param node_id A CPU node identifier.
     258              :  * @return Number of supported and enabled CPU power states.
     259              :  */
     260            1 : #define DT_NUM_CPU_POWER_STATES(node_id)                                                           \
     261              :         COND_CODE_1(DT_NODE_HAS_PROP(node_id, cpu_power_states),                                   \
     262              :                     (DT_FOREACH_PROP_ELEM_SEP(node_id, cpu_power_states, Z_DT_PHANDLE_01, (+))),   \
     263              :                     (0))
     264              : 
     265              : /**
     266              :  * @brief Initialize an array of struct pm_state_info with information from all
     267              :  * the states present and enabled in the given CPU node identifier.
     268              :  *
     269              :  * Example devicetree fragment:
     270              :  *
     271              :  * @code{.dts}
     272              :  *      cpus {
     273              :  *              ...
     274              :  *              cpu0: cpu@0 {
     275              :  *                      device_type = "cpu";
     276              :  *                      ...
     277              :  *                      cpu-power-states = <&state0 &state1>;
     278              :  *              };
     279              :  *
     280              :  *              power-states {
     281              :  *                      state0: state0 {
     282              :  *                              compatible = "zephyr,power-state";
     283              :  *                              power-state-name = "suspend-to-idle";
     284              :  *                              min-residency-us = <10000>;
     285              :  *                              exit-latency-us = <100>;
     286              :  *                      };
     287              :  *
     288              :  *                      state1: state1 {
     289              :  *                              compatible = "zephyr,power-state";
     290              :  *                              power-state-name = "suspend-to-ram";
     291              :  *                              min-residency-us = <50000>;
     292              :  *                              exit-latency-us = <500>;
     293              :  *                              zephyr,pm-device-disabled;
     294              :  *                      };
     295              :  *              };
     296              :  *      };
     297              : 
     298              :  * @endcode
     299              :  *
     300              :  * Example usage:
     301              :  *
     302              :  * @code{.c}
     303              :  * const struct pm_state_info states[] =
     304              :  *      PM_STATE_INFO_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
     305              :  * @endcode
     306              :  *
     307              :  * @param node_id A CPU node identifier.
     308              :  */
     309            1 : #define PM_STATE_INFO_LIST_FROM_DT_CPU(node_id)                                \
     310              :         {                                                                      \
     311              :                 LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0),          \
     312              :                         Z_PM_STATE_INFO_FROM_DT_CPU, (), node_id)              \
     313              :         }
     314              : 
     315              : /**
     316              :  * @brief Initialize an array of struct pm_state with information from all the
     317              :  * states present and enabled in the given CPU node identifier.
     318              :  *
     319              :  * Example devicetree fragment:
     320              :  *
     321              :  * @code{.dts}
     322              :  *      cpus {
     323              :  *              ...
     324              :  *              cpu0: cpu@0 {
     325              :  *                      device_type = "cpu";
     326              :  *                      ...
     327              :  *                      cpu-power-states = <&state0 &state1>;
     328              :  *              };
     329              :  *
     330              :  *              power-states {
     331              :  *                      state0: state0 {
     332              :  *                              compatible = "zephyr,power-state";
     333              :  *                              power-state-name = "suspend-to-idle";
     334              :  *                              min-residency-us = <10000>;
     335              :  *                              exit-latency-us = <100>;
     336              :  *                      };
     337              :  *
     338              :  *                      state1: state1 {
     339              :  *                              compatible = "zephyr,power-state";
     340              :  *                              power-state-name = "suspend-to-ram";
     341              :  *                              min-residency-us = <50000>;
     342              :  *                              exit-latency-us = <500>;
     343              :  *                      };
     344              :  *              };
     345              :  *      };
     346              :  * @endcode
     347              :  *
     348              :  * Example usage:
     349              :  *
     350              :  * @code{.c}
     351              :  * const enum pm_state states[] = PM_STATE_LIST_FROM_DT_CPU(DT_NODELABEL(cpu0));
     352              :  * @endcode
     353              :  *
     354              :  * @param node_id A CPU node identifier.
     355              :  */
     356            1 : #define PM_STATE_LIST_FROM_DT_CPU(node_id)                                     \
     357              :         {                                                                      \
     358              :                 LISTIFY(DT_PROP_LEN_OR(node_id, cpu_power_states, 0),          \
     359              :                         Z_PM_STATE_FROM_DT_CPU, (), node_id)                   \
     360              :         }
     361              : 
     362              : 
     363              : #if defined(CONFIG_PM) || defined(__DOXYGEN__)
     364              : /**
     365              :  * Obtain information about all supported states by a CPU.
     366              :  *
     367              :  * @param cpu CPU index.
     368              :  * @param states Where to store the list of supported states.
     369              :  *
     370              :  * @return Number of supported states.
     371              :  */
     372            1 : uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states);
     373              : 
     374              : /**
     375              :  * Get power state structure.
     376              :  *
     377              :  * Function searches in all states assigned to the CPU and in disabled states.
     378              :  *
     379              :  * @param cpu CPU index.
     380              :  * @param state Power state.
     381              :  * @param substate_id Substate.
     382              :  *
     383              :  * @return Pointer to the power state structure or NULL if state is not found.
     384              :  */
     385            1 : const struct pm_state_info *pm_state_get(uint8_t cpu, enum pm_state state, uint8_t substate_id);
     386              : 
     387              : /**
     388              :  * @brief Convert a pm_state enum value to its string representation.
     389              :  *
     390              :  * @param state Power state.
     391              :  *
     392              :  * @return A constant string representing the state.
     393              :  */
     394            1 : const char *pm_state_to_str(enum pm_state state);
     395              : 
     396              : 
     397              : /**
     398              :  * @brief Parse a string and convert it to a pm_state enum value.
     399              :  *
     400              :  * @param name Input string (e.g., "suspend-to-ram").
     401              :  * @param out Pointer to store the parsed pm_state value.
     402              :  *
     403              :  * @return 0 on success, -EINVAL if the string is invalid or NULL.
     404              :  */
     405            1 : int pm_state_from_str(const char *name, enum pm_state *out);
     406              : /**
     407              :  * @}
     408              :  */
     409              : 
     410              : #else  /* CONFIG_PM */
     411              : 
     412              : static inline uint8_t pm_state_cpu_get_all(uint8_t cpu, const struct pm_state_info **states)
     413              : {
     414              :         ARG_UNUSED(cpu);
     415              :         ARG_UNUSED(states);
     416              : 
     417              :         return 0;
     418              : }
     419              : 
     420              : static inline const struct pm_state_info *pm_state_get(uint8_t cpu,
     421              :                                                        enum pm_state state,
     422              :                                                        uint8_t substate_id)
     423              : {
     424              :         ARG_UNUSED(cpu);
     425              :         ARG_UNUSED(state);
     426              :         ARG_UNUSED(substate_id);
     427              : 
     428              :         return NULL;
     429              : }
     430              : 
     431              : #endif /* CONFIG_PM */
     432              : 
     433              : #ifdef __cplusplus
     434              : }
     435              : #endif
     436              : 
     437              : #endif
        

Generated by: LCOV version 2.0-1