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