|  | /* | 
|  | * Copyright (c) 2015 Intel Corporation. | 
|  | * | 
|  | * SPDX-License-Identifier: Apache-2.0 | 
|  | */ | 
|  |  | 
|  | #ifndef ZEPHYR_INCLUDE_DEVICE_H_ | 
|  | #define ZEPHYR_INCLUDE_DEVICE_H_ | 
|  |  | 
|  | /** | 
|  | * @brief Device Driver APIs | 
|  | * @defgroup io_interfaces Device Driver APIs | 
|  | * @{ | 
|  | * @} | 
|  | */ | 
|  | /** | 
|  | * @brief Device Model APIs | 
|  | * @defgroup device_model Device Model APIs | 
|  | * @{ | 
|  | */ | 
|  |  | 
|  | #include <init.h> | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | #define Z_DEVICE_MAX_NAME_LEN	48 | 
|  |  | 
|  |  | 
|  | /** | 
|  | * @def SYS_DEVICE_DEFINE | 
|  | * | 
|  | * @brief Run an initialization function at boot at specified priority, | 
|  | * and define device PM control function. | 
|  | * | 
|  | * @details This macro lets you run a function at system boot. | 
|  | * | 
|  | * @param drv_name Name of this system device | 
|  | * @param init_fn Pointer to the boot function to run | 
|  | * @param pm_control_fn Pointer to device_pm_control function. | 
|  | * Can be empty function (device_pm_control_nop) if not implemented. | 
|  | * @param level The initialization level, See Z_INIT_ENTRY_DEFINE for details. | 
|  | * @param prio Priority within the selected initialization level. See | 
|  | * Z_INIT_ENTRY_DEFINE for details. | 
|  | */ | 
|  | #define SYS_DEVICE_DEFINE(drv_name, init_fn, pm_control_fn, level, prio) \ | 
|  | DEVICE_DEFINE(Z_SYS_NAME(init_fn), drv_name, init_fn, pm_control_fn, \ | 
|  | NULL, NULL, level, prio, NULL) | 
|  |  | 
|  | /** | 
|  | * @def DEVICE_INIT | 
|  | * | 
|  | * @brief Create device object and set it up for boot time initialization. | 
|  | * | 
|  | * @details This macro defines a device object that is automatically | 
|  | * configured by the kernel during system initialization. Note that | 
|  | * devices set up with this macro will not be accessible from user mode | 
|  | * since the API is not specified; whenever possible, use DEVICE_AND_API_INIT | 
|  | * instead. | 
|  | * | 
|  | * @param dev_name Device name. This must be less than Z_DEVICE_MAX_NAME_LEN | 
|  | * characters in order to be looked up from user mode with device_get_binding(). | 
|  | * | 
|  | * @param drv_name The name this instance of the driver exposes to | 
|  | * the system. | 
|  | * | 
|  | * @param init_fn Address to the init function of the driver. | 
|  | * | 
|  | * @param data Pointer to the device's private data. | 
|  | * | 
|  | * @param cfg_info The address to the structure containing the | 
|  | * configuration information for this instance of the driver. | 
|  | * | 
|  | * @param level The initialization level, See Z_INIT_ENTRY_DEFINE for details. | 
|  | * | 
|  | * @param prio Priority within the selected initialization level. See | 
|  | * Z_INIT_ENTRY_DEFINE for details. | 
|  | */ | 
|  | #define DEVICE_INIT(dev_name, drv_name, init_fn, data, cfg_info, level, prio) \ | 
|  | DEVICE_AND_API_INIT(dev_name, drv_name, init_fn,		\ | 
|  | data, cfg_info, level, prio, NULL) | 
|  |  | 
|  |  | 
|  | /** | 
|  | * @def DEVICE_AND_API_INIT | 
|  | * | 
|  | * @brief Create device object and set it up for boot time initialization, | 
|  | * with the option to set driver_api. | 
|  | * | 
|  | * @copydetails DEVICE_INIT | 
|  | * @param api Provides an initial pointer to the API function struct | 
|  | * used by the driver. Can be NULL. | 
|  | * @details The driver api is also set here, eliminating the need to do that | 
|  | * during initialization. | 
|  | */ | 
|  | #ifndef CONFIG_DEVICE_POWER_MANAGEMENT | 
|  | #define DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, \ | 
|  | level, prio, api)				\ | 
|  | static Z_DECL_ALIGN(struct device)				\ | 
|  | _CONCAT(__device_, dev_name) __used			\ | 
|  | __attribute__((__section__(".device_" #level STRINGIFY(prio)))) = { \ | 
|  | .name = drv_name,					\ | 
|  | .config_info = (cfg_info),				\ | 
|  | .driver_api = (api),					\ | 
|  | .driver_data = (data),					\ | 
|  | };								\ | 
|  | Z_INIT_ENTRY_DEFINE(_CONCAT(__device_, dev_name), init_fn,	\ | 
|  | (&_CONCAT(__device_, dev_name)), level, prio) | 
|  | #else | 
|  | /* | 
|  | * Use the default device_pm_control for devices that do not call the | 
|  | * DEVICE_DEFINE macro so that caller of hook functions | 
|  | * need not check device_pm_control != NULL. | 
|  | */ | 
|  | #define DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, \ | 
|  | level, prio, api)				 \ | 
|  | DEVICE_DEFINE(dev_name, drv_name, init_fn,			 \ | 
|  | device_pm_control_nop, data, cfg_info, level,	 \ | 
|  | prio, api) | 
|  | #endif | 
|  |  | 
|  | /** | 
|  | * @def DEVICE_DEFINE | 
|  | * | 
|  | * @brief Create device object and set it up for boot time initialization, | 
|  | * with the option to device_pm_control. In case of Device Idle Power | 
|  | * Management is enabled, make sure the device is in suspended state after | 
|  | * initialization. | 
|  | * | 
|  | * @copydetails DEVICE_AND_API_INIT | 
|  | * @param pm_control_fn Pointer to device_pm_control function. | 
|  | * Can be empty function (device_pm_control_nop) if not implemented. | 
|  | */ | 
|  | #ifndef CONFIG_DEVICE_POWER_MANAGEMENT | 
|  | #define DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn,	 \ | 
|  | data, cfg_info, level, prio, api)			 \ | 
|  | DEVICE_AND_API_INIT(dev_name, drv_name, init_fn, data, cfg_info, \ | 
|  | level, prio, api) | 
|  | #else | 
|  | #define DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn,	\ | 
|  | data, cfg_info, level, prio, api)			\ | 
|  | static struct device_pm _CONCAT(__pm_, dev_name) __used  = {	\ | 
|  | .usage = ATOMIC_INIT(0),				\ | 
|  | .lock = Z_SEM_INITIALIZER(				\ | 
|  | _CONCAT(__pm_, dev_name).lock, 1, 1),		\ | 
|  | .signal = K_POLL_SIGNAL_INITIALIZER(			\ | 
|  | _CONCAT(__pm_, dev_name).signal),		\ | 
|  | .event = K_POLL_EVENT_INITIALIZER(			\ | 
|  | K_POLL_TYPE_SIGNAL,				\ | 
|  | K_POLL_MODE_NOTIFY_ONLY,			\ | 
|  | &_CONCAT(__pm_, dev_name).signal),		\ | 
|  | };								\ | 
|  | static Z_DECL_ALIGN(struct device)				\ | 
|  | _CONCAT(__device_, dev_name) __used			\ | 
|  | __attribute__((__section__(".device_" #level STRINGIFY(prio)))) = { \ | 
|  | .name = drv_name,					\ | 
|  | .config_info = (cfg_info),				\ | 
|  | .driver_api = (api),					\ | 
|  | .driver_data = (data),					\ | 
|  | .device_pm_control = (pm_control_fn),			\ | 
|  | .pm  = &_CONCAT(__pm_, dev_name),			\ | 
|  | };								\ | 
|  | Z_INIT_ENTRY_DEFINE(_CONCAT(__device_, dev_name), init_fn,	\ | 
|  | (&_CONCAT(__device_, dev_name)), level, prio) | 
|  |  | 
|  | #endif | 
|  |  | 
|  | /** | 
|  | * @def DEVICE_NAME_GET | 
|  | * | 
|  | * @brief Expands to the full name of a global device object | 
|  | * | 
|  | * @details Return the full name of a device object symbol created by | 
|  | * DEVICE_INIT(), using the dev_name provided to DEVICE_INIT(). | 
|  | * | 
|  | * It is meant to be used for declaring extern symbols pointing on device | 
|  | * objects before using the DEVICE_GET macro to get the device object. | 
|  | * | 
|  | * @param name The same as dev_name provided to DEVICE_INIT() | 
|  | * | 
|  | * @return The expanded name of the device object created by DEVICE_INIT() | 
|  | */ | 
|  | #define DEVICE_NAME_GET(name) (_CONCAT(__device_, name)) | 
|  |  | 
|  | /** | 
|  | * @def DEVICE_GET | 
|  | * | 
|  | * @brief Obtain a pointer to a device object by name | 
|  | * | 
|  | * @details Return the address of a device object created by | 
|  | * DEVICE_INIT(), using the dev_name provided to DEVICE_INIT(). | 
|  | * | 
|  | * @param name The same as dev_name provided to DEVICE_INIT() | 
|  | * | 
|  | * @return A pointer to the device object created by DEVICE_INIT() | 
|  | */ | 
|  | #define DEVICE_GET(name) (&DEVICE_NAME_GET(name)) | 
|  |  | 
|  | /** @def DEVICE_DECLARE | 
|  | * | 
|  | * @brief Declare a static device object | 
|  | * | 
|  | * This macro can be used at the top-level to declare a device, such | 
|  | * that DEVICE_GET() may be used before the full declaration in | 
|  | * DEVICE_INIT(). | 
|  | * | 
|  | * This is often useful when configuring interrupts statically in a | 
|  | * device's init or per-instance config function, as the init function | 
|  | * itself is required by DEVICE_INIT() and use of DEVICE_GET() | 
|  | * inside it creates a circular dependency. | 
|  | * | 
|  | * @param name Device name | 
|  | */ | 
|  | #define DEVICE_DECLARE(name) static struct device DEVICE_NAME_GET(name) | 
|  |  | 
|  | typedef void (*device_pm_cb)(struct device *dev, | 
|  | int status, void *context, void *arg); | 
|  |  | 
|  | /** | 
|  | * @brief Device PM info | 
|  | * | 
|  | * @param dev pointer to device structure | 
|  | * @param lock lock to synchronize the get/put operations | 
|  | * @param enable device pm enable flag | 
|  | * @param usage device usage count | 
|  | * @param fsm_state device idle internal power state | 
|  | * @param event event object to listen to the sync request events | 
|  | * @param signal signal to notify the Async API callers | 
|  | */ | 
|  | struct device_pm { | 
|  | struct device *dev; | 
|  | struct k_sem lock; | 
|  | bool enable; | 
|  | atomic_t usage; | 
|  | atomic_t fsm_state; | 
|  | struct k_work work; | 
|  | struct k_poll_event event; | 
|  | struct k_poll_signal signal; | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Runtime device structure (in memory) per driver instance | 
|  | * | 
|  | * @param name name of the device | 
|  | * @param init init function for the driver | 
|  | * @param config_info address of driver instance config information | 
|  | * @param device_config Build time config information | 
|  | * @param driver_api pointer to structure containing the API functions for | 
|  | * the device type. | 
|  | * @param driver_data driver instance data. For driver use only | 
|  | */ | 
|  | struct device { | 
|  | const char *name; | 
|  | const void *config_info; | 
|  | const void *driver_api; | 
|  | void * const driver_data; | 
|  | #ifdef CONFIG_DEVICE_POWER_MANAGEMENT | 
|  | int (*device_pm_control)(struct device *device, u32_t command, | 
|  | void *context, device_pm_cb cb, void *arg); | 
|  | struct device_pm * const pm; | 
|  | #endif | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Retrieve the device structure for a driver by name | 
|  | * | 
|  | * @details Device objects are created via the DEVICE_INIT() macro and | 
|  | * placed in memory by the linker. If a driver needs to bind to another driver | 
|  | * it can use this function to retrieve the device structure of the lower level | 
|  | * driver by the name the driver exposes to the system. | 
|  | * | 
|  | * @param name device name to search for. | 
|  | * | 
|  | * @return pointer to device structure; NULL if not found or cannot be used. | 
|  | */ | 
|  | __syscall struct device *device_get_binding(const char *name); | 
|  |  | 
|  | /** | 
|  | * @} | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief Device Power Management APIs | 
|  | * @defgroup device_power_management_api Device Power Management APIs | 
|  | * @ingroup power_management_api | 
|  | * @{ | 
|  | */ | 
|  |  | 
|  | #ifdef CONFIG_DEVICE_POWER_MANAGEMENT | 
|  |  | 
|  | /** @def DEVICE_PM_ACTIVE_STATE | 
|  | * | 
|  | * @brief device is in ACTIVE power state | 
|  | * | 
|  | * @details Normal operation of the device. All device context is retained. | 
|  | */ | 
|  | #define DEVICE_PM_ACTIVE_STATE          1 | 
|  |  | 
|  | /** @def DEVICE_PM_LOW_POWER_STATE | 
|  | * | 
|  | * @brief device is in LOW power state | 
|  | * | 
|  | * @details Device context is preserved by the HW and need not be | 
|  | * restored by the driver. | 
|  | */ | 
|  | #define DEVICE_PM_LOW_POWER_STATE       2 | 
|  |  | 
|  | /** @def DEVICE_PM_SUSPEND_STATE | 
|  | * | 
|  | * @brief device is in SUSPEND power state | 
|  | * | 
|  | * @details Most device context is lost by the hardware. | 
|  | * Device drivers must save and restore or reinitialize any context | 
|  | * lost by the hardware | 
|  | */ | 
|  | #define DEVICE_PM_SUSPEND_STATE         3 | 
|  |  | 
|  | /** @def DEVICE_PM_FORCE_SUSPEND_STATE | 
|  | * | 
|  | * @brief device is in force SUSPEND power state | 
|  | * | 
|  | * @details Driver puts the device in suspended state after | 
|  | * completing the ongoing transactions and will not process any | 
|  | * queued work or will not take any new requests for processing. | 
|  | * Most device context is lost by the hardware. Device drivers must | 
|  | * save and restore or reinitialize any context lost by the hardware. | 
|  | */ | 
|  | #define DEVICE_PM_FORCE_SUSPEND_STATE	4 | 
|  |  | 
|  | /** @def DEVICE_PM_OFF_STATE | 
|  | * | 
|  | * @brief device is in OFF power state | 
|  | * | 
|  | * @details - Power has been fully removed from the device. | 
|  | * The device context is lost when this state is entered, so the OS | 
|  | * software will reinitialize the device when powering it back on | 
|  | */ | 
|  | #define DEVICE_PM_OFF_STATE             5 | 
|  |  | 
|  | /* Constants defining support device power commands */ | 
|  | #define DEVICE_PM_SET_POWER_STATE       1 | 
|  | #define DEVICE_PM_GET_POWER_STATE       2 | 
|  |  | 
|  | #endif /* CONFIG_DEVICE_POWER_MANAGEMENT */ | 
|  |  | 
|  | /** | 
|  | * @brief Get name of device PM state | 
|  | * | 
|  | * @param state State id which name should be returned | 
|  | */ | 
|  | const char *device_pm_state_str(u32_t state); | 
|  |  | 
|  | /** | 
|  | * @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 busy_dev Pointer to device structure of the driver instance. | 
|  | */ | 
|  | void device_busy_set(struct device *busy_dev); | 
|  |  | 
|  | /** | 
|  | * @brief Indicate that the device has completed its transaction | 
|  | * | 
|  | * Called by a device driver to indicate the end of a transaction. | 
|  | * | 
|  | * @param busy_dev Pointer to device structure of the driver instance. | 
|  | */ | 
|  | void device_busy_clear(struct device *busy_dev); | 
|  |  | 
|  | #ifdef CONFIG_DEVICE_POWER_MANAGEMENT | 
|  | /* | 
|  | * Device PM functions | 
|  | */ | 
|  |  | 
|  | /** | 
|  | * @brief No-op function to initialize unimplemented hook | 
|  | * | 
|  | * This function should be used to initialize device hook | 
|  | * for which a device has no PM operations. | 
|  | * | 
|  | * @param unused_device Unused | 
|  | * @param unused_ctrl_command Unused | 
|  | * @param unused_context Unused | 
|  | * @param cb Unused | 
|  | * @param unused_arg Unused | 
|  | * | 
|  | * @retval -ENOTSUP for all operations. | 
|  | */ | 
|  | int device_pm_control_nop(struct device *unused_device, | 
|  | u32_t unused_ctrl_command, | 
|  | void *unused_context, | 
|  | device_pm_cb cb, | 
|  | void *unused_arg); | 
|  | /** | 
|  | * @brief Call the set power state function of a device | 
|  | * | 
|  | * Called by the application or power management service to let the device do | 
|  | * required operations when moving to the required power state | 
|  | * Note that devices may support just some of the device power states | 
|  | * @param device Pointer to device structure of the driver instance. | 
|  | * @param device_power_state Device power state to be set | 
|  | * @param cb Callback function to notify device power status | 
|  | * @param arg Caller passed argument to callback function | 
|  | * | 
|  | * @retval 0 If successful in queuing the request or changing the state. | 
|  | * @retval Errno Negative errno code if failure. Callback will not be called. | 
|  | */ | 
|  | static inline int device_set_power_state(struct device *device, | 
|  | u32_t device_power_state, | 
|  | device_pm_cb cb, void *arg) | 
|  | { | 
|  | return device->device_pm_control(device, | 
|  | DEVICE_PM_SET_POWER_STATE, | 
|  | &device_power_state, cb, arg); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief Call the get power state function of a device | 
|  | * | 
|  | * This function lets the caller know the current device | 
|  | * power state at any time. This state will be one of the defined | 
|  | * power states allowed for the devices in that system | 
|  | * | 
|  | * @param device pointer to device structure of the driver instance. | 
|  | * @param device_power_state Device power state to be filled by the device | 
|  | * | 
|  | * @retval 0 If successful. | 
|  | * @retval Errno Negative errno code if failure. | 
|  | */ | 
|  | static inline int device_get_power_state(struct device *device, | 
|  | u32_t *device_power_state) | 
|  | { | 
|  | return device->device_pm_control(device, | 
|  | DEVICE_PM_GET_POWER_STATE, | 
|  | device_power_state, | 
|  | NULL, NULL); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @brief 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. | 
|  | * | 
|  | * @param device_list Pointer to receive the device list array | 
|  | * @param device_count Pointer to receive the device count | 
|  | */ | 
|  | void device_list_get(struct device **device_list, int *device_count); | 
|  |  | 
|  | /** | 
|  | * @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 0 if no device is busy | 
|  | * @retval -EBUSY if any device is busy | 
|  | */ | 
|  | int device_any_busy_check(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 chk_dev Pointer to device structure of the specific device driver | 
|  | * the caller is interested in. | 
|  | * @retval 0 if the device is not busy | 
|  | * @retval -EBUSY if the device is busy | 
|  | */ | 
|  | int device_busy_check(struct device *chk_dev); | 
|  |  | 
|  | #ifdef CONFIG_DEVICE_IDLE_PM | 
|  |  | 
|  | /* Device PM FSM states */ | 
|  | enum device_pm_fsm_state { | 
|  | DEVICE_PM_FSM_STATE_ACTIVE = 1, | 
|  | DEVICE_PM_FSM_STATE_SUSPENDED, | 
|  | DEVICE_PM_FSM_STATE_SUSPENDING, | 
|  | DEVICE_PM_FSM_STATE_RESUMING, | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * @brief Enable device idle PM | 
|  | * | 
|  | * Called by a device driver to enable device idle power management. | 
|  | * The device might be asynchronously suspended if Idle PM is enabled | 
|  | * when the device is not use. | 
|  | * | 
|  | * @param dev Pointer to device structure of the specific device driver | 
|  | * the caller is interested in. | 
|  | */ | 
|  | void device_pm_enable(struct device *dev); | 
|  |  | 
|  | /** | 
|  | * @brief Disable device idle PM | 
|  | * | 
|  | * Called by a device driver to disable device idle power management. | 
|  | * The device might be asynchronously resumed if Idle PM is disabled | 
|  | * | 
|  | * @param dev Pointer to device structure of the specific device driver | 
|  | * the caller is interested in. | 
|  | */ | 
|  | void device_pm_disable(struct device *dev); | 
|  |  | 
|  | /** | 
|  | * @brief Call device resume asynchronously based on usage count | 
|  | * | 
|  | * Called by a device driver to mark the device as being used. | 
|  | * This API will asynchronously bring the device to resume state | 
|  | * if it not already in active state. | 
|  | * | 
|  | * @param dev Pointer to device structure of the specific device driver | 
|  | * the caller is interested in. | 
|  | * @retval 0 If successfully queued the Async request. If queued, | 
|  | * the caller need to wait on the poll event linked to device | 
|  | * pm signal mechanism to know the completion of resume operation. | 
|  | * @retval Errno Negative errno code if failure. | 
|  | */ | 
|  | int device_pm_get(struct device *dev); | 
|  |  | 
|  | /** | 
|  | * @brief Call device resume synchronously based on usage count | 
|  | * | 
|  | * Called by a device driver to mark the device as being used. It | 
|  | * will bring up or resume the device if it is in suspended state | 
|  | * based on the device usage count. This call is blocked until the | 
|  | * device PM state is changed to resume. | 
|  | * | 
|  | * @param dev Pointer to device structure of the specific device driver | 
|  | * the caller is interested in. | 
|  | * @retval 0 If successful. | 
|  | * @retval Errno Negative errno code if failure. | 
|  | */ | 
|  | int device_pm_get_sync(struct device *dev); | 
|  |  | 
|  | /** | 
|  | * @brief Call device suspend asynchronously based on usage count | 
|  | * | 
|  | * Called by a device driver to mark the device as being released. | 
|  | * This API asynchronously put the device to suspend state if | 
|  | * it not already in suspended state. | 
|  | * | 
|  | * @param dev Pointer to device structure of the specific device driver | 
|  | * the caller is interested in. | 
|  | * @retval 0 If successfully queued the Async request. If queued, | 
|  | * the caller need to wait on the poll event linked to device pm | 
|  | * signal mechanism to know the completion of suspend operation. | 
|  | * @retval Errno Negative errno code if failure. | 
|  | */ | 
|  | int device_pm_put(struct device *dev); | 
|  |  | 
|  | /** | 
|  | * @brief Call device suspend synchronously based on usage count | 
|  | * | 
|  | * Called by a device driver to mark the device as being released. It | 
|  | * will put the device to suspended state if is is in active state | 
|  | * based on the device usage count. This call is blocked until the | 
|  | * device PM state is changed to resume. | 
|  | * | 
|  | * @param dev Pointer to device structure of the specific device driver | 
|  | * the caller is interested in. | 
|  | * @retval 0 If successful. | 
|  | * @retval Errno Negative errno code if failure. | 
|  | */ | 
|  | int device_pm_put_sync(struct device *dev); | 
|  | #else | 
|  | static inline void device_pm_enable(struct device *dev) { } | 
|  | static inline void device_pm_disable(struct device *dev) { } | 
|  | static inline int device_pm_get(struct device *dev) { return -ENOTSUP; } | 
|  | static inline int device_pm_get_sync(struct device *dev) { return -ENOTSUP; } | 
|  | static inline int device_pm_put(struct device *dev) { return -ENOTSUP; } | 
|  | static inline int device_pm_put_sync(struct device *dev) { return -ENOTSUP; } | 
|  | #endif | 
|  | #else | 
|  | #define device_pm_control_nop(...) NULL | 
|  | #endif | 
|  |  | 
|  | /** | 
|  | * @} | 
|  | */ | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #include <syscalls/device.h> | 
|  |  | 
|  | #endif /* ZEPHYR_INCLUDE_DEVICE_H_ */ |