Zephyr API Documentation  3.0.0
A Scalable Open Source RTOS
3.0.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
device.h
Go to the documentation of this file.
1/*
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 <device.h>
11#include <kernel.h>
12#include <sys/atomic.h>
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
27struct device;
28
30enum pm_device_flag {
32 PM_DEVICE_FLAG_BUSY,
37 PM_DEVICE_FLAG_WS_CAPABLE,
39 PM_DEVICE_FLAG_WS_ENABLED,
41 PM_DEVICE_FLAG_RUNTIME_ENABLED,
43 PM_DEVICE_FLAG_STATE_LOCKED,
44};
45
68};
69
90};
91
104typedef int (*pm_device_action_cb_t)(const struct device *dev,
105 enum pm_device_action action);
106
115typedef bool (*pm_device_action_failed_cb_t)(const struct device *dev,
116 int err);
117
121struct pm_device {
122#if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
124 const struct device *dev;
126 struct k_mutex lock;
128 uint32_t usage;
130 struct k_work_delayable work;
132 struct k_condvar condvar;
133#endif /* CONFIG_PM_DEVICE_RUNTIME */
134#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
136 const struct device *domain;
137#endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
138 /* Device PM status flags. */
143 pm_device_action_cb_t action_cb;
144};
145
146#ifdef CONFIG_PM_DEVICE_RUNTIME
147#define Z_PM_DEVICE_RUNTIME_INIT(obj) \
148 .lock = Z_MUTEX_INITIALIZER(obj.lock), \
149 .condvar = Z_CONDVAR_INITIALIZER(obj.condvar),
150#else
151#define Z_PM_DEVICE_RUNTIME_INIT(obj)
152#endif /* CONFIG_PM_DEVICE_RUNTIME */
153
154#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
155#define Z_PM_DEVICE_POWER_DOMAIN_INIT(_node_id) \
156 .domain = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(_node_id, \
157 power_domain)),
158#else
159#define Z_PM_DEVICE_POWER_DOMAIN_INIT(obj)
160#endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
161
172#define Z_PM_DEVICE_INIT(obj, node_id, pm_action_cb) \
173 { \
174 Z_PM_DEVICE_RUNTIME_INIT(obj) \
175 .action_cb = pm_action_cb, \
176 .state = PM_DEVICE_STATE_ACTIVE, \
177 .flags = ATOMIC_INIT(COND_CODE_1( \
178 DT_NODE_EXISTS(node_id), \
179 (DT_PROP_OR(node_id, wakeup_source, 0)),\
180 (0)) << PM_DEVICE_FLAG_WS_CAPABLE), \
181 Z_PM_DEVICE_POWER_DOMAIN_INIT(node_id) \
182 }
183
189#define Z_PM_DEVICE_NAME(dev_name) _CONCAT(__pm_device__, dev_name)
190
202#define Z_PM_DEVICE_DEFINE_SLOT(dev_name) \
203 static const Z_DECL_ALIGN(struct device *) \
204 _CONCAT(Z_PM_DEVICE_NAME(dev_name), slot) __used \
205 __attribute__((__section__(".z_pm_device_slots")))
206
207#ifdef CONFIG_PM_DEVICE
215#define Z_PM_DEVICE_DEFINE(node_id, dev_name, pm_action_cb) \
216 Z_PM_DEVICE_DEFINE_SLOT(dev_name); \
217 static struct pm_device Z_PM_DEVICE_NAME(dev_name) = \
218 Z_PM_DEVICE_INIT(Z_PM_DEVICE_NAME(dev_name), node_id, \
219 pm_action_cb)
220
226#define Z_PM_DEVICE_GET(dev_name) (&Z_PM_DEVICE_NAME(dev_name))
227
228#else
229#define Z_PM_DEVICE_DEFINE(node_id, dev_name, pm_action_cb)
230#define Z_PM_DEVICE_GET(dev_name) NULL
231#endif /* CONFIG_PM_DEVICE */
232
245#define PM_DEVICE_DEFINE(dev_name, pm_action_cb) \
246 Z_PM_DEVICE_DEFINE(DT_INVALID_NODE, dev_name, pm_action_cb)
247
258#define PM_DEVICE_DT_DEFINE(node_id, pm_action_cb) \
259 Z_PM_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
260 pm_action_cb)
261
272#define PM_DEVICE_DT_INST_DEFINE(idx, pm_action_cb) \
273 Z_PM_DEVICE_DEFINE(DT_DRV_INST(idx), \
274 Z_DEVICE_DT_DEV_NAME(DT_DRV_INST(idx)), \
275 pm_action_cb)
276
285#define PM_DEVICE_GET(dev_name) \
286 Z_PM_DEVICE_GET(dev_name)
287
296#define PM_DEVICE_DT_GET(node_id) \
297 PM_DEVICE_GET(Z_DEVICE_DT_DEV_NAME(node_id))
298
307#define PM_DEVICE_DT_INST_GET(idx) \
308 PM_DEVICE_DT_GET(DT_DRV_INST(idx))
309
316
338__deprecated int pm_device_state_set(const struct device *dev,
340
350int pm_device_state_get(const struct device *dev,
351 enum pm_device_state *state);
352
370int pm_device_action_run(const struct device *dev,
371 enum pm_device_action action);
372
384 enum pm_device_action action,
385 pm_device_action_failed_cb_t failure_cb);
386
387#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
399void pm_device_busy_set(const struct device *dev);
400
408void pm_device_busy_clear(const struct device *dev);
409
417
426bool pm_device_is_busy(const struct device *dev);
427
441bool pm_device_wakeup_enable(struct device *dev, bool enable);
442
451bool pm_device_wakeup_is_enabled(const struct device *dev);
452
461bool pm_device_wakeup_is_capable(const struct device *dev);
462
477void pm_device_state_lock(const struct device *dev);
478
488void pm_device_state_unlock(const struct device *dev);
489
498bool pm_device_state_is_locked(const struct device *dev);
499
508bool pm_device_on_power_domain(const struct device *dev);
509
510#else
511static inline void pm_device_busy_set(const struct device *dev)
512{
513 ARG_UNUSED(dev);
514}
515static inline void pm_device_busy_clear(const struct device *dev)
516{
517 ARG_UNUSED(dev);
518}
519static inline bool pm_device_is_any_busy(void) { return false; }
520static inline bool pm_device_is_busy(const struct device *dev)
521{
522 ARG_UNUSED(dev);
523 return false;
524}
525static inline bool pm_device_wakeup_enable(struct device *dev, bool enable)
526{
527 ARG_UNUSED(dev);
528 ARG_UNUSED(enable);
529 return false;
530}
531static inline bool pm_device_wakeup_is_enabled(const struct device *dev)
532{
533 ARG_UNUSED(dev);
534 return false;
535}
536static inline bool pm_device_wakeup_is_capable(const struct device *dev)
537{
538 ARG_UNUSED(dev);
539 return false;
540}
541static inline void pm_device_state_lock(const struct device *dev)
542{
543 ARG_UNUSED(dev);
544}
545static inline void pm_device_state_unlock(const struct device *dev)
546{
547 ARG_UNUSED(dev);
548}
549static inline bool pm_device_state_is_locked(const struct device *dev)
550{
551 ARG_UNUSED(dev);
552 return false;
553}
554static inline bool pm_device_on_power_domain(const struct device *dev)
555{
556 ARG_UNUSED(dev);
557 return false;
558}
559#endif /* CONFIG_PM_DEVICE */
560
568__deprecated static inline void device_busy_set(const struct device *dev)
569{
571}
572
580__deprecated static inline void device_busy_clear(const struct device *dev)
581{
583}
584
593__deprecated static inline int device_any_busy_check(void)
594{
595 return pm_device_is_any_busy() ? -EBUSY : 0;
596}
597
608__deprecated static inline int device_busy_check(const struct device *dev)
609{
610 return pm_device_is_busy(dev) ? -EBUSY : 0;
611}
612
615#ifdef __cplusplus
616}
617#endif
618
619#endif
long atomic_t
Definition: atomic.h:22
bool pm_device_wakeup_is_enabled(const struct device *dev)
Check if a device is enabled as a wake up source.
static int device_busy_check(const struct device *dev)
Check if a device is busy.
Definition: device.h:608
bool pm_device_on_power_domain(const struct device *dev)
Check if the device is on a switchable power domain.
int pm_device_state_set(const struct device *dev, enum pm_device_state state)
Set the power state of a device.
int pm_device_action_run(const struct device *dev, enum pm_device_action action)
Run a pm action on a device.
pm_device_state
Device power states.
Definition: device.h:49
void pm_device_children_action_run(const struct device *dev, enum pm_device_action action, pm_device_action_failed_cb_t failure_cb)
Run a pm action on all children of a device.
void pm_device_busy_set(const struct device *dev)
Mark a device as busy.
bool pm_device_wakeup_enable(struct device *dev, bool enable)
Enable or disable a device as a wake up source.
void pm_device_busy_clear(const struct device *dev)
Clear a device busy status.
bool pm_device_is_busy(const struct device *dev)
Check if a device is busy.
static int device_any_busy_check(void)
Check if any device is busy.
Definition: device.h:593
void pm_device_state_unlock(const struct device *dev)
Unlock the current device state.
void pm_device_state_lock(const struct device *dev)
Lock current device state.
static void device_busy_set(const struct device *dev)
Definition: device.h:568
bool pm_device_wakeup_is_capable(const struct device *dev)
Check if a device is wake up capable.
const char * pm_device_state_str(enum pm_device_state state)
Get name of device PM state.
static void device_busy_clear(const struct device *dev)
Clear busy status of a device.
Definition: device.h:580
bool pm_device_is_any_busy(void)
Check if any device is busy.
pm_device_action
Device PM actions.
Definition: device.h:71
bool pm_device_state_is_locked(const struct device *dev)
Check if the device pm is locked.
int pm_device_state_get(const struct device *dev, enum pm_device_state *state)
Obtain the power state of a device.
@ PM_DEVICE_STATE_SUSPENDED
Definition: device.h:58
@ PM_DEVICE_STATE_OFF
Definition: device.h:67
@ PM_DEVICE_STATE_SUSPENDING
Definition: device.h:60
@ PM_DEVICE_STATE_ACTIVE
Definition: device.h:51
@ PM_DEVICE_ACTION_TURN_OFF
Definition: device.h:81
@ PM_DEVICE_ACTION_SUSPEND
Definition: device.h:73
@ PM_DEVICE_ACTION_FORCE_SUSPEND
Definition: device.h:89
@ PM_DEVICE_ACTION_RESUME
Definition: device.h:75
@ PM_DEVICE_ACTION_TURN_ON
Definition: device.h:87
#define EBUSY
Definition: errno.h:55
flags
Definition: http_parser.h:131
state
Definition: http_parser_state.h:30
static struct k_work work[2]
Definition: main.c:16
static struct k_spinlock lock
Definition: spinlock_error_case.c:12
#define bool
Definition: stdbool.h:13
__UINT32_TYPE__ uint32_t
Definition: stdint.h:60
Runtime device structure (in ROM) per driver instance.
Definition: device.h:450
Definition: kernel.h:2737
Definition: kernel.h:2629
A structure used to submit work after a delay.
Definition: kernel.h:3600