aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/events
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/events')
-rw-r--r--drivers/acpi/events/evgpeblk.c25
-rw-r--r--drivers/acpi/events/evmisc.c4
-rw-r--r--drivers/acpi/events/evxfevnt.c93
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
134acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback) 135acpi_status
136acpi_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
187acpi_status 194acpi_status
188acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 195acpi_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
50ACPI_MODULE_NAME("evxfevnt") 50ACPI_MODULE_NAME("evxfevnt")
51 51
52/* Local prototypes */
53acpi_status
54acpi_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
63acpi_status acpi_enable(void) 69acpi_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
719ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) 725ACPI_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 ******************************************************************************/
741acpi_status
742acpi_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
773ACPI_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 ******************************************************************************/
787acpi_status
788acpi_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}