aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evgpeblk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/evgpeblk.c')
-rw-r--r--drivers/acpi/acpica/evgpeblk.c143
1 files changed, 76 insertions, 67 deletions
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index fa47e3522abe..85ded1f2540d 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -51,7 +51,7 @@ ACPI_MODULE_NAME("evgpeblk")
51 51
52/* Local prototypes */ 52/* Local prototypes */
53static acpi_status 53static acpi_status
54acpi_ev_save_method_info(acpi_handle obj_handle, 54acpi_ev_match_gpe_method(acpi_handle obj_handle,
55 u32 level, void *obj_desc, void **return_value); 55 u32 level, void *obj_desc, void **return_value);
56 56
57static acpi_status 57static acpi_status
@@ -104,9 +104,7 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
104 104
105 while (gpe_block) { 105 while (gpe_block) {
106 if ((&gpe_block->event_info[0] <= gpe_event_info) && 106 if ((&gpe_block->event_info[0] <= gpe_event_info) &&
107 (&gpe_block->event_info[((acpi_size) 107 (&gpe_block->event_info[gpe_block->gpe_count] >
108 gpe_block->
109 register_count) * 8] >
110 gpe_event_info)) { 108 gpe_event_info)) {
111 return (TRUE); 109 return (TRUE);
112 } 110 }
@@ -229,7 +227,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
229 227
230/******************************************************************************* 228/*******************************************************************************
231 * 229 *
232 * FUNCTION: acpi_ev_save_method_info 230 * FUNCTION: acpi_ev_match_gpe_method
233 * 231 *
234 * PARAMETERS: Callback from walk_namespace 232 * PARAMETERS: Callback from walk_namespace
235 * 233 *
@@ -241,8 +239,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
241 * information for quick lookup during GPE dispatch 239 * information for quick lookup during GPE dispatch
242 * 240 *
243 * The name of each GPE control method is of the form: 241 * The name of each GPE control method is of the form:
244 * "_Lxx" or "_Exx" 242 * "_Lxx" or "_Exx", where:
245 * Where:
246 * L - means that the GPE is level triggered 243 * L - means that the GPE is level triggered
247 * E - means that the GPE is edge triggered 244 * E - means that the GPE is edge triggered
248 * xx - is the GPE number [in HEX] 245 * xx - is the GPE number [in HEX]
@@ -250,9 +247,11 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
250 ******************************************************************************/ 247 ******************************************************************************/
251 248
252static acpi_status 249static acpi_status
253acpi_ev_save_method_info(acpi_handle obj_handle, 250acpi_ev_match_gpe_method(acpi_handle obj_handle,
254 u32 level, void *obj_desc, void **return_value) 251 u32 level, void *obj_desc, void **return_value)
255{ 252{
253 struct acpi_namespace_node *method_node =
254 ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
256 struct acpi_gpe_block_info *gpe_block = (void *)obj_desc; 255 struct acpi_gpe_block_info *gpe_block = (void *)obj_desc;
257 struct acpi_gpe_event_info *gpe_event_info; 256 struct acpi_gpe_event_info *gpe_event_info;
258 u32 gpe_number; 257 u32 gpe_number;
@@ -262,21 +261,25 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
262 ACPI_FUNCTION_TRACE(ev_save_method_info); 261 ACPI_FUNCTION_TRACE(ev_save_method_info);
263 262
264 /* 263 /*
265 * _Lxx and _Exx GPE method support 264 * Match and decode the _Lxx and _Exx GPE method names
266 * 265 *
267 * 1) Extract the name from the object and convert to a string 266 * 1) Extract the method name and null terminate it
268 */ 267 */
269 ACPI_MOVE_32_TO_32(name, 268 ACPI_MOVE_32_TO_32(name, &method_node->name.integer);
270 &((struct acpi_namespace_node *)obj_handle)->name.
271 integer);
272 name[ACPI_NAME_SIZE] = 0; 269 name[ACPI_NAME_SIZE] = 0;
273 270
271 /* 2) Name must begin with an underscore */
272
273 if (name[0] != '_') {
274 return_ACPI_STATUS(AE_OK); /* Ignore this method */
275 }
276
274 /* 277 /*
275 * 2) Edge/Level determination is based on the 2nd character 278 * 3) Edge/Level determination is based on the 2nd character
276 * of the method name 279 * of the method name
277 * 280 *
278 * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE 281 * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
279 * if a _PRW object is found that points to this GPE. 282 * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
280 */ 283 */
281 switch (name[1]) { 284 switch (name[1]) {
282 case 'L': 285 case 'L':
@@ -288,7 +291,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
288 break; 291 break;
289 292
290 default: 293 default:
291 /* Unknown method type, just ignore it! */ 294 /* Unknown method type, just ignore it */
292 295
293 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, 296 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
294 "Ignoring unknown GPE method type: %s " 297 "Ignoring unknown GPE method type: %s "
@@ -296,7 +299,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
296 return_ACPI_STATUS(AE_OK); 299 return_ACPI_STATUS(AE_OK);
297 } 300 }
298 301
299 /* Convert the last two characters of the name to the GPE Number */ 302 /* 4) The last two characters of the name are the hex GPE Number */
300 303
301 gpe_number = ACPI_STRTOUL(&name[2], NULL, 16); 304 gpe_number = ACPI_STRTOUL(&name[2], NULL, 16);
302 if (gpe_number == ACPI_UINT32_MAX) { 305 if (gpe_number == ACPI_UINT32_MAX) {
@@ -311,28 +314,22 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
311 314
312 /* Ensure that we have a valid GPE number for this GPE block */ 315 /* Ensure that we have a valid GPE number for this GPE block */
313 316
314 if ((gpe_number < gpe_block->block_base_number) || 317 gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
315 (gpe_number >= (gpe_block->block_base_number + 318 if (!gpe_event_info) {
316 (gpe_block->register_count * 8)))) {
317 /* 319 /*
318 * Not valid for this GPE block, just ignore it. However, it may be 320 * This gpe_number is not valid for this GPE block, just ignore it.
319 * valid for a different GPE block, since GPE0 and GPE1 methods both 321 * However, it may be valid for a different GPE block, since GPE0
320 * appear under \_GPE. 322 * and GPE1 methods both appear under \_GPE.
321 */ 323 */
322 return_ACPI_STATUS(AE_OK); 324 return_ACPI_STATUS(AE_OK);
323 } 325 }
324 326
325 /* 327 /*
326 * Now we can add this information to the gpe_event_info block for use 328 * Add the GPE information from above to the gpe_event_info block for
327 * during dispatch of this GPE. 329 * use during dispatch of this GPE.
328 */ 330 */
329 gpe_event_info = 331 gpe_event_info->flags = (u8)(type | ACPI_GPE_DISPATCH_METHOD);
330 &gpe_block->event_info[gpe_number - gpe_block->block_base_number]; 332 gpe_event_info->dispatch.method_node = method_node;
331
332 gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD);
333
334 gpe_event_info->dispatch.method_node =
335 (struct acpi_namespace_node *)obj_handle;
336 333
337 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, 334 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
338 "Registered GPE method %s as GPE number 0x%.2X\n", 335 "Registered GPE method %s as GPE number 0x%.2X\n",
@@ -351,7 +348,7 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
351 * 348 *
352 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a 349 * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
353 * Device. Run the _PRW method. If present, extract the GPE 350 * Device. Run the _PRW method. If present, extract the GPE
354 * number and mark the GPE as a WAKE GPE. 351 * number and mark the GPE as a CAN_WAKE GPE.
355 * 352 *
356 ******************************************************************************/ 353 ******************************************************************************/
357 354
@@ -377,7 +374,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
377 ACPI_BTYPE_PACKAGE, &pkg_desc); 374 ACPI_BTYPE_PACKAGE, &pkg_desc);
378 if (ACPI_FAILURE(status)) { 375 if (ACPI_FAILURE(status)) {
379 376
380 /* Ignore all errors from _PRW, we don't want to abort the subsystem */ 377 /* Ignore all errors from _PRW, we don't want to abort the walk */
381 378
382 return_ACPI_STATUS(AE_OK); 379 return_ACPI_STATUS(AE_OK);
383 } 380 }
@@ -439,13 +436,13 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
439 * 2) The GPE index(number) is within the range of the Gpe Block 436 * 2) The GPE index(number) is within the range of the Gpe Block
440 * associated with the GPE device. 437 * associated with the GPE device.
441 */ 438 */
442 if ((gpe_device == target_gpe_device) && 439 if (gpe_device != target_gpe_device) {
443 (gpe_number >= gpe_block->block_base_number) && 440 goto cleanup;
444 (gpe_number < gpe_block->block_base_number + 441 }
445 (gpe_block->register_count * 8))) { 442
446 gpe_event_info = &gpe_block->event_info[gpe_number - 443 gpe_event_info = acpi_ev_low_get_gpe_info(gpe_number, gpe_block);
447 gpe_block-> 444 if (gpe_event_info) {
448 block_base_number]; 445 /* This GPE can wake the system */
449 446
450 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; 447 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
451 } 448 }
@@ -705,8 +702,7 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
705 acpi_os_release_lock(acpi_gbl_gpe_lock, flags); 702 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
706 } 703 }
707 704
708 acpi_current_gpe_count -= 705 acpi_current_gpe_count -= gpe_block->gpe_count;
709 gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH;
710 706
711 /* Free the gpe_block */ 707 /* Free the gpe_block */
712 708
@@ -760,9 +756,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
760 * Allocate the GPE event_info block. There are eight distinct GPEs 756 * Allocate the GPE event_info block. There are eight distinct GPEs
761 * per register. Initialization to zeros is sufficient. 757 * per register. Initialization to zeros is sufficient.
762 */ 758 */
763 gpe_event_info = ACPI_ALLOCATE_ZEROED(((acpi_size) gpe_block-> 759 gpe_event_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block->gpe_count *
764 register_count *
765 ACPI_GPE_REGISTER_WIDTH) *
766 sizeof(struct 760 sizeof(struct
767 acpi_gpe_event_info)); 761 acpi_gpe_event_info));
768 if (!gpe_event_info) { 762 if (!gpe_event_info) {
@@ -897,6 +891,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
897 /* Initialize the new GPE block */ 891 /* Initialize the new GPE block */
898 892
899 gpe_block->node = gpe_device; 893 gpe_block->node = gpe_device;
894 gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
900 gpe_block->register_count = register_count; 895 gpe_block->register_count = register_count;
901 gpe_block->block_base_number = gpe_block_base_number; 896 gpe_block->block_base_number = gpe_block_base_number;
902 897
@@ -925,7 +920,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
925 920
926 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, 921 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
927 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, 922 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
928 acpi_ev_save_method_info, NULL, 923 acpi_ev_match_gpe_method, NULL,
929 gpe_block, NULL); 924 gpe_block, NULL);
930 925
931 /* Return the new block */ 926 /* Return the new block */
@@ -938,14 +933,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
938 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", 933 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
939 (u32) gpe_block->block_base_number, 934 (u32) gpe_block->block_base_number,
940 (u32) (gpe_block->block_base_number + 935 (u32) (gpe_block->block_base_number +
941 ((gpe_block->register_count * 936 (gpe_block->gpe_count - 1)),
942 ACPI_GPE_REGISTER_WIDTH) - 1)),
943 gpe_device->name.ascii, gpe_block->register_count, 937 gpe_device->name.ascii, gpe_block->register_count,
944 interrupt_number)); 938 interrupt_number));
945 939
946 /* Update global count of currently available GPEs */ 940 /* Update global count of currently available GPEs */
947 941
948 acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH; 942 acpi_current_gpe_count += gpe_block->gpe_count;
949 return_ACPI_STATUS(AE_OK); 943 return_ACPI_STATUS(AE_OK);
950} 944}
951 945
@@ -969,10 +963,13 @@ acpi_status
969acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, 963acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
970 struct acpi_gpe_block_info *gpe_block) 964 struct acpi_gpe_block_info *gpe_block)
971{ 965{
966 acpi_status status;
972 struct acpi_gpe_event_info *gpe_event_info; 967 struct acpi_gpe_event_info *gpe_event_info;
973 struct acpi_gpe_walk_info gpe_info; 968 struct acpi_gpe_walk_info gpe_info;
974 u32 wake_gpe_count; 969 u32 wake_gpe_count;
975 u32 gpe_enabled_count; 970 u32 gpe_enabled_count;
971 u32 gpe_index;
972 u32 gpe_number;
976 u32 i; 973 u32 i;
977 u32 j; 974 u32 j;
978 975
@@ -998,50 +995,62 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
998 gpe_info.gpe_block = gpe_block; 995 gpe_info.gpe_block = gpe_block;
999 gpe_info.gpe_device = gpe_device; 996 gpe_info.gpe_device = gpe_device;
1000 997
1001 acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 998 status = acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1002 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 999 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1003 acpi_ev_match_prw_and_gpe, NULL, 1000 acpi_ev_match_prw_and_gpe, NULL,
1004 &gpe_info, NULL); 1001 &gpe_info, NULL);
1002 if (ACPI_FAILURE(status)) {
1003 ACPI_EXCEPTION((AE_INFO, status,
1004 "While executing _PRW methods"));
1005 }
1005 } 1006 }
1006 1007
1007 /* 1008 /*
1008 * Enable all GPEs that have a corresponding method and aren't 1009 * Enable all GPEs that have a corresponding method and are not
1009 * capable of generating wakeups. Any other GPEs within this block 1010 * capable of generating wakeups. Any other GPEs within this block
1010 * must be enabled via the acpi_enable_gpe() interface. 1011 * must be enabled via the acpi_enable_gpe interface.
1011 */ 1012 */
1012 wake_gpe_count = 0; 1013 wake_gpe_count = 0;
1013 gpe_enabled_count = 0; 1014 gpe_enabled_count = 0;
1014 if (gpe_device == acpi_gbl_fadt_gpe_device) 1015
1016 if (gpe_device == acpi_gbl_fadt_gpe_device) {
1015 gpe_device = NULL; 1017 gpe_device = NULL;
1018 }
1016 1019
1017 for (i = 0; i < gpe_block->register_count; i++) { 1020 for (i = 0; i < gpe_block->register_count; i++) {
1018 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { 1021 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
1019 acpi_status status;
1020 acpi_size gpe_index;
1021 int gpe_number;
1022 1022
1023 /* Get the info block for this particular GPE */ 1023 /* Get the info block for this particular GPE */
1024 gpe_index = (acpi_size)i * ACPI_GPE_REGISTER_WIDTH + j; 1024
1025 gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
1025 gpe_event_info = &gpe_block->event_info[gpe_index]; 1026 gpe_event_info = &gpe_block->event_info[gpe_index];
1026 1027
1027 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { 1028 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
1028 wake_gpe_count++; 1029 wake_gpe_count++;
1029 if (acpi_gbl_leave_wake_gpes_disabled) 1030 if (acpi_gbl_leave_wake_gpes_disabled) {
1030 continue; 1031 continue;
1032 }
1031 } 1033 }
1032 1034
1033 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) 1035 /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
1036
1037 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
1034 continue; 1038 continue;
1039 }
1040
1041 /* Enable this GPE */
1035 1042
1036 gpe_number = gpe_index + gpe_block->block_base_number; 1043 gpe_number = gpe_index + gpe_block->block_base_number;
1037 status = acpi_enable_gpe(gpe_device, gpe_number, 1044 status = acpi_enable_gpe(gpe_device, gpe_number,
1038 ACPI_GPE_TYPE_RUNTIME); 1045 ACPI_GPE_TYPE_RUNTIME);
1039 if (ACPI_FAILURE(status)) 1046 if (ACPI_FAILURE(status)) {
1040 ACPI_ERROR((AE_INFO, 1047 ACPI_EXCEPTION((AE_INFO, status,
1041 "Failed to enable GPE %02X\n", 1048 "Could not enable GPE 0x%02X",
1042 gpe_number)); 1049 gpe_number));
1043 else 1050 continue;
1044 gpe_enabled_count++; 1051 }
1052
1053 gpe_enabled_count++;
1045 } 1054 }
1046 } 1055 }
1047 1056