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 #include <zephyr/sys/iterable_sections.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @brief Device Power Management API
21  * @defgroup subsys_pm_device Device
22  * @ingroup subsys_pm
23  * @{
24  */
25 
26 /** @cond INTERNAL_HIDDEN */
27 
28 struct device;
29 
30 /** @brief Device PM flags. */
31 enum pm_device_flag {
32 	/** Indicate if the device is busy or not. */
33 	PM_DEVICE_FLAG_BUSY,
34 	/** Indicate if the device failed to power up. */
35 	PM_DEVICE_FLAG_TURN_ON_FAILED,
36 	/** Indicate if the device has claimed a power domain */
37 	PM_DEVICE_FLAG_PD_CLAIMED,
38 	/**
39 	 * Indicates whether or not the device is capable of waking the system
40 	 * up.
41 	 */
42 	PM_DEVICE_FLAG_WS_CAPABLE,
43 	/** Indicates if the device is being used as wakeup source. */
44 	PM_DEVICE_FLAG_WS_ENABLED,
45 	/** Indicates if device runtime is enabled  */
46 	PM_DEVICE_FLAG_RUNTIME_ENABLED,
47 	/** Indicates if the device pm is locked.  */
48 	PM_DEVICE_FLAG_STATE_LOCKED,
49 	/** Indicates if the device is used as a power domain */
50 	PM_DEVICE_FLAG_PD,
51 	/** Indicates if device runtime PM should be automatically enabled */
52 	PM_DEVICE_FLAG_RUNTIME_AUTO,
53 	/** Indicates that device runtime PM supports suspending and resuming from any context. */
54 	PM_DEVICE_FLAG_ISR_SAFE,
55 };
56 
57 /** @endcond */
58 
59 /** @brief Flag indicating that runtime PM API for the device can be called from any context.
60  *
61  * If @ref PM_DEVICE_ISR_SAFE flag is used for device definition, it indicates that PM actions
62  * are synchronous and can be executed from any context. This approach can be used for cases where
63  * suspending and resuming is short as it is executed in the critical section. This mode requires
64  * less resources (~80 byte less RAM) and allows to use device runtime PM from any context
65  * (including interrupts).
66  */
67 #define PM_DEVICE_ISR_SAFE 1
68 
69 /** @brief Device power states. */
70 enum pm_device_state {
71 	/** Device is in active or regular state. */
72 	PM_DEVICE_STATE_ACTIVE,
73 	/**
74 	 * Device is suspended.
75 	 *
76 	 * @note
77 	 *     Device context may be lost.
78 	 */
79 	PM_DEVICE_STATE_SUSPENDED,
80 	/** Device is being suspended. */
81 	PM_DEVICE_STATE_SUSPENDING,
82 	/**
83 	 * Device is turned off (power removed).
84 	 *
85 	 * @note
86 	 *     Device context is lost.
87 	 */
88 	PM_DEVICE_STATE_OFF
89 };
90 
91 /** @brief Device PM actions. */
92 enum pm_device_action {
93 	/** Suspend. */
94 	PM_DEVICE_ACTION_SUSPEND,
95 	/** Resume. */
96 	PM_DEVICE_ACTION_RESUME,
97 	/**
98 	 * Turn off.
99 	 * @note
100 	 *     Action triggered only by a power domain.
101 	 */
102 	PM_DEVICE_ACTION_TURN_OFF,
103 	/**
104 	 * Turn on.
105 	 * @note
106 	 *     Action triggered only by a power domain.
107 	 */
108 	PM_DEVICE_ACTION_TURN_ON,
109 };
110 
111 /**
112  * @brief Device PM action callback.
113  *
114  * @param dev Device instance.
115  * @param action Requested action.
116  *
117  * @retval 0 If successful.
118  * @retval -ENOTSUP If the requested action is not supported.
119  * @retval Errno Other negative errno on failure.
120  */
121 typedef int (*pm_device_action_cb_t)(const struct device *dev,
122 				     enum pm_device_action action);
123 
124 /**
125  * @brief Device PM action failed callback
126  *
127  * @param dev Device that failed the action.
128  * @param err Return code of action failure.
129  *
130  * @return True to continue iteration, false to halt iteration.
131  */
132 typedef bool (*pm_device_action_failed_cb_t)(const struct device *dev,
133 					 int err);
134 
135 /**
136  * @brief Device PM info
137  *
138  * Structure holds fields which are common for two PM devices: generic and
139  * synchronous.
140  */
141 struct pm_device_base {
142 	/** Device PM status flags. */
143 	atomic_t flags;
144 	/** Device power state */
145 	enum pm_device_state state;
146 	/** Device PM action callback */
147 	pm_device_action_cb_t action_cb;
148 #if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
149 	/** Device usage count */
150 	uint32_t usage;
151 #endif /* CONFIG_PM_DEVICE_RUNTIME */
152 #ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
153 	/** Power Domain it belongs */
154 	const struct device *domain;
155 #endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
156 };
157 
158 /**
159  * @brief Runtime PM info for device with generic PM.
160  *
161  * Generic PM involves suspending and resuming operations which can be blocking,
162  * long lasting or asynchronous. Runtime PM API is limited when used from
163  * interrupt context.
164  */
165 struct pm_device {
166 	/** Base info. */
167 	struct pm_device_base base;
168 #if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
169 	/** Pointer to the device */
170 	const struct device *dev;
171 	/** Lock to synchronize the get/put operations */
172 	struct k_sem lock;
173 	/** Event var to listen to the sync request events */
174 	struct k_event event;
175 	/** Work object for asynchronous calls */
176 	struct k_work_delayable work;
177 #endif /* CONFIG_PM_DEVICE_RUNTIME */
178 };
179 
180 /**
181  * @brief Runtime PM info for device with synchronous PM.
182  *
183  * Synchronous PM can be used with devices which suspend and resume operations can
184  * be performed in the critical section as they are short and non-blocking.
185  * Runtime PM API can be used from any context in that case.
186  */
187 struct pm_device_isr {
188 	/** Base info. */
189 	struct pm_device_base base;
190 #if defined(CONFIG_PM_DEVICE_RUNTIME) || defined(__DOXYGEN__)
191 	/** Lock to synchronize the synchronous get/put operations */
192 	struct k_spinlock lock;
193 #endif
194 };
195 
196 /* Base part must be the first element. */
197 BUILD_ASSERT(offsetof(struct pm_device, base) == 0);
198 BUILD_ASSERT(offsetof(struct pm_device_isr, base) == 0);
199 
200 /** @cond INTERNAL_HIDDEN */
201 
202 #ifdef CONFIG_PM_DEVICE_RUNTIME
203 #define Z_PM_DEVICE_RUNTIME_INIT(obj)			\
204 	.lock = Z_SEM_INITIALIZER(obj.lock, 1, 1),	\
205 	.event = Z_EVENT_INITIALIZER(obj.event),
206 #else
207 #define Z_PM_DEVICE_RUNTIME_INIT(obj)
208 #endif /* CONFIG_PM_DEVICE_RUNTIME */
209 
210 #ifdef CONFIG_PM_DEVICE_POWER_DOMAIN
211 #define	Z_PM_DEVICE_POWER_DOMAIN_INIT(_node_id)			\
212 	.domain = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(_node_id,	\
213 				   power_domain)),
214 #else
215 #define Z_PM_DEVICE_POWER_DOMAIN_INIT(obj)
216 #endif /* CONFIG_PM_DEVICE_POWER_DOMAIN */
217 
218 /**
219  * @brief Utility macro to initialize #pm_device_base flags
220  *
221  * @param node_id Devicetree node for the initialized device (can be invalid).
222  */
223 #define Z_PM_DEVICE_FLAGS(node_id)					 \
224 	(COND_CODE_1(							 \
225 		 DT_NODE_EXISTS(node_id),				 \
226 		 ((DT_PROP_OR(node_id, wakeup_source, 0)		 \
227 			 << PM_DEVICE_FLAG_WS_CAPABLE) |		 \
228 		  (DT_PROP_OR(node_id, zephyr_pm_device_runtime_auto, 0) \
229 			 << PM_DEVICE_FLAG_RUNTIME_AUTO) |		 \
230 		  (DT_NODE_HAS_COMPAT(node_id, power_domain) <<		 \
231 			 PM_DEVICE_FLAG_PD)),				 \
232 		 (0)))
233 
234 /**
235  * @brief Utility macro to initialize #pm_device.
236  *
237  * @note #DT_PROP_OR is used to retrieve the wakeup_source property because
238  * it may not be defined on all devices.
239  *
240  * @param obj Name of the #pm_device_base structure being initialized.
241  * @param node_id Devicetree node for the initialized device (can be invalid).
242  * @param pm_action_cb Device PM control callback function.
243  * @param _flags Additional flags passed to the structure.
244  */
245 #define Z_PM_DEVICE_BASE_INIT(obj, node_id, pm_action_cb, _flags)	     \
246 	{								     \
247 		.action_cb = pm_action_cb,				     \
248 		.state = PM_DEVICE_STATE_ACTIVE,			     \
249 		.flags = ATOMIC_INIT(Z_PM_DEVICE_FLAGS(node_id) | (_flags)), \
250 		Z_PM_DEVICE_POWER_DOMAIN_INIT(node_id)			     \
251 	}
252 
253 /**
254  * @brief Utility macro to initialize #pm_device_rt.
255  *
256  * @note #DT_PROP_OR is used to retrieve the wakeup_source property because
257  * it may not be defined on all devices.
258  *
259  * @param obj Name of the #pm_device_base structure being initialized.
260  * @param node_id Devicetree node for the initialized device (can be invalid).
261  * @param pm_action_cb Device PM control callback function.
262  */
263 #define Z_PM_DEVICE_INIT(obj, node_id, pm_action_cb, isr_safe)			\
264 	{									\
265 		.base = Z_PM_DEVICE_BASE_INIT(obj, node_id, pm_action_cb,	\
266 				isr_safe ? BIT(PM_DEVICE_FLAG_ISR_SAFE) : 0),	\
267 		COND_CODE_1(isr_safe, (), (Z_PM_DEVICE_RUNTIME_INIT(obj)))	\
268 	}
269 
270 /**
271  * Get the name of device PM resources.
272  *
273  * @param dev_id Device id.
274  */
275 #define Z_PM_DEVICE_NAME(dev_id) _CONCAT(__pm_device_, dev_id)
276 
277 /**
278  * @brief Define device PM slot.
279  *
280  * This macro defines a pointer to a device in the pm_device_slots region.
281  * When invoked for each device with PM, it will effectively result in a device
282  * pointer array with the same size of the actual devices with PM enabled. This
283  * is used internally by the PM subsystem to keep track of suspended devices
284  * during system power transitions.
285  *
286  * @param dev_id Device id.
287  */
288 #define Z_PM_DEVICE_DEFINE_SLOT(dev_id)					\
289 	static STRUCT_SECTION_ITERABLE_ALTERNATE(pm_device_slots, device, \
290 			_CONCAT(__pm_slot_, dev_id))
291 
292 #ifdef CONFIG_PM_DEVICE
293 /**
294  * Define device PM resources for the given node identifier.
295  *
296  * @param node_id Node identifier (DT_INVALID_NODE if not a DT device).
297  * @param dev_id Device id.
298  * @param pm_action_cb PM control callback.
299  */
300 #define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb, isr_safe)		\
301 	Z_PM_DEVICE_DEFINE_SLOT(dev_id);					\
302 	static struct COND_CODE_1(isr_safe, (pm_device_isr), (pm_device))	\
303 		Z_PM_DEVICE_NAME(dev_id) =					\
304 		Z_PM_DEVICE_INIT(Z_PM_DEVICE_NAME(dev_id), node_id,		\
305 				 pm_action_cb, isr_safe)
306 
307 /**
308  * Get a reference to the device PM resources.
309  *
310  * @param dev_id Device id.
311  */
312 #define Z_PM_DEVICE_GET(dev_id) ((struct pm_device_base *)&Z_PM_DEVICE_NAME(dev_id))
313 
314 #else
315 #define Z_PM_DEVICE_DEFINE(node_id, dev_id, pm_action_cb, isr_safe)
316 #define Z_PM_DEVICE_GET(dev_id) NULL
317 #endif /* CONFIG_PM_DEVICE */
318 
319 /** @endcond */
320 
321 /**
322  * Define device PM resources for the given device name.
323  *
324  * @note This macro is a no-op if @kconfig{CONFIG_PM_DEVICE} is not enabled.
325  *
326  * @param dev_id Device id.
327  * @param pm_action_cb PM control callback.
328  * @param ... Optional flag to indicate that ISR safe. Use @ref PM_DEVICE_ISR_SAFE or 0.
329  *
330  * @see #PM_DEVICE_DT_DEFINE, #PM_DEVICE_DT_INST_DEFINE
331  */
332 #define PM_DEVICE_DEFINE(dev_id, pm_action_cb, ...)			\
333 	Z_PM_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, pm_action_cb,	\
334 			COND_CODE_1(IS_EMPTY(__VA_ARGS__), (0), (__VA_ARGS__)))
335 
336 /**
337  * Define device PM resources for the given node identifier.
338  *
339  * @note This macro is a no-op if @kconfig{CONFIG_PM_DEVICE} is not enabled.
340  *
341  * @param node_id Node identifier.
342  * @param pm_action_cb PM control callback.
343  * @param ... Optional flag to indicate that device is isr_ok. Use @ref PM_DEVICE_ISR_SAFE or 0.
344  *
345  * @see #PM_DEVICE_DT_INST_DEFINE, #PM_DEVICE_DEFINE
346  */
347 #define PM_DEVICE_DT_DEFINE(node_id, pm_action_cb, ...) \
348 	Z_PM_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), pm_action_cb, \
349 			COND_CODE_1(IS_EMPTY(__VA_ARGS__), (0), (__VA_ARGS__)))
350 
351 /**
352  * Define device PM resources for the given instance.
353  *
354  * @note This macro is a no-op if @kconfig{CONFIG_PM_DEVICE} is not enabled.
355  *
356  * @param idx Instance index.
357  * @param pm_action_cb PM control callback.
358  * @param ... Optional flag to indicate that device is isr_ok. Use @ref PM_DEVICE_ISR_SAFE or 0.
359  *
360  * @see #PM_DEVICE_DT_DEFINE, #PM_DEVICE_DEFINE
361  */
362 #define PM_DEVICE_DT_INST_DEFINE(idx, pm_action_cb, ...)		\
363 	Z_PM_DEVICE_DEFINE(DT_DRV_INST(idx),				\
364 			   Z_DEVICE_DT_DEV_ID(DT_DRV_INST(idx)),	\
365 			   pm_action_cb,				\
366 			   COND_CODE_1(IS_EMPTY(__VA_ARGS__), (0), (__VA_ARGS__)))
367 
368 /**
369  * @brief Obtain a reference to the device PM resources for the given device.
370  *
371  * @param dev_id Device id.
372  *
373  * @return Reference to the device PM resources (NULL if device
374  * @kconfig{CONFIG_PM_DEVICE} is disabled).
375  */
376 #define PM_DEVICE_GET(dev_id) \
377 	Z_PM_DEVICE_GET(dev_id)
378 
379 /**
380  * @brief Obtain a reference to the device PM resources for the given node.
381  *
382  * @param node_id Node identifier.
383  *
384  * @return Reference to the device PM resources (NULL if device
385  * @kconfig{CONFIG_PM_DEVICE} is disabled).
386  */
387 #define PM_DEVICE_DT_GET(node_id) \
388 	PM_DEVICE_GET(Z_DEVICE_DT_DEV_ID(node_id))
389 
390 /**
391  * @brief Obtain a reference to the device PM resources for the given instance.
392  *
393  * @param idx Instance index.
394  *
395  * @return Reference to the device PM resources (NULL if device
396  * @kconfig{CONFIG_PM_DEVICE} is disabled).
397  */
398 #define PM_DEVICE_DT_INST_GET(idx) \
399 	PM_DEVICE_DT_GET(DT_DRV_INST(idx))
400 
401 /**
402  * @brief Get name of device PM state
403  *
404  * @param state State id which name should be returned
405  */
406 const char *pm_device_state_str(enum pm_device_state state);
407 
408 /**
409  * @brief Run a pm action on a device.
410  *
411  * This function calls the device PM control callback so that the device does
412  * the necessary operations to execute the given action.
413  *
414  * @param dev Device instance.
415  * @param action Device pm action.
416  *
417  * @retval 0 If successful.
418  * @retval -ENOTSUP If requested state is not supported.
419  * @retval -EALREADY If device is already at the requested state.
420  * @retval -EBUSY If device is changing its state.
421  * @retval -ENOSYS If device does not support PM.
422  * @retval -EPERM If device has power state locked.
423  * @retval Errno Other negative errno on failure.
424  */
425 int pm_device_action_run(const struct device *dev,
426 		enum pm_device_action action);
427 
428 /**
429  * @brief Run a pm action on all children of a device.
430  *
431  * This function calls all child devices PM control callback so that the device
432  * does the necessary operations to execute the given action.
433  *
434  * @param dev Device instance.
435  * @param action Device pm action.
436  * @param failure_cb Function to call if a child fails the action, can be NULL.
437  */
438 void pm_device_children_action_run(const struct device *dev,
439 		enum pm_device_action action,
440 		pm_device_action_failed_cb_t failure_cb);
441 
442 #if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
443 /**
444  * @brief Obtain the power state of a device.
445  *
446  * @param dev Device instance.
447  * @param state Pointer where device power state will be stored.
448  *
449  * @retval 0 If successful.
450  * @retval -ENOSYS If device does not implement power management.
451  */
452 int pm_device_state_get(const struct device *dev,
453 			enum pm_device_state *state);
454 
455 /**
456  * @brief Initialize a device state to #PM_DEVICE_STATE_SUSPENDED.
457  *
458  * By default device state is initialized to #PM_DEVICE_STATE_ACTIVE. However
459  * in order to save power some drivers may choose to only initialize the device
460  * to the suspended state, or actively put the device into the suspended state.
461  * This function can therefore be used to notify the PM subsystem that the
462  * device is in #PM_DEVICE_STATE_SUSPENDED instead of the default.
463  *
464  * @param dev Device instance.
465  */
pm_device_init_suspended(const struct device * dev)466 static inline void pm_device_init_suspended(const struct device *dev)
467 {
468 	struct pm_device_base *pm = dev->pm_base;
469 
470 	pm->state = PM_DEVICE_STATE_SUSPENDED;
471 }
472 
473 /**
474  * @brief Initialize a device state to #PM_DEVICE_STATE_OFF.
475  *
476  * By default device state is initialized to #PM_DEVICE_STATE_ACTIVE. In
477  * general, this makes sense because the device initialization function will
478  * resume and configure a device, leaving it operational. However, when power
479  * domains are enabled, the device may be connected to a switchable power
480  * source, in which case it won't be powered at boot. This function can
481  * therefore be used to notify the PM subsystem that the device is in
482  * #PM_DEVICE_STATE_OFF instead of the default.
483  *
484  * @param dev Device instance.
485  */
pm_device_init_off(const struct device * dev)486 static inline void pm_device_init_off(const struct device *dev)
487 {
488 	struct pm_device_base *pm = dev->pm_base;
489 
490 	pm->state = PM_DEVICE_STATE_OFF;
491 }
492 
493 /**
494  * @brief Mark a device as busy.
495  *
496  * Devices marked as busy will not be suspended when the system goes into
497  * low-power states. This can be useful if, for example, the device is in the
498  * middle of a transaction.
499  *
500  * @param dev Device instance.
501  *
502  * @see pm_device_busy_clear()
503  */
504 void pm_device_busy_set(const struct device *dev);
505 
506 /**
507  * @brief Clear a device busy status.
508  *
509  * @param dev Device instance.
510  *
511  * @see pm_device_busy_set()
512  */
513 void pm_device_busy_clear(const struct device *dev);
514 
515 /**
516  * @brief Check if any device is busy.
517  *
518  * @retval false If no device is busy
519  * @retval true If one or more devices are busy
520  */
521 bool pm_device_is_any_busy(void);
522 
523 /**
524  * @brief Check if a device is busy.
525  *
526  * @param dev Device instance.
527  *
528  * @retval false If the device is not busy
529  * @retval true If the device is busy
530  */
531 bool pm_device_is_busy(const struct device *dev);
532 
533 /**
534  * @brief Enable or disable a device as a wake up source.
535  *
536  * A device marked as a wake up source will not be suspended when the system
537  * goes into low-power modes, thus allowing to use it as a wake up source for
538  * the system.
539  *
540  * @param dev Device instance.
541  * @param enable @c true to enable or @c false to disable
542  *
543  * @retval true If the wakeup source was successfully enabled.
544  * @retval false If the wakeup source was not successfully enabled.
545  */
546 bool pm_device_wakeup_enable(const struct device *dev, bool enable);
547 
548 /**
549  * @brief Check if a device is enabled as a wake up source.
550  *
551  * @param dev Device instance.
552  *
553  * @retval true if the wakeup source is enabled.
554  * @retval false if the wakeup source is not enabled.
555  */
556 bool pm_device_wakeup_is_enabled(const struct device *dev);
557 
558 /**
559  * @brief Check if a device is wake up capable
560  *
561  * @param dev Device instance.
562  *
563  * @retval true If the device is wake up capable.
564  * @retval false If the device is not wake up capable.
565  */
566 bool pm_device_wakeup_is_capable(const struct device *dev);
567 
568 /**
569  * @brief Lock current device state.
570  *
571  * This function locks the current device power state. Once
572  * locked the device power state will not be changed by
573  * system power management or device runtime power
574  * management until unlocked.
575  *
576  * @note The given device should not have device runtime enabled.
577  *
578  * @see pm_device_state_unlock
579  *
580  * @param dev Device instance.
581  */
582 void pm_device_state_lock(const struct device *dev);
583 
584 /**
585  * @brief Unlock the current device state.
586  *
587  * Unlocks a previously locked device pm.
588  *
589  * @see pm_device_state_lock
590  *
591  * @param dev Device instance.
592  */
593 void pm_device_state_unlock(const struct device *dev);
594 
595 /**
596  * @brief Check if the device pm is locked.
597  *
598  * @param dev Device instance.
599  *
600  * @retval true If device is locked.
601  * @retval false If device is not locked.
602  */
603 bool pm_device_state_is_locked(const struct device *dev);
604 
605 /**
606  * @brief Check if the device is on a switchable power domain.
607  *
608  * @param dev Device instance.
609  *
610  * @retval true If device is on a switchable power domain.
611  * @retval false If device is not on a switchable power domain.
612  */
613 bool pm_device_on_power_domain(const struct device *dev);
614 
615 /**
616  * @brief Add a device to a power domain.
617  *
618  * This function adds a device to a given power domain.
619  *
620  * @param dev Device to be added to the power domain.
621  * @param domain Power domain.
622  *
623  * @retval 0 If successful.
624  * @retval -EALREADY If device is already part of the power domain.
625  * @retval -ENOSYS If the application was built without power domain support.
626  * @retval -ENOSPC If there is no space available in the power domain to add the device.
627  */
628 int pm_device_power_domain_add(const struct device *dev,
629 			       const struct device *domain);
630 
631 /**
632  * @brief Remove a device from a power domain.
633  *
634  * This function removes a device from a given power domain.
635  *
636  * @param dev Device to be removed from the power domain.
637  * @param domain Power domain.
638  *
639  * @retval 0 If successful.
640  * @retval -ENOSYS If the application was built without power domain support.
641  * @retval -ENOENT If device is not in the given domain.
642  */
643 int pm_device_power_domain_remove(const struct device *dev,
644 				  const struct device *domain);
645 
646 /**
647  * @brief Check if the device is currently powered.
648  *
649  * @param dev Device instance.
650  *
651  * @retval true If device is currently powered, or is assumed to be powered
652  * (i.e. it does not support PM or is not under a PM domain)
653  * @retval false If device is not currently powered
654  */
655 bool pm_device_is_powered(const struct device *dev);
656 
657 /**
658  * @brief Setup a device driver into the lowest valid power mode
659  *
660  * This helper function is intended to be called at the end of a driver
661  * init function to automatically setup the device into the lowest power
662  * mode. It assumes that the device has been configured as if it is in
663  * @ref PM_DEVICE_STATE_OFF.
664  *
665  * @param dev Device instance.
666  * @param action_cb Device PM control callback function.
667  * @retval 0 On success.
668  * @retval -errno Error code from @a action_cb on failure.
669  */
670 int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb);
671 
672 #else
pm_device_state_get(const struct device * dev,enum pm_device_state * state)673 static inline int pm_device_state_get(const struct device *dev,
674 				      enum pm_device_state *state)
675 {
676 	ARG_UNUSED(dev);
677 
678 	*state = PM_DEVICE_STATE_ACTIVE;
679 
680 	return 0;
681 }
682 
pm_device_init_suspended(const struct device * dev)683 static inline void pm_device_init_suspended(const struct device *dev)
684 {
685 	ARG_UNUSED(dev);
686 }
pm_device_init_off(const struct device * dev)687 static inline void pm_device_init_off(const struct device *dev)
688 {
689 	ARG_UNUSED(dev);
690 }
pm_device_busy_set(const struct device * dev)691 static inline void pm_device_busy_set(const struct device *dev)
692 {
693 	ARG_UNUSED(dev);
694 }
pm_device_busy_clear(const struct device * dev)695 static inline void pm_device_busy_clear(const struct device *dev)
696 {
697 	ARG_UNUSED(dev);
698 }
pm_device_is_any_busy(void)699 static inline bool pm_device_is_any_busy(void) { return false; }
pm_device_is_busy(const struct device * dev)700 static inline bool pm_device_is_busy(const struct device *dev)
701 {
702 	ARG_UNUSED(dev);
703 	return false;
704 }
pm_device_wakeup_enable(const struct device * dev,bool enable)705 static inline bool pm_device_wakeup_enable(const struct device *dev,
706 					   bool enable)
707 {
708 	ARG_UNUSED(dev);
709 	ARG_UNUSED(enable);
710 	return false;
711 }
pm_device_wakeup_is_enabled(const struct device * dev)712 static inline bool pm_device_wakeup_is_enabled(const struct device *dev)
713 {
714 	ARG_UNUSED(dev);
715 	return false;
716 }
pm_device_wakeup_is_capable(const struct device * dev)717 static inline bool pm_device_wakeup_is_capable(const struct device *dev)
718 {
719 	ARG_UNUSED(dev);
720 	return false;
721 }
pm_device_state_lock(const struct device * dev)722 static inline void pm_device_state_lock(const struct device *dev)
723 {
724 	ARG_UNUSED(dev);
725 }
pm_device_state_unlock(const struct device * dev)726 static inline void pm_device_state_unlock(const struct device *dev)
727 {
728 	ARG_UNUSED(dev);
729 }
pm_device_state_is_locked(const struct device * dev)730 static inline bool pm_device_state_is_locked(const struct device *dev)
731 {
732 	ARG_UNUSED(dev);
733 	return false;
734 }
pm_device_on_power_domain(const struct device * dev)735 static inline bool pm_device_on_power_domain(const struct device *dev)
736 {
737 	ARG_UNUSED(dev);
738 	return false;
739 }
740 
pm_device_power_domain_add(const struct device * dev,const struct device * domain)741 static inline int pm_device_power_domain_add(const struct device *dev,
742 					     const struct device *domain)
743 {
744 	ARG_UNUSED(dev);
745 	ARG_UNUSED(domain);
746 	return -ENOSYS;
747 }
748 
pm_device_power_domain_remove(const struct device * dev,const struct device * domain)749 static inline int pm_device_power_domain_remove(const struct device *dev,
750 						const struct device *domain)
751 {
752 	ARG_UNUSED(dev);
753 	ARG_UNUSED(domain);
754 	return -ENOSYS;
755 }
756 
pm_device_is_powered(const struct device * dev)757 static inline bool pm_device_is_powered(const struct device *dev)
758 {
759 	ARG_UNUSED(dev);
760 	return true;
761 }
762 
pm_device_driver_init(const struct device * dev,pm_device_action_cb_t action_cb)763 static inline int pm_device_driver_init(const struct device *dev, pm_device_action_cb_t action_cb)
764 {
765 	int rc;
766 
767 	/* When power management is not enabled, all drivers should initialise to active state */
768 	rc = action_cb(dev, PM_DEVICE_ACTION_TURN_ON);
769 	if (rc == 0) {
770 		rc = action_cb(dev, PM_DEVICE_ACTION_RESUME);
771 	}
772 	return rc;
773 }
774 
775 #endif /* CONFIG_PM_DEVICE */
776 
777 /** @} */
778 
779 #ifdef __cplusplus
780 }
781 #endif
782 
783 #endif
784