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