Zephyr API Documentation  3.5.0
A Scalable Open Source RTOS
3.5.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 <zephyr/device.h>
11#include <zephyr/kernel.h>
12#include <zephyr/sys/atomic.h>
14
15#ifdef __cplusplus
16extern "C" {
17#endif
18
28struct device;
29
31enum pm_device_flag {
33 PM_DEVICE_FLAG_BUSY,
35 PM_DEVICE_FLAG_TURN_ON_FAILED,
37 PM_DEVICE_FLAG_PD_CLAIMED,
42 PM_DEVICE_FLAG_WS_CAPABLE,
44 PM_DEVICE_FLAG_WS_ENABLED,
46 PM_DEVICE_FLAG_RUNTIME_ENABLED,
48 PM_DEVICE_FLAG_STATE_LOCKED,
50 PM_DEVICE_FLAG_PD,
52 PM_DEVICE_FLAG_RUNTIME_AUTO,
53};
54
77};
78
97};
98
109typedef int (*pm_device_action_cb_t)(const struct device *dev,
110 enum pm_device_action action);
111
120typedef bool (*pm_device_action_failed_cb_t)(const struct device *dev,
121 int err);
122
126struct pm_device {
127#if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
129 const struct device *dev;
131 struct k_sem lock;
138#endif /* CONFIG_PM_DEVICE_RUNTIME */
139#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
141 const struct device *domain;
142#endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
143 /* Device PM status flags. */
149};
150
153#ifdef CONFIG_PM_DEVICE_RUNTIME
154#define Z_PM_DEVICE_RUNTIME_INIT(obj) \
155 .lock = Z_SEM_INITIALIZER(obj.lock, 1, 1), \
156 .event = Z_EVENT_INITIALIZER(obj.event),
157#else
158#define Z_PM_DEVICE_RUNTIME_INIT(obj)
159#endif /* CONFIG_PM_DEVICE_RUNTIME */
160
161#ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
162#define Z_PM_DEVICE_POWER_DOMAIN_INIT(_node_id) \
163 .domain = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(_node_id, \
164 power_domain)),
165#else
166#define Z_PM_DEVICE_POWER_DOMAIN_INIT(obj)
167#endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
168
174#define Z_PM_DEVICE_FLAGS(node_id) \
175 (COND_CODE_1( \
176 DT_NODE_EXISTS(node_id), \
177 ((DT_PROP_OR(node_id, wakeup_source, 0) \
178 << PM_DEVICE_FLAG_WS_CAPABLE) | \
179 (DT_PROP_OR(node_id, zephyr_pm_device_runtime_auto, 0) \
180 << PM_DEVICE_FLAG_RUNTIME_AUTO) | \
181 (DT_NODE_HAS_COMPAT(node_id, power_domain) << \
182 PM_DEVICE_FLAG_PD)), \
183 (0)))
184
195#define Z_PM_DEVICE_INIT(obj, node_id, pm_action_cb) \
196 { \
197 Z_PM_DEVICE_RUNTIME_INIT(obj) \
198 .action_cb = pm_action_cb, \
199 .state = PM_DEVICE_STATE_ACTIVE, \
200 .flags = ATOMIC_INIT(Z_PM_DEVICE_FLAGS(node_id)), \
201 Z_PM_DEVICE_POWER_DOMAIN_INIT(node_id) \
202 }
203
209#define Z_PM_DEVICE_NAME(dev_id) _CONCAT(__pm_device_, dev_id)
210
222#define Z_PM_DEVICE_DEFINE_SLOT(dev_id) \
223 static const STRUCT_SECTION_ITERABLE_ALTERNATE(pm_device_slots, device, \
224 _CONCAT(__pm_slot_, dev_id))
225
226#ifdef CONFIG_PM_DEVICE
234#define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb) \
235 Z_PM_DEVICE_DEFINE_SLOT(dev_id); \
236 static struct pm_device Z_PM_DEVICE_NAME(dev_id) = \
237 Z_PM_DEVICE_INIT(Z_PM_DEVICE_NAME(dev_id), node_id, \
238 pm_action_cb)
239
245#define Z_PM_DEVICE_GET(dev_id) (&Z_PM_DEVICE_NAME(dev_id))
246
247#else
248#define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb)
249#define Z_PM_DEVICE_GET(dev_id) NULL
250#endif /* CONFIG_PM_DEVICE */
251
264#define PM_DEVICE_DEFINE(dev_id, pm_action_cb) \
265 Z_PM_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, pm_action_cb)
266
277#define PM_DEVICE_DT_DEFINE(node_id, pm_action_cb) \
278 Z_PM_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
279 pm_action_cb)
280
291#define PM_DEVICE_DT_INST_DEFINE(idx, pm_action_cb) \
292 Z_PM_DEVICE_DEFINE(DT_DRV_INST(idx), \
293 Z_DEVICE_DT_DEV_ID(DT_DRV_INST(idx)), \
294 pm_action_cb)
295
304#define PM_DEVICE_GET(dev_id) \
305 Z_PM_DEVICE_GET(dev_id)
306
315#define PM_DEVICE_DT_GET(node_id) \
316 PM_DEVICE_GET(Z_DEVICE_DT_DEV_ID(node_id))
317
326#define PM_DEVICE_DT_INST_GET(idx) \
327 PM_DEVICE_DT_GET(DT_DRV_INST(idx))
328
335
353int pm_device_action_run(const struct device *dev,
354 enum pm_device_action action);
355
367 enum pm_device_action action,
369
370#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
380int pm_device_state_get(const struct device *dev,
381 enum pm_device_state *state);
382
394static inline void pm_device_init_suspended(const struct device *dev)
395{
396 struct pm_device *pm = dev->pm;
397
399}
400
414static inline void pm_device_init_off(const struct device *dev)
415{
416 struct pm_device *pm = dev->pm;
417
419}
420
432void pm_device_busy_set(const struct device *dev);
433
441void pm_device_busy_clear(const struct device *dev);
442
450
459bool pm_device_is_busy(const struct device *dev);
460
474bool pm_device_wakeup_enable(const struct device *dev, bool enable);
475
485
495
510void pm_device_state_lock(const struct device *dev);
511
522
532
542
557 const struct device *domain);
558
572 const struct device *domain);
573
583bool pm_device_is_powered(const struct device *dev);
584
599
600#else
601static inline int pm_device_state_get(const struct device *dev,
603{
604 ARG_UNUSED(dev);
605
607
608 return 0;
609}
610
611static inline void pm_device_init_suspended(const struct device *dev)
612{
613 ARG_UNUSED(dev);
614}
615static inline void pm_device_init_off(const struct device *dev)
616{
617 ARG_UNUSED(dev);
618}
619static inline void pm_device_busy_set(const struct device *dev)
620{
621 ARG_UNUSED(dev);
622}
623static inline void pm_device_busy_clear(const struct device *dev)
624{
625 ARG_UNUSED(dev);
626}
627static inline bool pm_device_is_any_busy(void) { return false; }
628static inline bool pm_device_is_busy(const struct device *dev)
629{
630 ARG_UNUSED(dev);
631 return false;
632}
633static inline bool pm_device_wakeup_enable(const struct device *dev,
634 bool enable)
635{
636 ARG_UNUSED(dev);
637 ARG_UNUSED(enable);
638 return false;
639}
640static inline bool pm_device_wakeup_is_enabled(const struct device *dev)
641{
642 ARG_UNUSED(dev);
643 return false;
644}
645static inline bool pm_device_wakeup_is_capable(const struct device *dev)
646{
647 ARG_UNUSED(dev);
648 return false;
649}
650static inline void pm_device_state_lock(const struct device *dev)
651{
652 ARG_UNUSED(dev);
653}
654static inline void pm_device_state_unlock(const struct device *dev)
655{
656 ARG_UNUSED(dev);
657}
658static inline bool pm_device_state_is_locked(const struct device *dev)
659{
660 ARG_UNUSED(dev);
661 return false;
662}
663static inline bool pm_device_on_power_domain(const struct device *dev)
664{
665 ARG_UNUSED(dev);
666 return false;
667}
668
669static inline int pm_device_power_domain_add(const struct device *dev,
670 const struct device *domain)
671{
672 ARG_UNUSED(dev);
673 ARG_UNUSED(domain);
674 return -ENOSYS;
675}
676
677static inline int pm_device_power_domain_remove(const struct device *dev,
678 const struct device *domain)
679{
680 ARG_UNUSED(dev);
681 ARG_UNUSED(domain);
682 return -ENOSYS;
683}
684
685static inline bool pm_device_is_powered(const struct device *dev)
686{
687 ARG_UNUSED(dev);
688 return true;
689}
690
691static inline int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb)
692{
693 int rc;
694
695 /* When power management is not enabled, all drivers should initialise to active state */
697 if (rc == 0) {
699 }
700 return rc;
701}
702
703#endif /* CONFIG_PM_DEVICE */
704
707#ifdef __cplusplus
708}
709#endif
710
711#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:394
pm_device_state
Device power states.
Definition: device.h:58
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:109
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:120
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.
int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb)
Setup a device driver into the lowest valid power mode.
bool pm_device_is_any_busy(void)
Check if any device is busy.
pm_device_action
Device PM actions.
Definition: device.h:80
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:414
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
Device is suspended.
Definition: device.h:67
@ PM_DEVICE_STATE_OFF
Device is turned off (power removed).
Definition: device.h:76
@ PM_DEVICE_STATE_SUSPENDING
Device is being suspended.
Definition: device.h:69
@ PM_DEVICE_STATE_ACTIVE
Device is in active or regular state.
Definition: device.h:60
@ PM_DEVICE_ACTION_TURN_OFF
Turn off.
Definition: device.h:90
@ PM_DEVICE_ACTION_SUSPEND
Suspend.
Definition: device.h:82
@ PM_DEVICE_ACTION_RESUME
Resume.
Definition: device.h:84
@ PM_DEVICE_ACTION_TURN_ON
Turn on.
Definition: device.h:96
#define ENOSYS
Function not implemented.
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:381
struct pm_device * pm
Reference to the device PM resources (only available if <code>CONFIG_PM_DEVICE</code> <verbatim>em...
Definition: device.h:408
Event Structure.
Definition: kernel.h:2218
A structure used to submit work after a delay.
Definition: kernel.h:3893
Device PM info.
Definition: device.h:126
uint32_t usage
Device usage count.
Definition: device.h:135
enum pm_device_state state
Device power state.
Definition: device.h:146
pm_device_action_cb_t action_cb
Device PM action callback.
Definition: device.h:148
struct k_work_delayable work
Work object for asynchronous calls.
Definition: device.h:137
atomic_t flags
Definition: device.h:144
struct k_event event
Event var to listen to the sync request events.
Definition: device.h:133
struct k_sem lock
Lock to synchronize the get/put operations.
Definition: device.h:131
const struct device * dev
Pointer to the device.
Definition: device.h:129