1 /*
2 * Copyright (c) 2012-2014 Wind River Systems, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_PM_PM_H_
8 #define ZEPHYR_INCLUDE_PM_PM_H_
9
10 #include <zephyr/types.h>
11 #include <zephyr/sys/slist.h>
12 #include <zephyr/pm/state.h>
13 #include <zephyr/toolchain.h>
14 #include <errno.h>
15 #include <stdbool.h>
16
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20
21 /**
22 * @brief System and device power management
23 * @defgroup subsys_pm Power Management (PM)
24 * @ingroup os_services
25 * @{
26 * @}
27 */
28
29 /**
30 * @brief System Power Management API
31 * @defgroup subsys_pm_sys System
32 * @ingroup subsys_pm
33 * @{
34 */
35
36 /**
37 * Power management notifier struct
38 *
39 * This struct contains callbacks that are called when the target enters and
40 * exits power states.
41 *
42 * As currently implemented the entry callback is invoked when
43 * transitioning from PM_STATE_ACTIVE to another state, and the exit
44 * callback is invoked when transitioning from a non-active state to
45 * PM_STATE_ACTIVE. This behavior may change in the future.
46 *
47 * @note These callbacks can be called from the ISR of the event
48 * that caused the kernel exit from idling.
49 *
50 * @note It is not allowed to call @ref pm_notifier_unregister or
51 * @ref pm_notifier_register from these callbacks because they are called
52 * with the spin locked in those functions.
53 */
54 struct pm_notifier {
55 sys_snode_t _node;
56 /**
57 * Application defined function for doing any target specific operations
58 * for power state entry.
59 */
60 void (*state_entry)(enum pm_state state);
61 /**
62 * Application defined function for doing any target specific operations
63 * for power state exit.
64 */
65 void (*state_exit)(enum pm_state state);
66 };
67
68 #if defined(CONFIG_PM) || defined(__DOXYGEN__)
69 /**
70 * @brief Force usage of given power state.
71 *
72 * This function overrides decision made by PM policy forcing
73 * usage of given power state upon next entry of the idle thread.
74 *
75 * @note This function can only run in thread context
76 *
77 * @param cpu CPU index.
78 * @param info Power state which should be used in the ongoing
79 * suspend operation.
80 */
81 bool pm_state_force(uint8_t cpu, const struct pm_state_info *info);
82
83 /**
84 * @brief Register a power management notifier
85 *
86 * Register the given notifier from the power management notification
87 * list.
88 *
89 * @param notifier pm_notifier object to be registered.
90 */
91 void pm_notifier_register(struct pm_notifier *notifier);
92
93 /**
94 * @brief Unregister a power management notifier
95 *
96 * Remove the given notifier from the power management notification
97 * list. After that this object callbacks will not be called.
98 *
99 * @param notifier pm_notifier object to be unregistered.
100 *
101 * @return 0 if the notifier was successfully removed, a negative value
102 * otherwise.
103 */
104 int pm_notifier_unregister(struct pm_notifier *notifier);
105
106 /**
107 * @brief Gets the next power state that will be used.
108 *
109 * This function returns the next power state that will be used by the
110 * SoC.
111 *
112 * @param cpu CPU index.
113 * @return next pm_state_info that will be used
114 */
115 const struct pm_state_info *pm_state_next_get(uint8_t cpu);
116
117 /**
118 * @}
119 */
120
121 /**
122 * @brief System Power Management Hooks
123 * @defgroup subsys_pm_sys_hooks Hooks
124 * @ingroup subsys_pm_sys
125 * @{
126 */
127
128 /**
129 * @brief Put processor into a power state.
130 *
131 * This function implements the SoC specific details necessary
132 * to put the processor into available power states.
133 *
134 * @param state Power state.
135 * @param substate_id Power substate id.
136 */
137 void pm_state_set(enum pm_state state, uint8_t substate_id);
138
139 /**
140 * @brief Do any SoC or architecture specific post ops after sleep state exits.
141 *
142 * This function is a place holder to do any operations that may
143 * be needed to be done after sleep state exits. Currently it enables
144 * interrupts after resuming from sleep state. In future, the enabling
145 * of interrupts may be moved into the kernel.
146 *
147 * @param state Power state.
148 * @param substate_id Power substate id.
149 */
150 void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id);
151
152 /**
153 * @}
154 */
155
156 #else /* CONFIG_PM */
157
pm_notifier_register(struct pm_notifier * notifier)158 static inline void pm_notifier_register(struct pm_notifier *notifier)
159 {
160 ARG_UNUSED(notifier);
161 }
162
pm_notifier_unregister(struct pm_notifier * notifier)163 static inline int pm_notifier_unregister(struct pm_notifier *notifier)
164 {
165 ARG_UNUSED(notifier);
166
167 return -ENOSYS;
168 }
169
pm_state_set(enum pm_state state,uint8_t substate_id)170 static inline void pm_state_set(enum pm_state state, uint8_t substate_id)
171 {
172 ARG_UNUSED(state);
173 ARG_UNUSED(substate_id);
174 }
175
pm_state_exit_post_ops(enum pm_state state,uint8_t substate_id)176 static inline void pm_state_exit_post_ops(enum pm_state state,
177 uint8_t substate_id)
178 {
179 ARG_UNUSED(state);
180 ARG_UNUSED(substate_id);
181 }
182
pm_state_next_get(uint8_t cpu)183 static inline const struct pm_state_info *pm_state_next_get(uint8_t cpu)
184 {
185 ARG_UNUSED(cpu);
186
187 return NULL;
188 }
189 #endif /* CONFIG_PM */
190
191 void z_pm_save_idle_exit(void);
192
193 #ifdef __cplusplus
194 }
195 #endif
196
197 #endif /* ZEPHYR_INCLUDE_PM_PM_H_ */
198