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 * @since 1.2
25 * @ingroup os_services
26 * @{
27 * @}
28 */
29
30 /**
31 * @brief System Power Management API
32 * @defgroup subsys_pm_sys System
33 * @since 1.2
34 * @ingroup subsys_pm
35 * @{
36 */
37
38 /**
39 * Power management notifier struct
40 *
41 * This struct contains callbacks that are called when the target enters and
42 * exits power states.
43 *
44 * As currently implemented the entry callback is invoked when
45 * transitioning from PM_STATE_ACTIVE to another state, and the exit
46 * callback is invoked when transitioning from a non-active state to
47 * PM_STATE_ACTIVE. This behavior may change in the future.
48 *
49 * @note These callbacks can be called from the ISR of the event
50 * that caused the kernel exit from idling.
51 *
52 * @note It is not allowed to call @ref pm_notifier_unregister or
53 * @ref pm_notifier_register from these callbacks because they are called
54 * with the spin locked in those functions.
55 */
56 struct pm_notifier {
57 sys_snode_t _node;
58 /**
59 * Application defined function for doing any target specific operations
60 * for power state entry.
61 */
62 void (*state_entry)(enum pm_state state);
63 /**
64 * Application defined function for doing any target specific operations
65 * for power state exit.
66 */
67 void (*state_exit)(enum pm_state state);
68 };
69
70 #if defined(CONFIG_PM) || defined(__DOXYGEN__)
71 /**
72 * @brief Force usage of given power state.
73 *
74 * This function overrides decision made by PM policy forcing
75 * usage of given power state upon next entry of the idle thread.
76 *
77 * @note This function can only run in thread context
78 *
79 * @param cpu CPU index.
80 * @param info Power state which should be used in the ongoing
81 * suspend operation.
82 */
83 bool pm_state_force(uint8_t cpu, const struct pm_state_info *info);
84
85 /**
86 * @brief Register a power management notifier
87 *
88 * Register the given notifier from the power management notification
89 * list.
90 *
91 * @param notifier pm_notifier object to be registered.
92 */
93 void pm_notifier_register(struct pm_notifier *notifier);
94
95 /**
96 * @brief Unregister a power management notifier
97 *
98 * Remove the given notifier from the power management notification
99 * list. After that this object callbacks will not be called.
100 *
101 * @param notifier pm_notifier object to be unregistered.
102 *
103 * @return 0 if the notifier was successfully removed, a negative value
104 * otherwise.
105 */
106 int pm_notifier_unregister(struct pm_notifier *notifier);
107
108 /**
109 * @brief Gets the next power state that will be used.
110 *
111 * This function returns the next power state that will be used by the
112 * SoC.
113 *
114 * @param cpu CPU index.
115 * @return next pm_state_info that will be used
116 */
117 const struct pm_state_info *pm_state_next_get(uint8_t cpu);
118
119 /**
120 * @brief Notify exit from kernel sleep.
121 *
122 * This function would notify exit from kernel idling if a corresponding
123 * pm_system_suspend() notification was handled and did not return
124 * PM_STATE_ACTIVE.
125 *
126 * This function should be called from the ISR context of the event
127 * that caused the exit from kernel idling.
128 *
129 * This is required for cpu power states that would require
130 * interrupts to be enabled while entering low power states. e.g. C1 in x86. In
131 * those cases, the ISR would be invoked immediately after the event wakes up
132 * the CPU, before code following the CPU wait, gets a chance to execute. This
133 * can be ignored if no operation needs to be done at the wake event
134 * notification.
135 */
136 void pm_system_resume(void);
137
138
139 /** @cond INTERNAL_HIDDEN */
140 __deprecated void z_pm_save_idle_exit(void);
141 /** @endcond */
142
143 /**
144 * @}
145 */
146
147 /**
148 * @brief System Power Management Hooks
149 * @defgroup subsys_pm_sys_hooks Hooks
150 * @ingroup subsys_pm_sys
151 * @{
152 */
153
154 /**
155 * @brief Put processor into a power state.
156 *
157 * This function implements the SoC specific details necessary
158 * to put the processor into available power states.
159 *
160 * @param state Power state.
161 * @param substate_id Power substate id.
162 */
163 void pm_state_set(enum pm_state state, uint8_t substate_id);
164
165 /**
166 * @brief Do any SoC or architecture specific post ops after sleep state exits.
167 *
168 * This function is a place holder to do any operations that may
169 * be needed to be done after sleep state exits. Currently it enables
170 * interrupts after resuming from sleep state. In future, the enabling
171 * of interrupts may be moved into the kernel.
172 *
173 * @param state Power state.
174 * @param substate_id Power substate id.
175 */
176 void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id);
177
178 /**
179 * @}
180 */
181
182 #else /* CONFIG_PM */
183
pm_notifier_register(struct pm_notifier * notifier)184 static inline void pm_notifier_register(struct pm_notifier *notifier)
185 {
186 ARG_UNUSED(notifier);
187 }
188
pm_notifier_unregister(struct pm_notifier * notifier)189 static inline int pm_notifier_unregister(struct pm_notifier *notifier)
190 {
191 ARG_UNUSED(notifier);
192
193 return -ENOSYS;
194 }
195
pm_state_next_get(uint8_t cpu)196 static inline const struct pm_state_info *pm_state_next_get(uint8_t cpu)
197 {
198 ARG_UNUSED(cpu);
199
200 return NULL;
201 }
z_pm_save_idle_exit(void)202 static inline void z_pm_save_idle_exit(void)
203 {
204 }
205
pm_system_resume(void)206 static inline void pm_system_resume(void)
207 {
208 }
209
210 #endif /* CONFIG_PM */
211
212 #ifdef __cplusplus
213 }
214 #endif
215
216 #endif /* ZEPHYR_INCLUDE_PM_PM_H_ */
217