1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3 * Copyright (c) 2018, Linaro Limited
4 */
5
6 #ifndef __KERNEL_PM_H
7 #define __KERNEL_PM_H
8
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <tee_api_types.h>
12
13 /*
14 * Platform hints on targeted power state. Hints are stored in a 32bit
15 * unsigned value. Lower bits defines generic resource bit flags. Higher
16 * bits stores a platform specific value specific platform driver may
17 * understand. Registered callbacks may choose to use or ignore these hints.
18 *
19 * PM_HINT_CLOCK_STATE - When set clock shall be suspended/restored
20 * PM_HINT_POWER_STATE - When set device power shall be suspended/restored
21 * PM_HINT_IO_STATE - When set IO pins shall be suspended/restored
22 * PM_HINT_CONTEXT_STATE - When set the full context be suspended/restored
23 * PM_HINT_PLATFORM_STATE_MASK - Bit mask reserved for platform specific hints
24 * PM_HINT_PLATFORM_STATE_SHIFT - LSBit position of platform specific hints mask
25 */
26 #define PM_HINT_CLOCK_STATE BIT(0)
27 #define PM_HINT_POWER_STATE BIT(1)
28 #define PM_HINT_IO_STATE BIT(2)
29 #define PM_HINT_CONTEXT_STATE BIT(3)
30 #define PM_HINT_PLATFORM_STATE_MASK GENMASK_32(31, 16)
31 #define PM_HINT_PLATFORM_STATE_SHIFT U(16)
32
33 /*
34 * PM_OP_SUSPEND: platform is suspending to a target low power state
35 * PM_OP_RESUME: platform is resuming from low power state
36 */
37 enum pm_op {
38 PM_OP_SUSPEND = 0,
39 PM_OP_RESUME = 1,
40 };
41
42 /*
43 * Registered callbacks are called the ordering directives specified
44 * by the PM_CB_ORDER_* value. Driver ordered callbacks at suspended
45 * first/resumed last. Core service ordered callbacks are suspended
46 * last/resumed first.
47 */
48 enum pm_callback_order {
49 PM_CB_ORDER_DRIVER = 0,
50 PM_CB_ORDER_CORE_SERVICE,
51 PM_CB_ORDER_MAX
52 };
53
54 #define PM_CALLBACK_HANDLE_INITIALIZER(_callback, _handle, _order, _name)\
55 ((struct pm_callback_handle){ \
56 .callback = (_callback), \
57 .handle = (_handle), \
58 .order = (_order), \
59 .name = (_name), \
60 })
61
62 #define PM_CALLBACK_GET_HANDLE(pm_handle) ((pm_handle)->handle)
63
64 struct pm_callback_handle;
65 typedef TEE_Result (*pm_callback)(enum pm_op op, uint32_t pm_hint,
66 const struct pm_callback_handle *pm_handle);
67
68 /*
69 * Drivers and services can register a callback function for the platform
70 * suspend and resume sequences. A private address handle can be registered
71 * with the callback and retrieved from the callback. Callback can be
72 * registered with a specific call order as defined per PM_CB_ORDER_*.
73 *
74 * Callback shall return an error if failing to complete target transition.
75 * This information may be used by the platform to resume a platform on
76 * non-fatal failure to suspend.
77 *
78 * Callback implementations should ensure their functions belong to unpaged
79 * memory sections (see DECLARE_KEEP_PAGER()) since the callback is likely to
80 * be called from an unpaged execution context.
81 *
82 * Power Mamagement callback functions API:
83 *
84 * TEE_Result (*callback)(enum pm_op op,
85 * unsigned int pm_hint,
86 * const struct pm_callback_handle *pm_handle);
87 *
88 * @op - Target operation: either PM_SUSPEND or PM_RESUME
89 * @pm_hint - Hints on power state platform suspends to /resumes from.
90 * PM_STATE_HINT_* defines the supported values.
91 * @pm_handle - Reference to the struct pm_callback_handle related to to
92 * registered callback. Callback can retrieve the registered
93 * private handle with PM_CALLBACK_GET_HANDLE().
94 *
95 * Return a TEE_Result compliant return code
96 */
97 /*
98 * struct pm_callback_handle store the callback registration directives.
99 *
100 * @callback - Registered callback function
101 * @handle - Registered private handler for the callback
102 * @order - Registered callback call order priority (PM_CB_ORDER_*)
103 * @flags - Flags set by pm core to keep track of execution
104 * @name - Registered callback name
105 */
106 struct pm_callback_handle {
107 /* Set by the caller when registering a callback */
108 pm_callback callback;
109 void *handle;
110 uint8_t order;
111 /* Set by the system according to execution context */
112 uint8_t flags;
113 const char *name;
114 };
115
116 /*
117 * Register a callback for suspend/resume sequence
118 * Refer to struct pm_callback_handle for description of the callbacks
119 * API and the registration directives.
120 *
121 * @pm_handle: Reference callback registration directives
122 */
123 void register_pm_cb(struct pm_callback_handle *pm_handle);
124
125 /*
126 * Register a driver callback for generic suspend/resume.
127 * Refer to struct pm_callback_handle for description of the callbacks
128 * API.
129 *
130 * @callback: Registered callback function
131 * @handle: Registered private handle argument for the callback
132 * @name: Registered callback name
133 */
register_pm_driver_cb(pm_callback callback,void * handle,const char * name)134 static inline void register_pm_driver_cb(pm_callback callback, void *handle,
135 const char *name)
136 {
137 register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle,
138 PM_CB_ORDER_DRIVER,
139 name));
140 }
141
142 /*
143 * Register a core service callback for generic suspend/resume.
144 * Refer to struct pm_callback_handle for description of the callbacks
145 * API.
146 *
147 * @callback: Registered callback function
148 * @handle: Registered private handle argument for the callback
149 * @name: Registered callback name
150 */
register_pm_core_service_cb(pm_callback callback,void * handle,const char * name)151 static inline void register_pm_core_service_cb(pm_callback callback,
152 void *handle, const char *name)
153 {
154 register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle,
155 PM_CB_ORDER_CORE_SERVICE,
156 name));
157 }
158
159 /*
160 * Request call to registered PM callbacks
161 *
162 * @op: Either PM_OP_SUSPEND or PM_OP_RESUME
163 * @pm_hint: Hint (PM_HINT_*) on state the platform suspends to/resumes from.
164 *
165 * Return a TEE_Result compliant status
166 */
167 TEE_Result pm_change_state(enum pm_op op, uint32_t pm_hint);
168
169 #endif /*__KERNEL_PM_H*/
170