diff options
Diffstat (limited to 'drivers/acpi/acpica/evgpeblk.c')
-rw-r--r-- | drivers/acpi/acpica/evgpeblk.c | 66 |
1 files changed, 32 insertions, 34 deletions
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 85445fb5844e..ca2c41a53311 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -5,7 +5,7 @@ | |||
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * Copyright (C) 2000 - 2010, Intel Corp. | 8 | * Copyright (C) 2000 - 2011, Intel Corp. |
9 | * All rights reserved. | 9 | * All rights reserved. |
10 | * | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
@@ -361,6 +361,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
361 | 361 | ||
362 | gpe_block->node = gpe_device; | 362 | gpe_block->node = gpe_device; |
363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); | 363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); |
364 | gpe_block->initialized = FALSE; | ||
364 | gpe_block->register_count = register_count; | 365 | gpe_block->register_count = register_count; |
365 | gpe_block->block_base_number = gpe_block_base_number; | 366 | gpe_block->block_base_number = gpe_block_base_number; |
366 | 367 | ||
@@ -385,11 +386,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
385 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
386 | } | 387 | } |
387 | 388 | ||
389 | acpi_gbl_all_gpes_initialized = FALSE; | ||
390 | |||
388 | /* Find all GPE methods (_Lxx or_Exx) for this block */ | 391 | /* Find all GPE methods (_Lxx or_Exx) for this block */ |
389 | 392 | ||
390 | walk_info.gpe_block = gpe_block; | 393 | walk_info.gpe_block = gpe_block; |
391 | walk_info.gpe_device = gpe_device; | 394 | walk_info.gpe_device = gpe_device; |
392 | walk_info.enable_this_gpe = FALSE; | ||
393 | walk_info.execute_by_owner_id = FALSE; | 395 | walk_info.execute_by_owner_id = FALSE; |
394 | 396 | ||
395 | status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, | 397 | status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, |
@@ -421,48 +423,45 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
421 | * | 423 | * |
422 | * FUNCTION: acpi_ev_initialize_gpe_block | 424 | * FUNCTION: acpi_ev_initialize_gpe_block |
423 | * | 425 | * |
424 | * PARAMETERS: gpe_device - Handle to the parent GPE block | 426 | * PARAMETERS: acpi_gpe_callback |
425 | * gpe_block - Gpe Block info | ||
426 | * | 427 | * |
427 | * RETURN: Status | 428 | * RETURN: Status |
428 | * | 429 | * |
429 | * DESCRIPTION: Initialize and enable a GPE block. First find and run any | 430 | * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have |
430 | * _PRT methods associated with the block, then enable the | 431 | * associated methods. |
431 | * appropriate GPEs. | ||
432 | * Note: Assumes namespace is locked. | 432 | * Note: Assumes namespace is locked. |
433 | * | 433 | * |
434 | ******************************************************************************/ | 434 | ******************************************************************************/ |
435 | 435 | ||
436 | acpi_status | 436 | acpi_status |
437 | acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | 437 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
438 | struct acpi_gpe_block_info *gpe_block) | 438 | struct acpi_gpe_block_info *gpe_block, |
439 | void *ignored) | ||
439 | { | 440 | { |
440 | acpi_status status; | 441 | acpi_status status; |
441 | struct acpi_gpe_event_info *gpe_event_info; | 442 | struct acpi_gpe_event_info *gpe_event_info; |
442 | u32 gpe_enabled_count; | 443 | u32 gpe_enabled_count; |
443 | u32 gpe_index; | 444 | u32 gpe_index; |
444 | u32 gpe_number; | ||
445 | u32 i; | 445 | u32 i; |
446 | u32 j; | 446 | u32 j; |
447 | 447 | ||
448 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); | 448 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); |
449 | 449 | ||
450 | /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ | 450 | /* |
451 | 451 | * Ignore a null GPE block (e.g., if no GPE block 1 exists), and | |
452 | if (!gpe_block) { | 452 | * any GPE blocks that have been initialized already. |
453 | */ | ||
454 | if (!gpe_block || gpe_block->initialized) { | ||
453 | return_ACPI_STATUS(AE_OK); | 455 | return_ACPI_STATUS(AE_OK); |
454 | } | 456 | } |
455 | 457 | ||
456 | /* | 458 | /* |
457 | * Enable all GPEs that have a corresponding method. Any other GPEs | 459 | * Enable all GPEs that have a corresponding method and have the |
458 | * within this block must be enabled via the acpi_enable_gpe interface. | 460 | * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block |
461 | * must be enabled via the acpi_enable_gpe() interface. | ||
459 | */ | 462 | */ |
460 | gpe_enabled_count = 0; | 463 | gpe_enabled_count = 0; |
461 | 464 | ||
462 | if (gpe_device == acpi_gbl_fadt_gpe_device) { | ||
463 | gpe_device = NULL; | ||
464 | } | ||
465 | |||
466 | for (i = 0; i < gpe_block->register_count; i++) { | 465 | for (i = 0; i < gpe_block->register_count; i++) { |
467 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { | 466 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { |
468 | 467 | ||
@@ -470,27 +469,24 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
470 | 469 | ||
471 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; | 470 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; |
472 | gpe_event_info = &gpe_block->event_info[gpe_index]; | 471 | gpe_event_info = &gpe_block->event_info[gpe_index]; |
473 | gpe_number = gpe_index + gpe_block->block_base_number; | ||
474 | |||
475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ | ||
476 | |||
477 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { | ||
478 | continue; | ||
479 | } | ||
480 | 472 | ||
481 | /* | 473 | /* |
482 | * If the GPE has already been enabled for runtime | 474 | * Ignore GPEs that have no corresponding _Lxx/_Exx method |
483 | * signaling, make sure it remains enabled, but do not | 475 | * and GPEs that are used to wake the system |
484 | * increment its reference counter. | ||
485 | */ | 476 | */ |
486 | status = gpe_event_info->runtime_count ? | 477 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == |
487 | acpi_ev_enable_gpe(gpe_event_info) : | 478 | ACPI_GPE_DISPATCH_NONE) |
488 | acpi_enable_gpe(gpe_device, gpe_number); | 479 | || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) |
480 | == ACPI_GPE_DISPATCH_HANDLER) | ||
481 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
482 | continue; | ||
483 | } | ||
489 | 484 | ||
485 | status = acpi_ev_add_gpe_reference(gpe_event_info); | ||
490 | if (ACPI_FAILURE(status)) { | 486 | if (ACPI_FAILURE(status)) { |
491 | ACPI_EXCEPTION((AE_INFO, status, | 487 | ACPI_EXCEPTION((AE_INFO, status, |
492 | "Could not enable GPE 0x%02X", | 488 | "Could not enable GPE 0x%02X", |
493 | gpe_number)); | 489 | gpe_index + gpe_block->block_base_number)); |
494 | continue; | 490 | continue; |
495 | } | 491 | } |
496 | 492 | ||
@@ -504,5 +500,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
504 | gpe_enabled_count)); | 500 | gpe_enabled_count)); |
505 | } | 501 | } |
506 | 502 | ||
503 | gpe_block->initialized = TRUE; | ||
504 | |||
507 | return_ACPI_STATUS(AE_OK); | 505 | return_ACPI_STATUS(AE_OK); |
508 | } | 506 | } |