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 #define PM_HINT_STATE(_x) ((_x) & ~PM_HINT_PLATFORM_STATE_MASK) 34 #define PM_HINT_PLATFORM_STATE(_x) \ 35 (((_x) & PM_HINT_PLATFORM_STATE_MASK) >> PM_HINT_PLATFORM_STATE_SHIFT) 36 37 #define PM_HINT_IS_STATE(_x, _name) ((_x) & PM_HINT_ ## _name ## _STATE) 38 39 /* 40 * PM_OP_SUSPEND: platform is suspending to a target low power state 41 * PM_OP_RESUME: platform is resuming from low power state 42 */ 43 enum pm_op { 44 PM_OP_SUSPEND = 0, 45 PM_OP_RESUME = 1, 46 }; 47 48 /* 49 * Registered callbacks are called the ordering directives specified 50 * by the PM_CB_ORDER_* value. Driver ordered callbacks at suspended 51 * first/resumed last. Core service ordered callbacks are suspended 52 * last/resumed first. 53 */ 54 enum pm_callback_order { 55 PM_CB_ORDER_DRIVER = 0, 56 PM_CB_ORDER_CORE_SERVICE, 57 PM_CB_ORDER_MAX 58 }; 59 60 #define PM_CALLBACK_HANDLE_INITIALIZER(_callback, _handle, _order, _name)\ 61 ((struct pm_callback_handle){ \ 62 .callback = (_callback), \ 63 .handle = (_handle), \ 64 .order = (_order), \ 65 .name = (_name), \ 66 }) 67 68 #define PM_CALLBACK_GET_HANDLE(pm_handle) ((pm_handle)->handle) 69 70 struct pm_callback_handle; 71 typedef TEE_Result (*pm_callback)(enum pm_op op, uint32_t pm_hint, 72 const struct pm_callback_handle *pm_handle); 73 74 /* 75 * Drivers and services can register a callback function for the platform 76 * suspend and resume sequences. A private address handle can be registered 77 * with the callback and retrieved from the callback. Callback can be 78 * registered with a specific call order as defined per PM_CB_ORDER_*. 79 * 80 * Callback shall return an error if failing to complete target transition. 81 * This information may be used by the platform to resume a platform on 82 * non-fatal failure to suspend. 83 * 84 * Callback implementations should ensure their functions belong to unpaged 85 * memory sections (see DECLARE_KEEP_PAGER()) since the callback is likely to 86 * be called from an unpaged execution context. 87 * 88 * Power Mamagement callback functions API: 89 * 90 * TEE_Result (*callback)(enum pm_op op, 91 * unsigned int pm_hint, 92 * const struct pm_callback_handle *pm_handle); 93 * 94 * @op - Target operation: either PM_SUSPEND or PM_RESUME 95 * @pm_hint - Hints on power state platform suspends to /resumes from. 96 * PM_STATE_HINT_* defines the supported values. 97 * @pm_handle - Reference to the struct pm_callback_handle related to to 98 * registered callback. Callback can retrieve the registered 99 * private handle with PM_CALLBACK_GET_HANDLE(). 100 * 101 * Return a TEE_Result compliant return code 102 */ 103 /* 104 * struct pm_callback_handle store the callback registration directives. 105 * 106 * @callback - Registered callback function 107 * @handle - Registered private handler for the callback 108 * @order - Registered callback call order priority (PM_CB_ORDER_*) 109 * @flags - Flags set by pm core to keep track of execution 110 * @name - Registered callback name 111 */ 112 struct pm_callback_handle { 113 /* Set by the caller when registering a callback */ 114 pm_callback callback; 115 void *handle; 116 uint8_t order; 117 /* Set by the system according to execution context */ 118 uint8_t flags; 119 const char *name; 120 }; 121 122 /* 123 * Register a callback for suspend/resume sequence 124 * Refer to struct pm_callback_handle for description of the callbacks 125 * API and the registration directives. 126 * 127 * @pm_handle: Reference callback registration directives 128 */ 129 void register_pm_cb(struct pm_callback_handle *pm_handle); 130 131 /* 132 * Register a driver callback for generic suspend/resume. 133 * Refer to struct pm_callback_handle for description of the callbacks 134 * API. 135 * 136 * @callback: Registered callback function 137 * @handle: Registered private handle argument for the callback 138 * @name: Registered callback name 139 */ 140 static inline void register_pm_driver_cb(pm_callback callback, void *handle, 141 const char *name) 142 { 143 register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle, 144 PM_CB_ORDER_DRIVER, 145 name)); 146 } 147 148 /* 149 * Register a core service callback for generic suspend/resume. 150 * Refer to struct pm_callback_handle for description of the callbacks 151 * API. 152 * 153 * @callback: Registered callback function 154 * @handle: Registered private handle argument for the callback 155 * @name: Registered callback name 156 */ 157 static inline void register_pm_core_service_cb(pm_callback callback, 158 void *handle, const char *name) 159 { 160 register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle, 161 PM_CB_ORDER_CORE_SERVICE, 162 name)); 163 } 164 165 /* 166 * Request call to registered PM callbacks 167 * 168 * @op: Either PM_OP_SUSPEND or PM_OP_RESUME 169 * @pm_hint: Hint (PM_HINT_*) on state the platform suspends to/resumes from. 170 * 171 * Return a TEE_Result compliant status 172 */ 173 TEE_Result pm_change_state(enum pm_op op, uint32_t pm_hint); 174 175 #endif /*__KERNEL_PM_H*/ 176