123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /*
- * Copyright (c) 2015 Intel Corporation.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #ifndef ZEPHYR_INCLUDE_PM_DEVICE_H_
- #define ZEPHYR_INCLUDE_PM_DEVICE_H_
- #include <kernel.h>
- #include <sys/atomic.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * @brief Device Power Management API
- *
- * @defgroup device_power_management_api Device Power Management API
- * @ingroup power_management_api
- * @{
- */
- struct device;
- /** @brief Device power states. */
- enum pm_device_state {
- /** Device is in active or regular state. */
- PM_DEVICE_STATE_ACTIVE,
- /**
- * Device is in low power state.
- *
- * @note
- * Device context is preserved.
- */
- PM_DEVICE_STATE_LOW_POWER,
- /**
- * Device is suspended.
- *
- * @note
- * Device context may be lost.
- */
- PM_DEVICE_STATE_SUSPENDED,
- /**
- * Device is turned off (power removed).
- *
- * @note
- * Device context is lost.
- */
- PM_DEVICE_STATE_OFF
- };
- /** @brief Device PM flags. */
- enum pm_device_flag {
- /** Indicate if the device is busy or not. */
- PM_DEVICE_FLAG_BUSY,
- /**
- * Indicates whether or not the device is capable of waking the system
- * up.
- */
- PM_DEVICE_FLAGS_WS_CAPABLE,
- /** Indicates if the device is being used as wakeup source. */
- PM_DEVICE_FLAGS_WS_ENABLED,
- /** Indicates that the device is changing its state */
- PM_DEVICE_FLAG_TRANSITIONING,
- /** Number of flags (internal use only). */
- PM_DEVICE_FLAG_COUNT
- };
- /** @brief Device PM actions. */
- enum pm_device_action {
- /** Suspend. */
- PM_DEVICE_ACTION_SUSPEND,
- /** Resume. */
- PM_DEVICE_ACTION_RESUME,
- /** Turn off. */
- PM_DEVICE_ACTION_TURN_OFF,
- /** Force suspend. */
- PM_DEVICE_ACTION_FORCE_SUSPEND,
- /** Low power. */
- PM_DEVICE_ACTION_LOW_POWER,
- /** EARLY Suspend. */
- PM_DEVICE_ACTION_EARLY_SUSPEND,
- /** EARLY Resume. */
- PM_DEVICE_ACTION_LATE_RESUME,
- };
- /**
- * @brief Device PM info
- */
- struct pm_device {
- /** Pointer to the device */
- const struct device *dev;
- /** Lock to synchronize the get/put operations */
- struct k_mutex lock;
- /* Following are packed fields protected by #lock. */
- /** Device pm enable flag */
- bool enable : 1;
- /* Device PM status flags. */
- atomic_t flags;
- /** Device usage count */
- uint32_t usage;
- /** Device power state */
- enum pm_device_state state;
- /** Work object for asynchronous calls */
- struct k_work_delayable work;
- /** Event conditional var to listen to the sync request events */
- struct k_condvar condvar;
- };
- /**
- * @brief Utility macro to initialize #pm_device.
- *
- * @note DT_PROP_OR is used to retrieve the wakeup_source property because
- * it may not be defined on all devices.
- *
- * @param obj Name of the #pm_device structure being initialized.
- * @param node_id Devicetree node for the initialized device (can be invalid).
- */
- #define Z_PM_DEVICE_INIT(obj, node_id) \
- { \
- .usage = 0U, \
- .lock = Z_MUTEX_INITIALIZER(obj.lock), \
- .condvar = Z_CONDVAR_INITIALIZER(obj.condvar), \
- .state = PM_DEVICE_STATE_ACTIVE, \
- .flags = ATOMIC_INIT(COND_CODE_1( \
- DT_NODE_EXISTS(node_id), \
- (DT_PROP_OR(node_id, wakeup_source, 0)),\
- (0)) << PM_DEVICE_FLAGS_WS_CAPABLE), \
- }
- /**
- * @brief Device power management control function 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 int (*pm_device_control_callback_t)(const struct device *dev,
- enum pm_device_action action);
- /**
- * @brief Get name of device PM state
- *
- * @param state State id which name should be returned
- */
- const char *pm_device_state_str(enum pm_device_state state);
- /**
- * @brief Set the power state of a device.
- *
- * This function calls the device PM control callback so that the device does
- * the necessary operations to put the device into the given state.
- *
- * @note Some devices may not support all device power states.
- *
- * @param dev Device instance.
- * @param state Device power state to be set.
- *
- * @retval 0 If successful.
- * @retval -ENOTSUP If requested state is not supported.
- * @retval -EALREADY If device is already at the requested state.
- * @retval -EBUSY If device is changing its state.
- * @retval Errno Other negative errno on failure.
- */
- int pm_device_state_set(const struct device *dev,
- enum pm_device_state state);
- /**
- * @brief Obtain the power state of a device.
- *
- * @param dev Device instance.
- * @param state Pointer where device power state will be stored.
- *
- * @retval 0 If successful.
- * @retval -ENOSYS If device does not implement power management.
- */
- int pm_device_state_get(const struct device *dev,
- enum pm_device_state *state);
- #ifdef CONFIG_PM_DEVICE
- /**
- * @brief 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.
- *
- * @param dev Pointer to device structure of the driver instance.
- */
- void pm_device_busy_set(const struct device *dev);
- /**
- * @brief Indicate that the device has completed its transaction
- *
- * Called by a device driver to indicate the end of a transaction.
- *
- * @param dev Pointer to device structure of the driver instance.
- */
- void pm_device_busy_clear(const struct device *dev);
- /**
- * @brief 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.
- *
- * @retval false if no device is busy
- * @retval true if any device is busy
- */
- bool pm_device_is_any_busy(void);
- /**
- * @brief 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.
- *
- * @param dev Pointer to device structure of the specific device driver
- * the caller is interested in.
- * @retval false if the device is not busy
- * @retval true if the device is busy
- */
- bool pm_device_is_busy(const struct device *dev);
- #else
- static inline void pm_device_busy_set(const struct device *dev) {}
- static inline void pm_device_busy_clear(const struct device *dev) {}
- static inline bool pm_device_is_any_busy(void) { return false; }
- static inline bool pm_device_is_busy(const struct device *dev) { return false; }
- #endif
- __deprecated static inline void device_busy_set(const struct device *dev)
- {
- pm_device_busy_set(dev);
- }
- __deprecated static inline void device_busy_clear(const struct device *dev)
- {
- pm_device_busy_clear(dev);
- }
- __deprecated static inline int device_any_busy_check(void)
- {
- return pm_device_is_any_busy() ? -EBUSY : 0;
- }
- __deprecated static inline int device_busy_check(const struct device *dev)
- {
- return pm_device_is_busy(dev) ? -EBUSY : 0;
- }
- /** Alias for legacy use of device_pm_control_nop */
- #define device_pm_control_nop __DEPRECATED_MACRO NULL
- /**
- * @brief Enable a power management wakeup source
- *
- * Enable a wakeup source. This will keep the current device active when the
- * system is suspended, allowing it to be used to wake up the system.
- *
- * @param dev device object to enable.
- * @param enable @c true to enable or @c false to disable
- *
- * @retval true if the wakeup source was successfully enabled.
- * @retval false if the wakeup source was not successfully enabled.
- */
- bool pm_device_wakeup_enable(struct device *dev, bool enable);
- /**
- * @brief Check if a power management wakeup source is enabled
- *
- * Checks if a wake up source is enabled.
- *
- * @param dev device object to check.
- *
- * @retval true if the wakeup source is enabled.
- * @retval false if the wakeup source is not enabled.
- */
- bool pm_device_wakeup_is_enabled(const struct device *dev);
- /**
- * @brief Check if a device is wake up capable
- *
- * @param dev device object to check.
- *
- * @retval true if the device is wake up capable.
- * @retval false if the device is not wake up capable.
- */
- bool pm_device_wakeup_is_capable(const struct device *dev);
- /** @} */
- #ifdef __cplusplus
- }
- #endif
- #endif
|