LCOV - code coverage report
Current view: top level - zephyr/pm - device.h Hit Total Coverage
Test: new.info Lines: 43 44 97.7 %
Date: 2024-12-21 18:13:37

          Line data    Source code
       1           0 : /*
       2             :  * Copyright (c) 2015 Intel Corporation.
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : #ifndef ZEPHYR_INCLUDE_PM_DEVICE_H_
       8             : #define ZEPHYR_INCLUDE_PM_DEVICE_H_
       9             : 
      10             : #include <zephyr/device.h>
      11             : #include <zephyr/kernel.h>
      12             : #include <zephyr/sys/atomic.h>
      13             : #include <zephyr/sys/iterable_sections.h>
      14             : 
      15             : #ifdef __cplusplus
      16             : extern "C" {
      17             : #endif
      18             : 
      19             : /**
      20             :  * @brief Device Power Management API
      21             :  * @defgroup subsys_pm_device Device
      22             :  * @ingroup subsys_pm
      23             :  * @{
      24             :  */
      25             : 
      26             : /** @cond INTERNAL_HIDDEN */
      27             : 
      28             : struct device;
      29             : 
      30             : /** @brief Device PM flags. */
      31             : enum pm_device_flag {
      32             :         /** Indicate if the device is busy or not. */
      33             :         PM_DEVICE_FLAG_BUSY,
      34             :         /** Indicate if the device failed to power up. */
      35             :         PM_DEVICE_FLAG_TURN_ON_FAILED,
      36             :         /** Indicate if the device has claimed a power domain */
      37             :         PM_DEVICE_FLAG_PD_CLAIMED,
      38             :         /**
      39             :          * Indicates whether or not the device is capable of waking the system
      40             :          * up.
      41             :          */
      42             :         PM_DEVICE_FLAG_WS_CAPABLE,
      43             :         /** Indicates if the device is being used as wakeup source. */
      44             :         PM_DEVICE_FLAG_WS_ENABLED,
      45             :         /** Indicates if device runtime is enabled  */
      46             :         PM_DEVICE_FLAG_RUNTIME_ENABLED,
      47             :         /** Indicates if the device is used as a power domain */
      48             :         PM_DEVICE_FLAG_PD,
      49             :         /** Indicates if device runtime PM should be automatically enabled */
      50             :         PM_DEVICE_FLAG_RUNTIME_AUTO,
      51             :         /** Indicates that device runtime PM supports suspending and resuming from any context. */
      52             :         PM_DEVICE_FLAG_ISR_SAFE,
      53             : };
      54             : 
      55             : /** @endcond */
      56             : 
      57             : /** @brief Flag indicating that runtime PM API for the device can be called from any context.
      58             :  *
      59             :  * If @ref PM_DEVICE_ISR_SAFE flag is used for device definition, it indicates that PM actions
      60             :  * are synchronous and can be executed from any context. This approach can be used for cases where
      61             :  * suspending and resuming is short as it is executed in the critical section. This mode requires
      62             :  * less resources (~80 byte less RAM) and allows to use device runtime PM from any context
      63             :  * (including interrupts).
      64             :  */
      65           1 : #define PM_DEVICE_ISR_SAFE 1
      66             : 
      67             : /** @brief Device power states. */
      68           1 : enum pm_device_state {
      69             :         /** Device is in active or regular state. */
      70             :         PM_DEVICE_STATE_ACTIVE,
      71             :         /**
      72             :          * Device is suspended.
      73             :          *
      74             :          * @note
      75             :          *     Device context may be lost.
      76             :          */
      77             :         PM_DEVICE_STATE_SUSPENDED,
      78             :         /** Device is being suspended. */
      79             :         PM_DEVICE_STATE_SUSPENDING,
      80             :         /**
      81             :          * Device is turned off (power removed).
      82             :          *
      83             :          * @note
      84             :          *     Device context is lost.
      85             :          */
      86             :         PM_DEVICE_STATE_OFF
      87             : };
      88             : 
      89             : /** @brief Device PM actions. */
      90           1 : enum pm_device_action {
      91             :         /** Suspend. */
      92             :         PM_DEVICE_ACTION_SUSPEND,
      93             :         /** Resume. */
      94             :         PM_DEVICE_ACTION_RESUME,
      95             :         /**
      96             :          * Turn off.
      97             :          * @note
      98             :          *     Action triggered only by a power domain.
      99             :          */
     100             :         PM_DEVICE_ACTION_TURN_OFF,
     101             :         /**
     102             :          * Turn on.
     103             :          * @note
     104             :          *     Action triggered only by a power domain.
     105             :          */
     106             :         PM_DEVICE_ACTION_TURN_ON,
     107             : };
     108             : 
     109             : /**
     110             :  * @brief Device PM action callback.
     111             :  *
     112             :  * @param dev Device instance.
     113             :  * @param action Requested action.
     114             :  *
     115             :  * @retval 0 If successful.
     116             :  * @retval -ENOTSUP If the requested action is not supported.
     117             :  * @retval Errno Other negative errno on failure.
     118             :  */
     119           1 : typedef int (*pm_device_action_cb_t)(const struct device *dev,
     120             :                                      enum pm_device_action action);
     121             : 
     122             : /**
     123             :  * @brief Device PM action failed callback
     124             :  *
     125             :  * @param dev Device that failed the action.
     126             :  * @param err Return code of action failure.
     127             :  *
     128             :  * @return True to continue iteration, false to halt iteration.
     129             :  */
     130           1 : typedef bool (*pm_device_action_failed_cb_t)(const struct device *dev,
     131             :                                          int err);
     132             : 
     133             : /**
     134             :  * @brief Device PM info
     135             :  *
     136             :  * Structure holds fields which are common for two PM devices: generic and
     137             :  * synchronous.
     138             :  */
     139           1 : struct pm_device_base {
     140             :         /** Device PM status flags. */
     141           1 :         atomic_t flags;
     142             :         /** Device power state */
     143           1 :         enum pm_device_state state;
     144             :         /** Device PM action callback */
     145           1 :         pm_device_action_cb_t action_cb;
     146             : #if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
     147             :         /** Device usage count */
     148           1 :         uint32_t usage;
     149             : #endif /* CONFIG_PM_DEVICE_RUNTIME */
     150             : #ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
     151             :         /** Power Domain it belongs */
     152             :         const struct device *domain;
     153             : #endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
     154             : };
     155             : 
     156             : /**
     157             :  * @brief Runtime PM info for device with generic PM.
     158             :  *
     159             :  * Generic PM involves suspending and resuming operations which can be blocking,
     160             :  * long lasting or asynchronous. Runtime PM API is limited when used from
     161             :  * interrupt context.
     162             :  */
     163           1 : struct pm_device {
     164             :         /** Base info. */
     165           1 :         struct pm_device_base base;
     166             : #if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
     167             :         /** Pointer to the device */
     168           1 :         const struct device *dev;
     169             :         /** Lock to synchronize the get/put operations */
     170           1 :         struct k_sem lock;
     171             :         /** Event var to listen to the sync request events */
     172           1 :         struct k_event event;
     173             :         /** Work object for asynchronous calls */
     174           1 :         struct k_work_delayable work;
     175             : #endif /* CONFIG_PM_DEVICE_RUNTIME */
     176             : };
     177             : 
     178             : /**
     179             :  * @brief Runtime PM info for device with synchronous PM.
     180             :  *
     181             :  * Synchronous PM can be used with devices which suspend and resume operations can
     182             :  * be performed in the critical section as they are short and non-blocking.
     183             :  * Runtime PM API can be used from any context in that case.
     184             :  */
     185           1 : struct pm_device_isr {
     186             :         /** Base info. */
     187           1 :         struct pm_device_base base;
     188             : #if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
     189             :         /** Lock to synchronize the synchronous get/put operations */
     190           1 :         struct k_spinlock lock;
     191             : #endif
     192             : };
     193             : 
     194             : /* Base part must be the first element. */
     195             : BUILD_ASSERT(offsetof(struct pm_device, base) == 0);
     196             : BUILD_ASSERT(offsetof(struct pm_device_isr, base) == 0);
     197             : 
     198             : /** @cond INTERNAL_HIDDEN */
     199             : 
     200             : #ifdef CONFIG_PM_DEVICE_RUNTIME
     201             : #define Z_PM_DEVICE_RUNTIME_INIT(obj)                   \
     202             :         .lock = Z_SEM_INITIALIZER(obj.lock, 1, 1),      \
     203             :         .event = Z_EVENT_INITIALIZER(obj.event),
     204             : #else
     205             : #define Z_PM_DEVICE_RUNTIME_INIT(obj)
     206             : #endif /* CONFIG_PM_DEVICE_RUNTIME */
     207             : 
     208             : #ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
     209             : #define Z_PM_DEVICE_POWER_DOMAIN_INIT(_node_id)                 \
     210             :         .domain = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(_node_id,    \
     211             :                                    power_domains)),
     212             : #else
     213             : #define Z_PM_DEVICE_POWER_DOMAIN_INIT(obj)
     214             : #endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
     215             : 
     216             : /**
     217             :  * @brief Utility macro to initialize #pm_device_base flags
     218             :  *
     219             :  * @param node_id Devicetree node for the initialized device (can be invalid).
     220             :  */
     221             : #define Z_PM_DEVICE_FLAGS(node_id)                                       \
     222             :         (COND_CODE_1(                                                    \
     223             :                  DT_NODE_EXISTS(node_id),                                \
     224             :                  ((DT_PROP_OR(node_id, wakeup_source, 0)                 \
     225             :                          << PM_DEVICE_FLAG_WS_CAPABLE) |           \
     226             :                   (DT_PROP_OR(node_id, zephyr_pm_device_runtime_auto, 0) \
     227             :                          << PM_DEVICE_FLAG_RUNTIME_AUTO) |                 \
     228             :                   (DT_NODE_HAS_COMPAT(node_id, power_domain) <<            \
     229             :                          PM_DEVICE_FLAG_PD)),                            \
     230             :                  (0)))
     231             : 
     232             : /**
     233             :  * @brief Utility macro to initialize #pm_device.
     234             :  *
     235             :  * @note #DT_PROP_OR is used to retrieve the wakeup_source property because
     236             :  * it may not be defined on all devices.
     237             :  *
     238             :  * @param obj Name of the #pm_device_base structure being initialized.
     239             :  * @param node_id Devicetree node for the initialized device (can be invalid).
     240             :  * @param pm_action_cb Device PM control callback function.
     241             :  * @param _flags Additional flags passed to the structure.
     242             :  */
     243             : #define Z_PM_DEVICE_BASE_INIT(obj, node_id, pm_action_cb, _flags)            \
     244             :         {                                                                    \
     245             :                 .flags = ATOMIC_INIT(Z_PM_DEVICE_FLAGS(node_id) | (_flags)), \
     246             :                 .state = PM_DEVICE_STATE_ACTIVE,                             \
     247             :                 .action_cb = pm_action_cb,                                   \
     248             :                 Z_PM_DEVICE_POWER_DOMAIN_INIT(node_id)                       \
     249             :         }
     250             : 
     251             : /**
     252             :  * @brief Utility macro to initialize #pm_device_rt.
     253             :  *
     254             :  * @note #DT_PROP_OR is used to retrieve the wakeup_source property because
     255             :  * it may not be defined on all devices.
     256             :  *
     257             :  * @param obj Name of the #pm_device_base structure being initialized.
     258             :  * @param node_id Devicetree node for the initialized device (can be invalid).
     259             :  * @param pm_action_cb Device PM control callback function.
     260             :  */
     261             : #define Z_PM_DEVICE_INIT(obj, node_id, pm_action_cb, isr_safe)                  \
     262             :         {                                                                       \
     263             :                 .base = Z_PM_DEVICE_BASE_INIT(obj, node_id, pm_action_cb,       \
     264             :                                 isr_safe ? BIT(PM_DEVICE_FLAG_ISR_SAFE) : 0),   \
     265             :                 COND_CODE_1(isr_safe, (), (Z_PM_DEVICE_RUNTIME_INIT(obj)))      \
     266             :         }
     267             : 
     268             : /**
     269             :  * Get the name of device PM resources.
     270             :  *
     271             :  * @param dev_id Device id.
     272             :  */
     273             : #define Z_PM_DEVICE_NAME(dev_id) _CONCAT(__pm_device_, dev_id)
     274             : 
     275             : #ifdef CONFIG_PM
     276             : /**
     277             :  * @brief Define device PM slot.
     278             :  *
     279             :  * This macro defines a pointer to a device in the pm_device_slots region.
     280             :  * When invoked for each device with PM, it will effectively result in a device
     281             :  * pointer array with the same size of the actual devices with PM enabled. This
     282             :  * is used internally by the PM subsystem to keep track of suspended devices
     283             :  * during system power transitions.
     284             :  *
     285             :  * @param dev_id Device id.
     286             :  */
     287             : #define Z_PM_DEVICE_DEFINE_SLOT(dev_id)                                 \
     288             :         static STRUCT_SECTION_ITERABLE_ALTERNATE(pm_device_slots, device, \
     289             :                         _CONCAT(__pm_slot_, dev_id))
     290             : #else
     291             : #define Z_PM_DEVICE_DEFINE_SLOT(dev_id)
     292             : #endif /* CONFIG_PM */
     293             : 
     294             : #ifdef CONFIG_PM_DEVICE
     295             : /**
     296             :  * Define device PM resources for the given node identifier.
     297             :  *
     298             :  * @param node_id Node identifier (DT_INVALID_NODE if not a DT device).
     299             :  * @param dev_id Device id.
     300             :  * @param pm_action_cb PM control callback.
     301             :  */
     302             : #define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb, isr_safe)             \
     303             :         Z_PM_DEVICE_DEFINE_SLOT(dev_id);                                        \
     304             :         static struct COND_CODE_1(isr_safe, (pm_device_isr), (pm_device))       \
     305             :                 Z_PM_DEVICE_NAME(dev_id) =                                      \
     306             :                 Z_PM_DEVICE_INIT(Z_PM_DEVICE_NAME(dev_id), node_id,             \
     307             :                                  pm_action_cb, isr_safe)
     308             : 
     309             : /**
     310             :  * Get a reference to the device PM resources.
     311             :  *
     312             :  * @param dev_id Device id.
     313             :  */
     314             : #define Z_PM_DEVICE_GET(dev_id) ((struct pm_device_base *)&Z_PM_DEVICE_NAME(dev_id))
     315             : 
     316             : #else
     317             : #define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb, isr_safe)
     318             : #define Z_PM_DEVICE_GET(dev_id) NULL
     319             : #endif /* CONFIG_PM_DEVICE */
     320             : 
     321             : /** @endcond */
     322             : 
     323             : /**
     324             :  * Define device PM resources for the given device name.
     325             :  *
     326             :  * @note This macro is a no-op if @kconfig{CONFIG_PM_DEVICE} is not enabled.
     327             :  *
     328             :  * @param dev_id Device id.
     329             :  * @param pm_action_cb PM control callback.
     330             :  * @param ... Optional flag to indicate that ISR safe. Use @ref PM_DEVICE_ISR_SAFE or 0.
     331             :  *
     332             :  * @see #PM_DEVICE_DT_DEFINE, #PM_DEVICE_DT_INST_DEFINE
     333             :  */
     334           1 : #define PM_DEVICE_DEFINE(dev_id, pm_action_cb, ...)                     \
     335             :         Z_PM_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, pm_action_cb,       \
     336             :                         COND_CODE_1(IS_EMPTY(__VA_ARGS__), (0), (__VA_ARGS__)))
     337             : 
     338             : /**
     339             :  * Define device PM resources for the given node identifier.
     340             :  *
     341             :  * @note This macro is a no-op if @kconfig{CONFIG_PM_DEVICE} is not enabled.
     342             :  *
     343             :  * @param node_id Node identifier.
     344             :  * @param pm_action_cb PM control callback.
     345             :  * @param ... Optional flag to indicate that device is isr_ok. Use @ref PM_DEVICE_ISR_SAFE or 0.
     346             :  *
     347             :  * @see #PM_DEVICE_DT_INST_DEFINE, #PM_DEVICE_DEFINE
     348             :  */
     349           1 : #define PM_DEVICE_DT_DEFINE(node_id, pm_action_cb, ...) \
     350             :         Z_PM_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), pm_action_cb, \
     351             :                         COND_CODE_1(IS_EMPTY(__VA_ARGS__), (0), (__VA_ARGS__)))
     352             : 
     353             : /**
     354             :  * Define device PM resources for the given instance.
     355             :  *
     356             :  * @note This macro is a no-op if @kconfig{CONFIG_PM_DEVICE} is not enabled.
     357             :  *
     358             :  * @param idx Instance index.
     359             :  * @param pm_action_cb PM control callback.
     360             :  * @param ... Optional flag to indicate that device is isr_ok. Use @ref PM_DEVICE_ISR_SAFE or 0.
     361             :  *
     362             :  * @see #PM_DEVICE_DT_DEFINE, #PM_DEVICE_DEFINE
     363             :  */
     364           1 : #define PM_DEVICE_DT_INST_DEFINE(idx, pm_action_cb, ...)                \
     365             :         Z_PM_DEVICE_DEFINE(DT_DRV_INST(idx),                            \
     366             :                            Z_DEVICE_DT_DEV_ID(DT_DRV_INST(idx)),        \
     367             :                            pm_action_cb,                                \
     368             :                            COND_CODE_1(IS_EMPTY(__VA_ARGS__), (0), (__VA_ARGS__)))
     369             : 
     370             : /**
     371             :  * @brief Obtain a reference to the device PM resources for the given device.
     372             :  *
     373             :  * @param dev_id Device id.
     374             :  *
     375             :  * @return Reference to the device PM resources (NULL if device
     376             :  * @kconfig{CONFIG_PM_DEVICE} is disabled).
     377             :  */
     378           1 : #define PM_DEVICE_GET(dev_id) \
     379             :         Z_PM_DEVICE_GET(dev_id)
     380             : 
     381             : /**
     382             :  * @brief Obtain a reference to the device PM resources for the given node.
     383             :  *
     384             :  * @param node_id Node identifier.
     385             :  *
     386             :  * @return Reference to the device PM resources (NULL if device
     387             :  * @kconfig{CONFIG_PM_DEVICE} is disabled).
     388             :  */
     389           1 : #define PM_DEVICE_DT_GET(node_id) \
     390             :         PM_DEVICE_GET(Z_DEVICE_DT_DEV_ID(node_id))
     391             : 
     392             : /**
     393             :  * @brief Obtain a reference to the device PM resources for the given instance.
     394             :  *
     395             :  * @param idx Instance index.
     396             :  *
     397             :  * @return Reference to the device PM resources (NULL if device
     398             :  * @kconfig{CONFIG_PM_DEVICE} is disabled).
     399             :  */
     400           1 : #define PM_DEVICE_DT_INST_GET(idx) \
     401             :         PM_DEVICE_DT_GET(DT_DRV_INST(idx))
     402             : 
     403             : /**
     404             :  * @brief Get name of device PM state
     405             :  *
     406             :  * @param state State id which name should be returned
     407             :  */
     408           1 : const char *pm_device_state_str(enum pm_device_state state);
     409             : 
     410             : /**
     411             :  * @brief Run a pm action on a device.
     412             :  *
     413             :  * This function calls the device PM control callback so that the device does
     414             :  * the necessary operations to execute the given action.
     415             :  *
     416             :  * @param dev Device instance.
     417             :  * @param action Device pm action.
     418             :  *
     419             :  * @retval 0 If successful.
     420             :  * @retval -ENOTSUP If requested state is not supported.
     421             :  * @retval -EALREADY If device is already at the requested state.
     422             :  * @retval -EBUSY If device is changing its state.
     423             :  * @retval -ENOSYS If device does not support PM.
     424             :  * @retval -EPERM If device has power state locked.
     425             :  * @retval Errno Other negative errno on failure.
     426             :  */
     427           1 : int pm_device_action_run(const struct device *dev,
     428             :                 enum pm_device_action action);
     429             : 
     430             : /**
     431             :  * @brief Run a pm action on all children of a device.
     432             :  *
     433             :  * This function calls all child devices PM control callback so that the device
     434             :  * does the necessary operations to execute the given action.
     435             :  *
     436             :  * @param dev Device instance.
     437             :  * @param action Device pm action.
     438             :  * @param failure_cb Function to call if a child fails the action, can be NULL.
     439             :  */
     440           1 : void pm_device_children_action_run(const struct device *dev,
     441             :                 enum pm_device_action action,
     442             :                 pm_device_action_failed_cb_t failure_cb);
     443             : 
     444             : #if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
     445             : /**
     446             :  * @brief Obtain the power state of a device.
     447             :  *
     448             :  * @param dev Device instance.
     449             :  * @param state Pointer where device power state will be stored.
     450             :  *
     451             :  * @retval 0 If successful.
     452             :  * @retval -ENOSYS If device does not implement power management.
     453             :  */
     454           1 : int pm_device_state_get(const struct device *dev,
     455             :                         enum pm_device_state *state);
     456             : 
     457             : /**
     458             :  * @brief Initialize a device state to #PM_DEVICE_STATE_SUSPENDED.
     459             :  *
     460             :  * By default device state is initialized to #PM_DEVICE_STATE_ACTIVE. However
     461             :  * in order to save power some drivers may choose to only initialize the device
     462             :  * to the suspended state, or actively put the device into the suspended state.
     463             :  * This function can therefore be used to notify the PM subsystem that the
     464             :  * device is in #PM_DEVICE_STATE_SUSPENDED instead of the default.
     465             :  *
     466             :  * @param dev Device instance.
     467             :  */
     468           1 : static inline void pm_device_init_suspended(const struct device *dev)
     469             : {
     470             :         struct pm_device_base *pm = dev->pm_base;
     471             : 
     472             :         pm->state = PM_DEVICE_STATE_SUSPENDED;
     473             : }
     474             : 
     475             : /**
     476             :  * @brief Initialize a device state to #PM_DEVICE_STATE_OFF.
     477             :  *
     478             :  * By default device state is initialized to #PM_DEVICE_STATE_ACTIVE. In
     479             :  * general, this makes sense because the device initialization function will
     480             :  * resume and configure a device, leaving it operational. However, when power
     481             :  * domains are enabled, the device may be connected to a switchable power
     482             :  * source, in which case it won't be powered at boot. This function can
     483             :  * therefore be used to notify the PM subsystem that the device is in
     484             :  * #PM_DEVICE_STATE_OFF instead of the default.
     485             :  *
     486             :  * @param dev Device instance.
     487             :  */
     488           1 : static inline void pm_device_init_off(const struct device *dev)
     489             : {
     490             :         struct pm_device_base *pm = dev->pm_base;
     491             : 
     492             :         pm->state = PM_DEVICE_STATE_OFF;
     493             : }
     494             : 
     495             : /**
     496             :  * @brief Mark a device as busy.
     497             :  *
     498             :  * Devices marked as busy will not be suspended when the system goes into
     499             :  * low-power states. This can be useful if, for example, the device is in the
     500             :  * middle of a transaction.
     501             :  *
     502             :  * @param dev Device instance.
     503             :  *
     504             :  * @see pm_device_busy_clear()
     505             :  */
     506           1 : void pm_device_busy_set(const struct device *dev);
     507             : 
     508             : /**
     509             :  * @brief Clear a device busy status.
     510             :  *
     511             :  * @param dev Device instance.
     512             :  *
     513             :  * @see pm_device_busy_set()
     514             :  */
     515           1 : void pm_device_busy_clear(const struct device *dev);
     516             : 
     517             : /**
     518             :  * @brief Check if any device is busy.
     519             :  *
     520             :  * @retval false If no device is busy
     521             :  * @retval true If one or more devices are busy
     522             :  */
     523           1 : bool pm_device_is_any_busy(void);
     524             : 
     525             : /**
     526             :  * @brief Check if a device is busy.
     527             :  *
     528             :  * @param dev Device instance.
     529             :  *
     530             :  * @retval false If the device is not busy
     531             :  * @retval true If the device is busy
     532             :  */
     533           1 : bool pm_device_is_busy(const struct device *dev);
     534             : 
     535             : /**
     536             :  * @brief Enable or disable a device as a wake up source.
     537             :  *
     538             :  * A device marked as a wake up source will not be suspended when the system
     539             :  * goes into low-power modes, thus allowing to use it as a wake up source for
     540             :  * the system.
     541             :  *
     542             :  * @param dev Device instance.
     543             :  * @param enable @c true to enable or @c false to disable
     544             :  *
     545             :  * @retval true If the wakeup source was successfully enabled.
     546             :  * @retval false If the wakeup source was not successfully enabled.
     547             :  */
     548           1 : bool pm_device_wakeup_enable(const struct device *dev, bool enable);
     549             : 
     550             : /**
     551             :  * @brief Check if a device is enabled as a wake up source.
     552             :  *
     553             :  * @param dev Device instance.
     554             :  *
     555             :  * @retval true if the wakeup source is enabled.
     556             :  * @retval false if the wakeup source is not enabled.
     557             :  */
     558           1 : bool pm_device_wakeup_is_enabled(const struct device *dev);
     559             : 
     560             : /**
     561             :  * @brief Check if a device is wake up capable
     562             :  *
     563             :  * @param dev Device instance.
     564             :  *
     565             :  * @retval true If the device is wake up capable.
     566             :  * @retval false If the device is not wake up capable.
     567             :  */
     568           1 : bool pm_device_wakeup_is_capable(const struct device *dev);
     569             : 
     570             : /**
     571             :  * @brief Check if the device is on a switchable power domain.
     572             :  *
     573             :  * @param dev Device instance.
     574             :  *
     575             :  * @retval true If device is on a switchable power domain.
     576             :  * @retval false If device is not on a switchable power domain.
     577             :  */
     578           1 : bool pm_device_on_power_domain(const struct device *dev);
     579             : 
     580             : /**
     581             :  * @brief Add a device to a power domain.
     582             :  *
     583             :  * This function adds a device to a given power domain.
     584             :  *
     585             :  * @param dev Device to be added to the power domain.
     586             :  * @param domain Power domain.
     587             :  *
     588             :  * @retval 0 If successful.
     589             :  * @retval -EALREADY If device is already part of the power domain.
     590             :  * @retval -ENOSYS If the application was built without power domain support.
     591             :  * @retval -ENOSPC If there is no space available in the power domain to add the device.
     592             :  */
     593           1 : int pm_device_power_domain_add(const struct device *dev,
     594             :                                const struct device *domain);
     595             : 
     596             : /**
     597             :  * @brief Remove a device from a power domain.
     598             :  *
     599             :  * This function removes a device from a given power domain.
     600             :  *
     601             :  * @param dev Device to be removed from the power domain.
     602             :  * @param domain Power domain.
     603             :  *
     604             :  * @retval 0 If successful.
     605             :  * @retval -ENOSYS If the application was built without power domain support.
     606             :  * @retval -ENOENT If device is not in the given domain.
     607             :  */
     608           1 : int pm_device_power_domain_remove(const struct device *dev,
     609             :                                   const struct device *domain);
     610             : 
     611             : /**
     612             :  * @brief Check if the device is currently powered.
     613             :  *
     614             :  * @param dev Device instance.
     615             :  *
     616             :  * @retval true If device is currently powered, or is assumed to be powered
     617             :  * (i.e. it does not support PM or is not under a PM domain)
     618             :  * @retval false If device is not currently powered
     619             :  */
     620           1 : bool pm_device_is_powered(const struct device *dev);
     621             : 
     622             : /**
     623             :  * @brief Setup a device driver into the lowest valid power mode
     624             :  *
     625             :  * This helper function is intended to be called at the end of a driver
     626             :  * init function to automatically setup the device into the lowest power
     627             :  * mode. It assumes that the device has been configured as if it is in
     628             :  * @ref PM_DEVICE_STATE_OFF, or @ref PM_DEVICE_STATE_SUSPENDED if device can
     629             :  * never be powered off.
     630             :  *
     631             :  * @param dev Device instance.
     632             :  * @param action_cb Device PM control callback function.
     633             :  * @retval 0 On success.
     634             :  * @retval -errno Error code from @a action_cb on failure.
     635             :  */
     636           1 : int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb);
     637             : 
     638             : #else
     639             : static inline int pm_device_state_get(const struct device *dev,
     640             :                                       enum pm_device_state *state)
     641             : {
     642             :         ARG_UNUSED(dev);
     643             : 
     644             :         *state = PM_DEVICE_STATE_ACTIVE;
     645             : 
     646             :         return 0;
     647             : }
     648             : 
     649             : static inline void pm_device_init_suspended(const struct device *dev)
     650             : {
     651             :         ARG_UNUSED(dev);
     652             : }
     653             : static inline void pm_device_init_off(const struct device *dev)
     654             : {
     655             :         ARG_UNUSED(dev);
     656             : }
     657             : static inline void pm_device_busy_set(const struct device *dev)
     658             : {
     659             :         ARG_UNUSED(dev);
     660             : }
     661             : static inline void pm_device_busy_clear(const struct device *dev)
     662             : {
     663             :         ARG_UNUSED(dev);
     664             : }
     665             : static inline bool pm_device_is_any_busy(void) { return false; }
     666             : static inline bool pm_device_is_busy(const struct device *dev)
     667             : {
     668             :         ARG_UNUSED(dev);
     669             :         return false;
     670             : }
     671             : static inline bool pm_device_wakeup_enable(const struct device *dev,
     672             :                                            bool enable)
     673             : {
     674             :         ARG_UNUSED(dev);
     675             :         ARG_UNUSED(enable);
     676             :         return false;
     677             : }
     678             : static inline bool pm_device_wakeup_is_enabled(const struct device *dev)
     679             : {
     680             :         ARG_UNUSED(dev);
     681             :         return false;
     682             : }
     683             : static inline bool pm_device_wakeup_is_capable(const struct device *dev)
     684             : {
     685             :         ARG_UNUSED(dev);
     686             :         return false;
     687             : }
     688             : static inline bool pm_device_on_power_domain(const struct device *dev)
     689             : {
     690             :         ARG_UNUSED(dev);
     691             :         return false;
     692             : }
     693             : 
     694             : static inline int pm_device_power_domain_add(const struct device *dev,
     695             :                                              const struct device *domain)
     696             : {
     697             :         ARG_UNUSED(dev);
     698             :         ARG_UNUSED(domain);
     699             :         return -ENOSYS;
     700             : }
     701             : 
     702             : static inline int pm_device_power_domain_remove(const struct device *dev,
     703             :                                                 const struct device *domain)
     704             : {
     705             :         ARG_UNUSED(dev);
     706             :         ARG_UNUSED(domain);
     707             :         return -ENOSYS;
     708             : }
     709             : 
     710             : static inline bool pm_device_is_powered(const struct device *dev)
     711             : {
     712             :         ARG_UNUSED(dev);
     713             :         return true;
     714             : }
     715             : 
     716             : static inline int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb)
     717             : {
     718             :         int rc;
     719             : 
     720             :         /* When power management is not enabled, all drivers should initialise to active state */
     721             :         rc = action_cb(dev, PM_DEVICE_ACTION_TURN_ON);
     722             :         if ((rc < 0) && (rc != -ENOTSUP)) {
     723             :                 return rc;
     724             :         }
     725             : 
     726             :         rc = action_cb(dev, PM_DEVICE_ACTION_RESUME);
     727             :         if (rc < 0) {
     728             :                 return rc;
     729             :         }
     730             : 
     731             :         return 0;
     732             : }
     733             : 
     734             : #endif /* CONFIG_PM_DEVICE */
     735             : 
     736             : /** @} */
     737             : 
     738             : #ifdef __cplusplus
     739             : }
     740             : #endif
     741             : 
     742             : #endif

Generated by: LCOV version 1.14