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 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) \ 55 (struct pm_callback_handle){ \ 56 .callback = (_callback), \ 57 .handle = (_handle), \ 58 .order = (_order), \ 59 } 60 61 #define PM_CALLBACK_GET_HANDLE(pm_handle) ((pm_handle)->handle) 62 63 /* 64 * Drivers and services can register a callback function for the platform 65 * suspend and resume sequences. A private address handle can be registered 66 * with the callback and retrieved from the callback. Callback can be 67 * registered with a specific call order as defined per PM_CB_ORDER_*. 68 * 69 * Callback shall return an error if failing to complete target transition. 70 * This information may be used by the platform to resume a platform on 71 * non-fatal failure to suspend. 72 * 73 * Callback implementations should ensure their functions belong to unpaged 74 * memory sections (see KEEP_PAGER()) since the callback is likely to be 75 * called from an unpaged execution context. 76 * 77 * Power Mamagement callback functions API: 78 * 79 * TEE_Result (*callback)(enum pm_op op, 80 * unsigned int pm_hint, 81 * const struct pm_callback_handle *pm_handle); 82 * 83 * @op - Target operation: either PM_SUSPEND or PM_RESUME 84 * @pm_hint - Hints on power state platform suspends to /resumes from. 85 * PM_STATE_HINT_* defines the supported values. 86 * @pm_handle - Reference to the struct pm_callback_handle related to to 87 * registered callback. Callback can retrieve the registered 88 * private handle with PM_CALLBACK_GET_HANDLE(). 89 * 90 * Return a TEE_Result compliant return code 91 */ 92 /* 93 * struct pm_callback_handle store the callback registration directives. 94 * 95 * @callback - Registered callback function 96 * @handle - Registered private handler for the callback 97 * @order - Registered callback call order priority (PM_CB_ORDER_*) 98 */ 99 struct pm_callback_handle { 100 /* Set by the caller when registering a callback */ 101 TEE_Result (*callback)(enum pm_op op, uint32_t pm_hint, 102 const struct pm_callback_handle *pm_handle); 103 void *handle; 104 uint8_t order; 105 /* Set by the system according to execution context */ 106 uint8_t flags; 107 }; 108 109 /* 110 * Register a callback for suspend/resume sequence 111 * Refer to struct pm_callback_handle for description of the callbacks 112 * API and the registration directives. 113 * 114 * @pm_handle: Reference callback registration directives 115 */ 116 void register_pm_cb(struct pm_callback_handle *pm_handle); 117 118 /* 119 * Register a driver callback for generic suspend/resume. 120 * Refer to struct pm_callback_handle for description of the callbacks 121 * API. 122 * 123 * @callback: Registered callback function 124 * @handle: Registered private handle argument for the callback 125 */ 126 static inline void register_pm_driver_cb( 127 TEE_Result (*callback)( 128 enum pm_op op, uint32_t pm_hint, 129 const struct pm_callback_handle *pm_handle), 130 void *handle) 131 { 132 register_pm_cb(&PM_CALLBACK_HANDLE_INITIALIZER(callback, handle, 133 PM_CB_ORDER_DRIVER)); 134 } 135 136 /* 137 * Request call to registered PM callbacks 138 * 139 * @op: Either PM_OP_SUSPEND or PM_OP_RESUME 140 * @pm_hint: Hint (PM_HINT_*) on state the platform suspends to/resumes from. 141 * 142 * Return a TEE_Result compliant status 143 */ 144 TEE_Result pm_change_state(enum pm_op op, uint32_t pm_hint); 145 146 #endif /*__KERNEL_PM_H*/ 147