Branch data Line data Source code
1 : : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 : : /****************************************************************************** 3 : : * 4 : : * Module Name: exsystem - Interface to OS services 5 : : * 6 : : * Copyright (C) 2000 - 2020, Intel Corp. 7 : : * 8 : : *****************************************************************************/ 9 : : 10 : : #include <acpi/acpi.h> 11 : : #include "accommon.h" 12 : : #include "acinterp.h" 13 : : 14 : : #define _COMPONENT ACPI_EXECUTER 15 : : ACPI_MODULE_NAME("exsystem") 16 : : 17 : : /******************************************************************************* 18 : : * 19 : : * FUNCTION: acpi_ex_system_wait_semaphore 20 : : * 21 : : * PARAMETERS: semaphore - Semaphore to wait on 22 : : * timeout - Max time to wait 23 : : * 24 : : * RETURN: Status 25 : : * 26 : : * DESCRIPTION: Implements a semaphore wait with a check to see if the 27 : : * semaphore is available immediately. If it is not, the 28 : : * interpreter is released before waiting. 29 : : * 30 : : ******************************************************************************/ 31 : 0 : acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) 32 : : { 33 : 0 : acpi_status status; 34 : : 35 : 0 : ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); 36 : : 37 : 0 : status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT); 38 [ # # ]: 0 : if (ACPI_SUCCESS(status)) { 39 : : return_ACPI_STATUS(status); 40 : : } 41 : : 42 [ # # ]: 0 : if (status == AE_TIME) { 43 : : 44 : : /* We must wait, so unlock the interpreter */ 45 : : 46 : 0 : acpi_ex_exit_interpreter(); 47 : 0 : status = acpi_os_wait_semaphore(semaphore, 1, timeout); 48 : : 49 : : ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 50 : : "*** Thread awake after blocking, %s\n", 51 : 0 : acpi_format_exception(status))); 52 : : 53 : : /* Reacquire the interpreter */ 54 : : 55 : 0 : acpi_ex_enter_interpreter(); 56 : : } 57 : : 58 : : return_ACPI_STATUS(status); 59 : : } 60 : : 61 : : /******************************************************************************* 62 : : * 63 : : * FUNCTION: acpi_ex_system_wait_mutex 64 : : * 65 : : * PARAMETERS: mutex - Mutex to wait on 66 : : * timeout - Max time to wait 67 : : * 68 : : * RETURN: Status 69 : : * 70 : : * DESCRIPTION: Implements a mutex wait with a check to see if the 71 : : * mutex is available immediately. If it is not, the 72 : : * interpreter is released before waiting. 73 : : * 74 : : ******************************************************************************/ 75 : : 76 : 700 : acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) 77 : : { 78 : 700 : acpi_status status; 79 : : 80 : 700 : ACPI_FUNCTION_TRACE(ex_system_wait_mutex); 81 : : 82 : 700 : status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT); 83 [ - + ]: 700 : if (ACPI_SUCCESS(status)) { 84 : : return_ACPI_STATUS(status); 85 : : } 86 : : 87 [ # # ]: 0 : if (status == AE_TIME) { 88 : : 89 : : /* We must wait, so unlock the interpreter */ 90 : : 91 : 0 : acpi_ex_exit_interpreter(); 92 : 0 : status = acpi_os_acquire_mutex(mutex, timeout); 93 : : 94 : : ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 95 : : "*** Thread awake after blocking, %s\n", 96 : 0 : acpi_format_exception(status))); 97 : : 98 : : /* Reacquire the interpreter */ 99 : : 100 : 0 : acpi_ex_enter_interpreter(); 101 : : } 102 : : 103 : : return_ACPI_STATUS(status); 104 : : } 105 : : 106 : : /******************************************************************************* 107 : : * 108 : : * FUNCTION: acpi_ex_system_do_stall 109 : : * 110 : : * PARAMETERS: how_long - The amount of time to stall, 111 : : * in microseconds 112 : : * 113 : : * RETURN: Status 114 : : * 115 : : * DESCRIPTION: Suspend running thread for specified amount of time. 116 : : * Note: ACPI specification requires that Stall() does not 117 : : * relinquish the processor, and delays longer than 100 usec 118 : : * should use Sleep() instead. We allow stalls up to 255 usec 119 : : * for compatibility with other interpreters and existing BIOSs. 120 : : * 121 : : ******************************************************************************/ 122 : : 123 : 0 : acpi_status acpi_ex_system_do_stall(u32 how_long) 124 : : { 125 : 0 : acpi_status status = AE_OK; 126 : : 127 : 0 : ACPI_FUNCTION_ENTRY(); 128 : : 129 [ # # ]: 0 : if (how_long > 255) { /* 255 microseconds */ 130 : : /* 131 : : * Longer than 255 usec, this is an error 132 : : * 133 : : * (ACPI specifies 100 usec as max, but this gives some slack in 134 : : * order to support existing BIOSs) 135 : : */ 136 : 0 : ACPI_ERROR((AE_INFO, 137 : : "Time parameter is too large (%u)", how_long)); 138 : 0 : status = AE_AML_OPERAND_VALUE; 139 : : } else { 140 : 0 : acpi_os_stall(how_long); 141 : : } 142 : : 143 : 0 : return (status); 144 : : } 145 : : 146 : : /******************************************************************************* 147 : : * 148 : : * FUNCTION: acpi_ex_system_do_sleep 149 : : * 150 : : * PARAMETERS: how_long - The amount of time to sleep, 151 : : * in milliseconds 152 : : * 153 : : * RETURN: None 154 : : * 155 : : * DESCRIPTION: Sleep the running thread for specified amount of time. 156 : : * 157 : : ******************************************************************************/ 158 : : 159 : 0 : acpi_status acpi_ex_system_do_sleep(u64 how_long) 160 : : { 161 : 0 : ACPI_FUNCTION_ENTRY(); 162 : : 163 : : /* Since this thread will sleep, we must release the interpreter */ 164 : : 165 : 0 : acpi_ex_exit_interpreter(); 166 : : 167 : : /* 168 : : * For compatibility with other ACPI implementations and to prevent 169 : : * accidental deep sleeps, limit the sleep time to something reasonable. 170 : : */ 171 : 0 : if (how_long > ACPI_MAX_SLEEP) { 172 : : how_long = ACPI_MAX_SLEEP; 173 : : } 174 : : 175 : 0 : acpi_os_sleep(how_long); 176 : : 177 : : /* And now we must get the interpreter again */ 178 : : 179 : 0 : acpi_ex_enter_interpreter(); 180 : 0 : return (AE_OK); 181 : : } 182 : : 183 : : /******************************************************************************* 184 : : * 185 : : * FUNCTION: acpi_ex_system_signal_event 186 : : * 187 : : * PARAMETERS: obj_desc - The object descriptor for this op 188 : : * 189 : : * RETURN: Status 190 : : * 191 : : * DESCRIPTION: Provides an access point to perform synchronization operations 192 : : * within the AML. 193 : : * 194 : : ******************************************************************************/ 195 : : 196 : 0 : acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) 197 : : { 198 : 0 : acpi_status status = AE_OK; 199 : : 200 : 0 : ACPI_FUNCTION_TRACE(ex_system_signal_event); 201 : : 202 [ # # ]: 0 : if (obj_desc) { 203 : 0 : status = 204 : 0 : acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1); 205 : : } 206 : : 207 : 0 : return_ACPI_STATUS(status); 208 : : } 209 : : 210 : : /******************************************************************************* 211 : : * 212 : : * FUNCTION: acpi_ex_system_wait_event 213 : : * 214 : : * PARAMETERS: time_desc - The 'time to delay' object descriptor 215 : : * obj_desc - The object descriptor for this op 216 : : * 217 : : * RETURN: Status 218 : : * 219 : : * DESCRIPTION: Provides an access point to perform synchronization operations 220 : : * within the AML. This operation is a request to wait for an 221 : : * event. 222 : : * 223 : : ******************************************************************************/ 224 : : 225 : : acpi_status 226 : 0 : acpi_ex_system_wait_event(union acpi_operand_object *time_desc, 227 : : union acpi_operand_object *obj_desc) 228 : : { 229 : 0 : acpi_status status = AE_OK; 230 : : 231 : 0 : ACPI_FUNCTION_TRACE(ex_system_wait_event); 232 : : 233 [ # # ]: 0 : if (obj_desc) { 234 : 0 : status = 235 : 0 : acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore, 236 : 0 : (u16) time_desc->integer. 237 : : value); 238 : : } 239 : : 240 : 0 : return_ACPI_STATUS(status); 241 : : } 242 : : 243 : : /******************************************************************************* 244 : : * 245 : : * FUNCTION: acpi_ex_system_reset_event 246 : : * 247 : : * PARAMETERS: obj_desc - The object descriptor for this op 248 : : * 249 : : * RETURN: Status 250 : : * 251 : : * DESCRIPTION: Reset an event to a known state. 252 : : * 253 : : ******************************************************************************/ 254 : : 255 : 0 : acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc) 256 : : { 257 : 0 : acpi_status status = AE_OK; 258 : 0 : acpi_semaphore temp_semaphore; 259 : : 260 : 0 : ACPI_FUNCTION_ENTRY(); 261 : : 262 : : /* 263 : : * We are going to simply delete the existing semaphore and 264 : : * create a new one! 265 : : */ 266 : 0 : status = 267 : 0 : acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore); 268 [ # # ]: 0 : if (ACPI_SUCCESS(status)) { 269 : 0 : (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore); 270 : 0 : obj_desc->event.os_semaphore = temp_semaphore; 271 : : } 272 : : 273 : 0 : return (status); 274 : : }