diff options
author | Bob Moore <robert.moore@intel.com> | 2008-12-29 20:45:17 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-12-31 01:10:24 -0500 |
commit | e97d6bf1a01b7403d98aea95731863aab2e84064 (patch) | |
tree | fd6dafb476e312424311425be96e07e5969f060f /drivers/acpi/events | |
parent | c1e3523ccbeca312e11557d2a75f90632a2fb5c7 (diff) |
ACPICA: New: acpi_get_gpe_device interface
This function maps an input GPE index to a GPE block device. Also
Added acpi_current_gpe_count to track the current number of GPEs
that are being managed by the ACPICA core (both FADT-based GPEs
and the GPEs contained in GPE block devices.)
Modify drivers/acpi/system.c to use these 2 new interfaces
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/events')
-rw-r--r-- | drivers/acpi/events/evgpeblk.c | 25 | ||||
-rw-r--r-- | drivers/acpi/events/evmisc.c | 4 | ||||
-rw-r--r-- | drivers/acpi/events/evxfevnt.c | 93 |
3 files changed, 115 insertions, 7 deletions
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 7537cda54050..2872be2b9be5 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c | |||
@@ -124,6 +124,7 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) | |||
124 | * FUNCTION: acpi_ev_walk_gpe_list | 124 | * FUNCTION: acpi_ev_walk_gpe_list |
125 | * | 125 | * |
126 | * PARAMETERS: gpe_walk_callback - Routine called for each GPE block | 126 | * PARAMETERS: gpe_walk_callback - Routine called for each GPE block |
127 | * Context - Value passed to callback | ||
127 | * | 128 | * |
128 | * RETURN: Status | 129 | * RETURN: Status |
129 | * | 130 | * |
@@ -131,7 +132,8 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) | |||
131 | * | 132 | * |
132 | ******************************************************************************/ | 133 | ******************************************************************************/ |
133 | 134 | ||
134 | acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) | 135 | acpi_status |
136 | acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context) | ||
135 | { | 137 | { |
136 | struct acpi_gpe_block_info *gpe_block; | 138 | struct acpi_gpe_block_info *gpe_block; |
137 | struct acpi_gpe_xrupt_info *gpe_xrupt_info; | 139 | struct acpi_gpe_xrupt_info *gpe_xrupt_info; |
@@ -154,8 +156,13 @@ acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) | |||
154 | 156 | ||
155 | /* One callback per GPE block */ | 157 | /* One callback per GPE block */ |
156 | 158 | ||
157 | status = gpe_walk_callback(gpe_xrupt_info, gpe_block); | 159 | status = |
160 | gpe_walk_callback(gpe_xrupt_info, gpe_block, | ||
161 | context); | ||
158 | if (ACPI_FAILURE(status)) { | 162 | if (ACPI_FAILURE(status)) { |
163 | if (status == AE_CTRL_END) { /* Callback abort */ | ||
164 | status = AE_OK; | ||
165 | } | ||
159 | goto unlock_and_exit; | 166 | goto unlock_and_exit; |
160 | } | 167 | } |
161 | 168 | ||
@@ -186,7 +193,8 @@ acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) | |||
186 | 193 | ||
187 | acpi_status | 194 | acpi_status |
188 | acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 195 | acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
189 | struct acpi_gpe_block_info *gpe_block) | 196 | struct acpi_gpe_block_info *gpe_block, |
197 | void *context) | ||
190 | { | 198 | { |
191 | struct acpi_gpe_event_info *gpe_event_info; | 199 | struct acpi_gpe_event_info *gpe_event_info; |
192 | u32 i; | 200 | u32 i; |
@@ -690,7 +698,8 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) | |||
690 | 698 | ||
691 | /* Disable all GPEs in this block */ | 699 | /* Disable all GPEs in this block */ |
692 | 700 | ||
693 | status = acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block); | 701 | status = |
702 | acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block, NULL); | ||
694 | 703 | ||
695 | if (!gpe_block->previous && !gpe_block->next) { | 704 | if (!gpe_block->previous && !gpe_block->next) { |
696 | 705 | ||
@@ -717,6 +726,9 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) | |||
717 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 726 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
718 | } | 727 | } |
719 | 728 | ||
729 | acpi_current_gpe_count -= | ||
730 | gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH; | ||
731 | |||
720 | /* Free the gpe_block */ | 732 | /* Free the gpe_block */ |
721 | 733 | ||
722 | ACPI_FREE(gpe_block->register_info); | 734 | ACPI_FREE(gpe_block->register_info); |
@@ -958,6 +970,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
958 | gpe_device->name.ascii, gpe_block->register_count, | 970 | gpe_device->name.ascii, gpe_block->register_count, |
959 | interrupt_number)); | 971 | interrupt_number)); |
960 | 972 | ||
973 | /* Update global count of currently available GPEs */ | ||
974 | |||
975 | acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH; | ||
961 | return_ACPI_STATUS(AE_OK); | 976 | return_ACPI_STATUS(AE_OK); |
962 | } | 977 | } |
963 | 978 | ||
@@ -1057,7 +1072,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
1057 | 1072 | ||
1058 | /* Enable all valid runtime GPEs found above */ | 1073 | /* Enable all valid runtime GPEs found above */ |
1059 | 1074 | ||
1060 | status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block); | 1075 | status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block, NULL); |
1061 | if (ACPI_FAILURE(status)) { | 1076 | if (ACPI_FAILURE(status)) { |
1062 | ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p", | 1077 | ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p", |
1063 | gpe_block)); | 1078 | gpe_block)); |
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index dbac5b3248a0..d807158c6401 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -588,7 +588,7 @@ void acpi_ev_terminate(void) | |||
588 | 588 | ||
589 | /* Disable all GPEs in all GPE blocks */ | 589 | /* Disable all GPEs in all GPE blocks */ |
590 | 590 | ||
591 | status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block); | 591 | status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL); |
592 | 592 | ||
593 | /* Remove SCI handler */ | 593 | /* Remove SCI handler */ |
594 | 594 | ||
@@ -606,7 +606,7 @@ void acpi_ev_terminate(void) | |||
606 | 606 | ||
607 | /* Deallocate all handler objects installed within GPE info structs */ | 607 | /* Deallocate all handler objects installed within GPE info structs */ |
608 | 608 | ||
609 | status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers); | 609 | status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL); |
610 | 610 | ||
611 | /* Return to original mode if necessary */ | 611 | /* Return to original mode if necessary */ |
612 | 612 | ||
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 669b8ca4984b..aa4dec8edfc5 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c | |||
@@ -49,6 +49,11 @@ | |||
49 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
50 | ACPI_MODULE_NAME("evxfevnt") | 50 | ACPI_MODULE_NAME("evxfevnt") |
51 | 51 | ||
52 | /* Local prototypes */ | ||
53 | acpi_status | ||
54 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
55 | struct acpi_gpe_block_info *gpe_block, void *context); | ||
56 | |||
52 | /******************************************************************************* | 57 | /******************************************************************************* |
53 | * | 58 | * |
54 | * FUNCTION: acpi_enable | 59 | * FUNCTION: acpi_enable |
@@ -60,6 +65,7 @@ ACPI_MODULE_NAME("evxfevnt") | |||
60 | * DESCRIPTION: Transfers the system into ACPI mode. | 65 | * DESCRIPTION: Transfers the system into ACPI mode. |
61 | * | 66 | * |
62 | ******************************************************************************/ | 67 | ******************************************************************************/ |
68 | |||
63 | acpi_status acpi_enable(void) | 69 | acpi_status acpi_enable(void) |
64 | { | 70 | { |
65 | acpi_status status = AE_OK; | 71 | acpi_status status = AE_OK; |
@@ -717,3 +723,90 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) | |||
717 | } | 723 | } |
718 | 724 | ||
719 | ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) | 725 | ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) |
726 | |||
727 | /******************************************************************************* | ||
728 | * | ||
729 | * FUNCTION: acpi_get_gpe_device | ||
730 | * | ||
731 | * PARAMETERS: Index - System GPE index (0-current_gpe_count) | ||
732 | * gpe_device - Where the parent GPE Device is returned | ||
733 | * | ||
734 | * RETURN: Status | ||
735 | * | ||
736 | * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL | ||
737 | * gpe device indicates that the gpe number is contained in one of | ||
738 | * the FADT-defined gpe blocks. Otherwise, the GPE block device. | ||
739 | * | ||
740 | ******************************************************************************/ | ||
741 | acpi_status | ||
742 | acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) | ||
743 | { | ||
744 | struct acpi_gpe_device_info info; | ||
745 | acpi_status status; | ||
746 | |||
747 | ACPI_FUNCTION_TRACE(acpi_get_gpe_device); | ||
748 | |||
749 | if (!gpe_device) { | ||
750 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
751 | } | ||
752 | |||
753 | if (index >= acpi_current_gpe_count) { | ||
754 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
755 | } | ||
756 | |||
757 | /* Setup and walk the GPE list */ | ||
758 | |||
759 | info.index = index; | ||
760 | info.status = AE_NOT_EXIST; | ||
761 | info.gpe_device = NULL; | ||
762 | info.next_block_base_index = 0; | ||
763 | |||
764 | status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); | ||
765 | if (ACPI_FAILURE(status)) { | ||
766 | return_ACPI_STATUS(status); | ||
767 | } | ||
768 | |||
769 | *gpe_device = info.gpe_device; | ||
770 | return_ACPI_STATUS(info.status); | ||
771 | } | ||
772 | |||
773 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | ||
774 | |||
775 | /******************************************************************************* | ||
776 | * | ||
777 | * FUNCTION: acpi_ev_get_gpe_device | ||
778 | * | ||
779 | * PARAMETERS: GPE_WALK_CALLBACK | ||
780 | * | ||
781 | * RETURN: Status | ||
782 | * | ||
783 | * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE | ||
784 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | ||
785 | * | ||
786 | ******************************************************************************/ | ||
787 | acpi_status | ||
788 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
789 | struct acpi_gpe_block_info *gpe_block, void *context) | ||
790 | { | ||
791 | struct acpi_gpe_device_info *info = context; | ||
792 | |||
793 | /* Increment Index by the number of GPEs in this block */ | ||
794 | |||
795 | info->next_block_base_index += | ||
796 | (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH); | ||
797 | |||
798 | if (info->index < info->next_block_base_index) { | ||
799 | /* | ||
800 | * The GPE index is within this block, get the node. Leave the node | ||
801 | * NULL for the FADT-defined GPEs | ||
802 | */ | ||
803 | if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { | ||
804 | info->gpe_device = gpe_block->node; | ||
805 | } | ||
806 | |||
807 | info->status = AE_OK; | ||
808 | return (AE_CTRL_END); | ||
809 | } | ||
810 | |||
811 | return (AE_OK); | ||
812 | } | ||