1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable 5 * 6 * Copyright (C) 2000 - 2023, Intel Corp. 7 * 8 *****************************************************************************/ 9 10 #define EXPORT_ACPI_INTERFACES 11 12 #include <acpi/acpi.h> 13 #include "accommon.h" 14 #include "actables.h" 15 16 #define _COMPONENT ACPI_EVENTS 17 ACPI_MODULE_NAME("evxfevnt") 18 19 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 20 /******************************************************************************* 21 * 22 * FUNCTION: acpi_enable 23 * 24 * PARAMETERS: None 25 * 26 * RETURN: Status 27 * 28 * DESCRIPTION: Transfers the system into ACPI mode. 29 * 30 ******************************************************************************/ 31 acpi_status acpi_enable(void) 32 { 33 acpi_status status; 34 int retry; 35 36 ACPI_FUNCTION_TRACE(acpi_enable); 37 38 /* ACPI tables must be present */ 39 40 if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) { 41 return_ACPI_STATUS(AE_NO_ACPI_TABLES); 42 } 43 44 /* If the Hardware Reduced flag is set, machine is always in acpi mode */ 45 46 if (acpi_gbl_reduced_hardware) { 47 return_ACPI_STATUS(AE_OK); 48 } 49 50 /* Check current mode */ 51 52 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 53 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 54 "System is already in ACPI mode\n")); 55 return_ACPI_STATUS(AE_OK); 56 } 57 58 /* Transition to ACPI mode */ 59 60 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); 61 if (ACPI_FAILURE(status)) { 62 ACPI_ERROR((AE_INFO, 63 "Could not transition to ACPI mode")); 64 return_ACPI_STATUS(status); 65 } 66 67 /* Sanity check that transition succeeded */ 68 69 for (retry = 0; retry < 30000; ++retry) { 70 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { 71 if (retry != 0) 72 ACPI_WARNING((AE_INFO, 73 "Platform took > %d00 usec to enter ACPI mode", retry)); 74 return_ACPI_STATUS(AE_OK); 75 } 76 acpi_os_stall(100); /* 100 usec */ 77 } 78 79 ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode")); 80 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 81 } 82 83 ACPI_EXPORT_SYMBOL(acpi_enable) 84 85 /******************************************************************************* 86 * 87 * FUNCTION: acpi_disable 88 * 89 * PARAMETERS: None 90 * 91 * RETURN: Status 92 * 93 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. 94 * 95 ******************************************************************************/ 96 acpi_status acpi_disable(void) 97 { 98 acpi_status status = AE_OK; 99 100 ACPI_FUNCTION_TRACE(acpi_disable); 101 102 /* If the Hardware Reduced flag is set, machine is always in acpi mode */ 103 104 if (acpi_gbl_reduced_hardware) { 105 return_ACPI_STATUS(AE_OK); 106 } 107 108 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { 109 ACPI_DEBUG_PRINT((ACPI_DB_INIT, 110 "System is already in legacy (non-ACPI) mode\n")); 111 } else { 112 /* Transition to LEGACY mode */ 113 114 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); 115 116 if (ACPI_FAILURE(status)) { 117 ACPI_ERROR((AE_INFO, 118 "Could not exit ACPI mode to legacy mode")); 119 return_ACPI_STATUS(status); 120 } 121 122 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); 123 } 124 125 return_ACPI_STATUS(status); 126 } 127 128 ACPI_EXPORT_SYMBOL(acpi_disable) 129 130 /******************************************************************************* 131 * 132 * FUNCTION: acpi_enable_event 133 * 134 * PARAMETERS: event - The fixed eventto be enabled 135 * flags - Reserved 136 * 137 * RETURN: Status 138 * 139 * DESCRIPTION: Enable an ACPI event (fixed) 140 * 141 ******************************************************************************/ 142 acpi_status acpi_enable_event(u32 event, u32 flags) 143 { 144 acpi_status status = AE_OK; 145 u32 value; 146 147 ACPI_FUNCTION_TRACE(acpi_enable_event); 148 149 /* If Hardware Reduced flag is set, there are no fixed events */ 150 151 if (acpi_gbl_reduced_hardware) { 152 return_ACPI_STATUS(AE_OK); 153 } 154 155 /* Decode the Fixed Event */ 156 157 if (event > ACPI_EVENT_MAX) { 158 return_ACPI_STATUS(AE_BAD_PARAMETER); 159 } 160 161 /* 162 * Enable the requested fixed event (by writing a one to the enable 163 * register bit) 164 */ 165 status = 166 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 167 enable_register_id, ACPI_ENABLE_EVENT); 168 if (ACPI_FAILURE(status)) { 169 return_ACPI_STATUS(status); 170 } 171 172 /* Make sure that the hardware responded */ 173 174 status = 175 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 176 enable_register_id, &value); 177 if (ACPI_FAILURE(status)) { 178 return_ACPI_STATUS(status); 179 } 180 181 if (value != 1) { 182 ACPI_ERROR((AE_INFO, 183 "Could not enable %s event", 184 acpi_ut_get_event_name(event))); 185 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 186 } 187 188 return_ACPI_STATUS(status); 189 } 190 191 ACPI_EXPORT_SYMBOL(acpi_enable_event) 192 193 /******************************************************************************* 194 * 195 * FUNCTION: acpi_disable_event 196 * 197 * PARAMETERS: event - The fixed event to be disabled 198 * flags - Reserved 199 * 200 * RETURN: Status 201 * 202 * DESCRIPTION: Disable an ACPI event (fixed) 203 * 204 ******************************************************************************/ 205 acpi_status acpi_disable_event(u32 event, u32 flags) 206 { 207 acpi_status status = AE_OK; 208 u32 value; 209 210 ACPI_FUNCTION_TRACE(acpi_disable_event); 211 212 /* If Hardware Reduced flag is set, there are no fixed events */ 213 214 if (acpi_gbl_reduced_hardware) { 215 return_ACPI_STATUS(AE_OK); 216 } 217 218 /* Decode the Fixed Event */ 219 220 if (event > ACPI_EVENT_MAX) { 221 return_ACPI_STATUS(AE_BAD_PARAMETER); 222 } 223 224 /* 225 * Disable the requested fixed event (by writing a zero to the enable 226 * register bit) 227 */ 228 status = 229 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 230 enable_register_id, ACPI_DISABLE_EVENT); 231 if (ACPI_FAILURE(status)) { 232 return_ACPI_STATUS(status); 233 } 234 235 status = 236 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 237 enable_register_id, &value); 238 if (ACPI_FAILURE(status)) { 239 return_ACPI_STATUS(status); 240 } 241 242 if (value != 0) { 243 ACPI_ERROR((AE_INFO, 244 "Could not disable %s events", 245 acpi_ut_get_event_name(event))); 246 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); 247 } 248 249 return_ACPI_STATUS(status); 250 } 251 252 ACPI_EXPORT_SYMBOL(acpi_disable_event) 253 254 /******************************************************************************* 255 * 256 * FUNCTION: acpi_clear_event 257 * 258 * PARAMETERS: event - The fixed event to be cleared 259 * 260 * RETURN: Status 261 * 262 * DESCRIPTION: Clear an ACPI event (fixed) 263 * 264 ******************************************************************************/ 265 acpi_status acpi_clear_event(u32 event) 266 { 267 acpi_status status = AE_OK; 268 269 ACPI_FUNCTION_TRACE(acpi_clear_event); 270 271 /* If Hardware Reduced flag is set, there are no fixed events */ 272 273 if (acpi_gbl_reduced_hardware) { 274 return_ACPI_STATUS(AE_OK); 275 } 276 277 /* Decode the Fixed Event */ 278 279 if (event > ACPI_EVENT_MAX) { 280 return_ACPI_STATUS(AE_BAD_PARAMETER); 281 } 282 283 /* 284 * Clear the requested fixed event (By writing a one to the status 285 * register bit) 286 */ 287 status = 288 acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. 289 status_register_id, ACPI_CLEAR_STATUS); 290 291 return_ACPI_STATUS(status); 292 } 293 294 ACPI_EXPORT_SYMBOL(acpi_clear_event) 295 296 /******************************************************************************* 297 * 298 * FUNCTION: acpi_get_event_status 299 * 300 * PARAMETERS: event - The fixed event 301 * event_status - Where the current status of the event will 302 * be returned 303 * 304 * RETURN: Status 305 * 306 * DESCRIPTION: Obtains and returns the current status of the event 307 * 308 ******************************************************************************/ 309 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) 310 { 311 acpi_status status; 312 acpi_event_status local_event_status = 0; 313 u32 in_byte; 314 315 ACPI_FUNCTION_TRACE(acpi_get_event_status); 316 317 if (!event_status) { 318 return_ACPI_STATUS(AE_BAD_PARAMETER); 319 } 320 321 /* Decode the Fixed Event */ 322 323 if (event > ACPI_EVENT_MAX) { 324 return_ACPI_STATUS(AE_BAD_PARAMETER); 325 } 326 327 /* Fixed event currently can be dispatched? */ 328 329 if (acpi_gbl_fixed_event_handlers[event].handler) { 330 local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; 331 } 332 333 /* Fixed event currently enabled? */ 334 335 status = 336 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 337 enable_register_id, &in_byte); 338 if (ACPI_FAILURE(status)) { 339 return_ACPI_STATUS(status); 340 } 341 342 if (in_byte) { 343 local_event_status |= 344 (ACPI_EVENT_FLAG_ENABLED | ACPI_EVENT_FLAG_ENABLE_SET); 345 } 346 347 /* Fixed event currently active? */ 348 349 status = 350 acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. 351 status_register_id, &in_byte); 352 if (ACPI_FAILURE(status)) { 353 return_ACPI_STATUS(status); 354 } 355 356 if (in_byte) { 357 local_event_status |= ACPI_EVENT_FLAG_STATUS_SET; 358 } 359 360 (*event_status) = local_event_status; 361 return_ACPI_STATUS(AE_OK); 362 } 363 364 ACPI_EXPORT_SYMBOL(acpi_get_event_status) 365 #endif /* !ACPI_REDUCED_HARDWARE */ 366