Zephyr Project API  3.3.0
A Scalable Open Source RTOS
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 <zephyr/device.h>
11#include <zephyr/kernel.h>
12#include <zephyr/sys/atomic.h>
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
27struct device;
28
30enum pm_device_flag {
32 PM_DEVICE_FLAG_BUSY,
34 PM_DEVICE_FLAG_TURN_ON_FAILED,
39 PM_DEVICE_FLAG_WS_CAPABLE,
41 PM_DEVICE_FLAG_WS_ENABLED,
43 PM_DEVICE_FLAG_RUNTIME_ENABLED,
45 PM_DEVICE_FLAG_STATE_LOCKED,
47 PM_DEVICE_FLAG_PD,
48};
49
72};
73
92};
93
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_sem lock;
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. */
144};
145
148#ifdef CONFIG_PM_DEVICE_RUNTIME
149#define Z_PM_DEVICE_RUNTIME_INIT(obj) \
150 .lock = Z_SEM_INITIALIZER(obj.lock, 1, 1), \
151 .event = Z_EVENT_INITIALIZER(obj.event),
152#else
153#define Z_PM_DEVICE_RUNTIME_INIT(obj)
154#endif /* CONFIG_PM_DEVICE_RUNTIME */
155
156#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
157#define Z_PM_DEVICE_POWER_DOMAIN_INIT(_node_id) \
158 .domain = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(_node_id, \
159 power_domain)),
160#else
161#define Z_PM_DEVICE_POWER_DOMAIN_INIT(obj)
162#endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
163
174#define Z_PM_DEVICE_INIT(obj, node_id, pm_action_cb) \
175 { \
176 Z_PM_DEVICE_RUNTIME_INIT(obj) \
177 .action_cb = pm_action_cb, \
178 .state = PM_DEVICE_STATE_ACTIVE, \
179 .flags = ATOMIC_INIT(COND_CODE_1( \
180 DT_NODE_EXISTS(node_id), \
181 ((DT_PROP_OR(node_id, wakeup_source, 0) \
182 << PM_DEVICE_FLAG_WS_CAPABLE) | \
183 (DT_NODE_HAS_COMPAT(node_id, power_domain) << \
184 PM_DEVICE_FLAG_PD)), (0))), \
185 Z_PM_DEVICE_POWER_DOMAIN_INIT(node_id) \
186 }
187
193#define Z_PM_DEVICE_NAME(dev_id) _CONCAT(__pm_device_, dev_id)
194
206#define Z_PM_DEVICE_DEFINE_SLOT(dev_id) \
207 static const Z_DECL_ALIGN(struct device *) \
208 _CONCAT(__pm_slot_, dev_id) __used \
209 __attribute__((__section__(".z_pm_device_slots")))
210
211#ifdef CONFIG_PM_DEVICE
219#define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb) \
220 Z_PM_DEVICE_DEFINE_SLOT(dev_id); \
221 static struct pm_device Z_PM_DEVICE_NAME(dev_id) = \
222 Z_PM_DEVICE_INIT(Z_PM_DEVICE_NAME(dev_id), node_id, \
223 pm_action_cb)
224
230#define Z_PM_DEVICE_GET(dev_id) (&Z_PM_DEVICE_NAME(dev_id))
231
232#else
233#define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb)
234#define Z_PM_DEVICE_GET(dev_id) NULL
235#endif /* CONFIG_PM_DEVICE */
236
249#define PM_DEVICE_DEFINE(dev_id, pm_action_cb) \
250 Z_PM_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, pm_action_cb)
251
262#define PM_DEVICE_DT_DEFINE(node_id, pm_action_cb) \
263 Z_PM_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
264 pm_action_cb)
265
276#define PM_DEVICE_DT_INST_DEFINE(idx, pm_action_cb) \
277 Z_PM_DEVICE_DEFINE(DT_DRV_INST(idx), \
278 Z_DEVICE_DT_DEV_ID(DT_DRV_INST(idx)), \
279 pm_action_cb)
280
289#define PM_DEVICE_GET(dev_id) \
290 Z_PM_DEVICE_GET(dev_id)
291
300#define PM_DEVICE_DT_GET(node_id) \
301 PM_DEVICE_GET(Z_DEVICE_DT_DEV_ID(node_id))
302
311#define PM_DEVICE_DT_INST_GET(idx) \
312 PM_DEVICE_DT_GET(DT_DRV_INST(idx))
313
320
338int pm_device_action_run(const struct device *dev,
339 enum pm_device_action action);
340
352 enum pm_device_action action,
354
355#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
365int pm_device_state_get(const struct device *dev,
366 enum pm_device_state *state);
367
379static inline void pm_device_init_suspended(const struct device *dev)
380{
381 struct pm_device *pm = dev->pm;
382
384}
385
399static inline void pm_device_init_off(const struct device *dev)
400{
401 struct pm_device *pm = dev->pm;
402
404}
405
417void pm_device_busy_set(const struct device *dev);
418
426void pm_device_busy_clear(const struct device *dev);
427
435
444bool pm_device_is_busy(const struct device *dev);
445
459bool pm_device_wakeup_enable(const struct device *dev, bool enable);
460
470
480
495void pm_device_state_lock(const struct device *dev);
496
507
517
527
542 const struct device *domain);
543
557 const struct device *domain);
558
567bool pm_device_is_powered(const struct device *dev);
568#else
569static inline int pm_device_state_get(const struct device *dev,
571{
572 ARG_UNUSED(dev);
573
575
576 return 0;
577}
578
579static inline void pm_device_init_suspended(const struct device *dev)
580{
581 ARG_UNUSED(dev);
582}
583static inline void pm_device_init_off(const struct device *dev)
584{
585 ARG_UNUSED(dev);
586}
587static inline void pm_device_busy_set(const struct device *dev)
588{
589 ARG_UNUSED(dev);
590}
591static inline void pm_device_busy_clear(const struct device *dev)
592{
593 ARG_UNUSED(dev);
594}
595static inline bool pm_device_is_any_busy(void) { return false; }
596static inline bool pm_device_is_busy(const struct device *dev)
597{
598 ARG_UNUSED(dev);
599 return false;
600}
601static inline bool pm_device_wakeup_enable(const struct device *dev,
602 bool enable)
603{
604 ARG_UNUSED(dev);
605 ARG_UNUSED(enable);
606 return false;
607}
608static inline bool pm_device_wakeup_is_enabled(const struct device *dev)
609{
610 ARG_UNUSED(dev);
611 return false;
612}
613static inline bool pm_device_wakeup_is_capable(const struct device *dev)
614{
615 ARG_UNUSED(dev);
616 return false;
617}
618static inline void pm_device_state_lock(const struct device *dev)
619{
620 ARG_UNUSED(dev);
621}
622static inline void pm_device_state_unlock(const struct device *dev)
623{
624 ARG_UNUSED(dev);
625}
626static inline bool pm_device_state_is_locked(const struct device *dev)
627{
628 ARG_UNUSED(dev);
629 return false;
630}
631static inline bool pm_device_on_power_domain(const struct device *dev)
632{
633 ARG_UNUSED(dev);
634 return false;
635}
636
637static inline int pm_device_power_domain_add(const struct device *dev,
638 const struct device *domain)
639{
640 return -ENOSYS;
641}
642
643static inline int pm_device_power_domain_remove(const struct device *dev,
644 const struct device *domain)
645{
646 return -ENOSYS;
647}
648
649static inline bool pm_device_is_powered(const struct device *dev)
650{
651 ARG_UNUSED(dev);
652 return true;
653}
654#endif /* CONFIG_PM_DEVICE */
655
658#ifdef __cplusplus
659}
660#endif
661
662#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.
int pm_device_power_domain_remove(const struct device *dev, const struct device *domain)
Remove a device from a power domain.
bool pm_device_on_power_domain(const struct device *dev)
Check if the device is on a switchable power domain.
int pm_device_action_run(const struct device *dev, enum pm_device_action action)
Run a pm action on a device.
static void pm_device_init_suspended(const struct device *dev)
Initialize a device state to PM_DEVICE_STATE_SUSPENDED.
Definition: device.h:379
pm_device_state
Device power states.
Definition: device.h:53
bool pm_device_wakeup_enable(const struct device *dev, bool enable)
Enable or disable a device as a wake up source.
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.
int(* pm_device_action_cb_t)(const struct device *dev, enum pm_device_action action)
Device PM action callback.
Definition: device.h:104
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.
bool(* pm_device_action_failed_cb_t)(const struct device *dev, int err)
Device PM action failed callback.
Definition: device.h:115
bool pm_device_is_powered(const struct device *dev)
Check if the device is currently powered.
int pm_device_power_domain_add(const struct device *dev, const struct device *domain)
Add a device to a power domain.
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.
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.
bool pm_device_is_any_busy(void)
Check if any device is busy.
pm_device_action
Device PM actions.
Definition: device.h:75
bool pm_device_state_is_locked(const struct device *dev)
Check if the device pm is locked.
static void pm_device_init_off(const struct device *dev)
Initialize a device state to PM_DEVICE_STATE_OFF.
Definition: device.h:399
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:62
@ PM_DEVICE_STATE_OFF
Definition: device.h:71
@ PM_DEVICE_STATE_SUSPENDING
Definition: device.h:64
@ PM_DEVICE_STATE_ACTIVE
Definition: device.h:55
@ PM_DEVICE_ACTION_TURN_OFF
Definition: device.h:85
@ PM_DEVICE_ACTION_SUSPEND
Definition: device.h:77
@ PM_DEVICE_ACTION_RESUME
Definition: device.h:79
@ PM_DEVICE_ACTION_TURN_ON
Definition: device.h:91
#define ENOSYS
Definition: errno.h:83
Public kernel APIs.
state
Definition: parser_state.h:29
#define bool
Definition: stdbool.h:13
__UINT32_TYPE__ uint32_t
Definition: stdint.h:90
Runtime device structure (in ROM) per driver instance.
Definition: device.h:378
struct pm_device * pm
Definition: device.h:403
Definition: kernel.h:2111
A structure used to submit work after a delay.
Definition: kernel.h:3735
Device PM info.
Definition: device.h:121
uint32_t usage
Definition: device.h:130
enum pm_device_state state
Definition: device.h:141
pm_device_action_cb_t action_cb
Definition: device.h:143
struct k_work_delayable work
Definition: device.h:132
atomic_t flags
Definition: device.h:139
struct k_event event
Definition: device.h:128
struct k_sem lock
Definition: device.h:126
const struct device * dev
Definition: device.h:124