diff options
Diffstat (limited to 'drivers/acpi/acpica/evregion.c')
-rw-r--r-- | drivers/acpi/acpica/evregion.c | 63 |
1 files changed, 22 insertions, 41 deletions
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 6555e350fc1f..cea14d6fc76c 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -54,7 +54,8 @@ extern u8 acpi_gbl_default_address_spaces[]; | |||
54 | 54 | ||
55 | /* Local prototypes */ | 55 | /* Local prototypes */ |
56 | 56 | ||
57 | static void acpi_ev_orphan_ec_reg_method(void); | 57 | static void |
58 | acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node); | ||
58 | 59 | ||
59 | static acpi_status | 60 | static acpi_status |
60 | acpi_ev_reg_run(acpi_handle obj_handle, | 61 | acpi_ev_reg_run(acpi_handle obj_handle, |
@@ -532,7 +533,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
532 | } | 533 | } |
533 | 534 | ||
534 | info->prefix_node = region_obj2->extra.method_REG; | 535 | info->prefix_node = region_obj2->extra.method_REG; |
535 | info->pathname = NULL; | 536 | info->relative_pathname = NULL; |
536 | info->parameters = args; | 537 | info->parameters = args; |
537 | info->flags = ACPI_IGNORE_RETURN_VALUE; | 538 | info->flags = ACPI_IGNORE_RETURN_VALUE; |
538 | 539 | ||
@@ -612,7 +613,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, | |||
612 | /* Special case for EC: handle "orphan" _REG methods with no region */ | 613 | /* Special case for EC: handle "orphan" _REG methods with no region */ |
613 | 614 | ||
614 | if (space_id == ACPI_ADR_SPACE_EC) { | 615 | if (space_id == ACPI_ADR_SPACE_EC) { |
615 | acpi_ev_orphan_ec_reg_method(); | 616 | acpi_ev_orphan_ec_reg_method(node); |
616 | } | 617 | } |
617 | 618 | ||
618 | return_ACPI_STATUS(status); | 619 | return_ACPI_STATUS(status); |
@@ -681,7 +682,7 @@ acpi_ev_reg_run(acpi_handle obj_handle, | |||
681 | * | 682 | * |
682 | * FUNCTION: acpi_ev_orphan_ec_reg_method | 683 | * FUNCTION: acpi_ev_orphan_ec_reg_method |
683 | * | 684 | * |
684 | * PARAMETERS: None | 685 | * PARAMETERS: ec_device_node - Namespace node for an EC device |
685 | * | 686 | * |
686 | * RETURN: None | 687 | * RETURN: None |
687 | * | 688 | * |
@@ -693,37 +694,27 @@ acpi_ev_reg_run(acpi_handle obj_handle, | |||
693 | * detected by providing a _REG method object underneath the | 694 | * detected by providing a _REG method object underneath the |
694 | * Embedded Controller device." | 695 | * Embedded Controller device." |
695 | * | 696 | * |
696 | * To quickly access the EC device, we use the EC_ID that appears | 697 | * To quickly access the EC device, we use the ec_device_node used |
697 | * within the ECDT. Otherwise, we would need to perform a time- | 698 | * during EC handler installation. Otherwise, we would need to |
698 | * consuming namespace walk, executing _HID methods to find the | 699 | * perform a time consuming namespace walk, executing _HID |
699 | * EC device. | 700 | * methods to find the EC device. |
701 | * | ||
702 | * MUTEX: Assumes the namespace is locked | ||
700 | * | 703 | * |
701 | ******************************************************************************/ | 704 | ******************************************************************************/ |
702 | 705 | ||
703 | static void acpi_ev_orphan_ec_reg_method(void) | 706 | static void |
707 | acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) | ||
704 | { | 708 | { |
705 | struct acpi_table_ecdt *table; | 709 | acpi_handle reg_method; |
710 | struct acpi_namespace_node *next_node; | ||
706 | acpi_status status; | 711 | acpi_status status; |
707 | struct acpi_object_list args; | 712 | struct acpi_object_list args; |
708 | union acpi_object objects[2]; | 713 | union acpi_object objects[2]; |
709 | struct acpi_namespace_node *ec_device_node; | ||
710 | struct acpi_namespace_node *reg_method; | ||
711 | struct acpi_namespace_node *next_node; | ||
712 | 714 | ||
713 | ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method); | 715 | ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method); |
714 | 716 | ||
715 | /* Get the ECDT (if present in system) */ | 717 | if (!ec_device_node) { |
716 | |||
717 | status = acpi_get_table(ACPI_SIG_ECDT, 0, | ||
718 | ACPI_CAST_INDIRECT_PTR(struct acpi_table_header, | ||
719 | &table)); | ||
720 | if (ACPI_FAILURE(status)) { | ||
721 | return_VOID; | ||
722 | } | ||
723 | |||
724 | /* We need a valid EC_ID string */ | ||
725 | |||
726 | if (!(*table->id)) { | ||
727 | return_VOID; | 718 | return_VOID; |
728 | } | 719 | } |
729 | 720 | ||
@@ -731,22 +722,11 @@ static void acpi_ev_orphan_ec_reg_method(void) | |||
731 | 722 | ||
732 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 723 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
733 | 724 | ||
734 | /* Get a handle to the EC device referenced in the ECDT */ | ||
735 | |||
736 | status = acpi_get_handle(NULL, | ||
737 | ACPI_CAST_PTR(char, table->id), | ||
738 | ACPI_CAST_PTR(acpi_handle, &ec_device_node)); | ||
739 | if (ACPI_FAILURE(status)) { | ||
740 | goto exit; | ||
741 | } | ||
742 | |||
743 | /* Get a handle to a _REG method immediately under the EC device */ | 725 | /* Get a handle to a _REG method immediately under the EC device */ |
744 | 726 | ||
745 | status = acpi_get_handle(ec_device_node, | 727 | status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, ®_method); |
746 | METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle, | ||
747 | ®_method)); | ||
748 | if (ACPI_FAILURE(status)) { | 728 | if (ACPI_FAILURE(status)) { |
749 | goto exit; | 729 | goto exit; /* There is no _REG method present */ |
750 | } | 730 | } |
751 | 731 | ||
752 | /* | 732 | /* |
@@ -754,19 +734,20 @@ static void acpi_ev_orphan_ec_reg_method(void) | |||
754 | * this scope with the Embedded Controller space ID. Otherwise, it | 734 | * this scope with the Embedded Controller space ID. Otherwise, it |
755 | * will already have been executed. Note, this allows for Regions | 735 | * will already have been executed. Note, this allows for Regions |
756 | * with other space IDs to be present; but the code below will then | 736 | * with other space IDs to be present; but the code below will then |
757 | * execute the _REG method with the EC space ID argument. | 737 | * execute the _REG method with the embedded_control space_ID argument. |
758 | */ | 738 | */ |
759 | next_node = acpi_ns_get_next_node(ec_device_node, NULL); | 739 | next_node = acpi_ns_get_next_node(ec_device_node, NULL); |
760 | while (next_node) { | 740 | while (next_node) { |
761 | if ((next_node->type == ACPI_TYPE_REGION) && | 741 | if ((next_node->type == ACPI_TYPE_REGION) && |
762 | (next_node->object) && | 742 | (next_node->object) && |
763 | (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) { | 743 | (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) { |
764 | goto exit; /* Do not execute _REG */ | 744 | goto exit; /* Do not execute the _REG */ |
765 | } | 745 | } |
746 | |||
766 | next_node = acpi_ns_get_next_node(ec_device_node, next_node); | 747 | next_node = acpi_ns_get_next_node(ec_device_node, next_node); |
767 | } | 748 | } |
768 | 749 | ||
769 | /* Evaluate the _REG(EC,Connect) method */ | 750 | /* Evaluate the _REG(embedded_control,Connect) method */ |
770 | 751 | ||
771 | args.count = 2; | 752 | args.count = 2; |
772 | args.pointer = objects; | 753 | args.pointer = objects; |