aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpica/Makefile2
-rw-r--r--drivers/acpi/acpica/acevents.h4
-rw-r--r--drivers/acpi/acpica/evgpeutil.c39
-rw-r--r--drivers/acpi/acpica/evxfevnt.c600
-rw-r--r--drivers/acpi/acpica/evxfgpe.c610
5 files changed, 654 insertions, 601 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index a7e1d1aa4107..eec2eadd2431 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -14,7 +14,7 @@ acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
14 14
15acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ 15acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \
16 evmisc.o evrgnini.o evxface.o evxfregn.o \ 16 evmisc.o evrgnini.o evxface.o evxfregn.o \
17 evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o 17 evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o
18 18
19acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ 19acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
20 exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ 20 exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index a6f99cc37a19..43f15c8cd2b2 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -138,6 +138,10 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context);
138 138
139u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); 139u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info);
140 140
141acpi_status
142acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
143 struct acpi_gpe_block_info *gpe_block, void *context);
144
141struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number); 145struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number);
142 146
143acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); 147acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt);
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c
index 19a0e513ea48..10e477494dcf 100644
--- a/drivers/acpi/acpica/evgpeutil.c
+++ b/drivers/acpi/acpica/evgpeutil.c
@@ -154,6 +154,45 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
154 154
155/******************************************************************************* 155/*******************************************************************************
156 * 156 *
157 * FUNCTION: acpi_ev_get_gpe_device
158 *
159 * PARAMETERS: GPE_WALK_CALLBACK
160 *
161 * RETURN: Status
162 *
163 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
164 * block device. NULL if the GPE is one of the FADT-defined GPEs.
165 *
166 ******************************************************************************/
167
168acpi_status
169acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
170 struct acpi_gpe_block_info *gpe_block, void *context)
171{
172 struct acpi_gpe_device_info *info = context;
173
174 /* Increment Index by the number of GPEs in this block */
175
176 info->next_block_base_index += gpe_block->gpe_count;
177
178 if (info->index < info->next_block_base_index) {
179 /*
180 * The GPE index is within this block, get the node. Leave the node
181 * NULL for the FADT-defined GPEs
182 */
183 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
184 info->gpe_device = gpe_block->node;
185 }
186
187 info->status = AE_OK;
188 return (AE_CTRL_END);
189 }
190
191 return (AE_OK);
192}
193
194/*******************************************************************************
195 *
157 * FUNCTION: acpi_ev_get_gpe_xrupt_block 196 * FUNCTION: acpi_ev_get_gpe_xrupt_block
158 * 197 *
159 * PARAMETERS: interrupt_number - Interrupt for a GPE block 198 * PARAMETERS: interrupt_number - Interrupt for a GPE block
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index a1dabe3fd8ae..90488c1e0f3d 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -43,18 +43,11 @@
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include "accommon.h" 45#include "accommon.h"
46#include "acevents.h"
47#include "acnamesp.h"
48#include "actables.h" 46#include "actables.h"
49 47
50#define _COMPONENT ACPI_EVENTS 48#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evxfevnt") 49ACPI_MODULE_NAME("evxfevnt")
52 50
53/* Local prototypes */
54static acpi_status
55acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
56 struct acpi_gpe_block_info *gpe_block, void *context);
57
58/******************************************************************************* 51/*******************************************************************************
59 * 52 *
60 * FUNCTION: acpi_enable 53 * FUNCTION: acpi_enable
@@ -213,185 +206,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
213 206
214/******************************************************************************* 207/*******************************************************************************
215 * 208 *
216 * FUNCTION: acpi_gpe_wakeup
217 *
218 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
219 * gpe_number - GPE level within the GPE block
220 * Action - Enable or Disable
221 *
222 * RETURN: Status
223 *
224 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
225 *
226 ******************************************************************************/
227acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
228{
229 acpi_status status = AE_OK;
230 struct acpi_gpe_event_info *gpe_event_info;
231 struct acpi_gpe_register_info *gpe_register_info;
232 acpi_cpu_flags flags;
233 u32 register_bit;
234
235 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
236
237 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
238
239 /* Ensure that we have a valid GPE number */
240
241 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
242 if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
243 status = AE_BAD_PARAMETER;
244 goto unlock_and_exit;
245 }
246
247 gpe_register_info = gpe_event_info->register_info;
248 if (!gpe_register_info) {
249 status = AE_NOT_EXIST;
250 goto unlock_and_exit;
251 }
252
253 register_bit =
254 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
255
256 /* Perform the action */
257
258 switch (action) {
259 case ACPI_GPE_ENABLE:
260 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
261 (u8)register_bit);
262 break;
263
264 case ACPI_GPE_DISABLE:
265 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
266 (u8)register_bit);
267 break;
268
269 default:
270 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
271 status = AE_BAD_PARAMETER;
272 break;
273 }
274
275unlock_and_exit:
276 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
277 return_ACPI_STATUS(status);
278}
279
280ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
281
282/*******************************************************************************
283 *
284 * FUNCTION: acpi_enable_gpe
285 *
286 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
287 * gpe_number - GPE level within the GPE block
288 *
289 * RETURN: Status
290 *
291 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
292 * hardware-enabled.
293 *
294 ******************************************************************************/
295acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
296{
297 acpi_status status = AE_BAD_PARAMETER;
298 struct acpi_gpe_event_info *gpe_event_info;
299 acpi_cpu_flags flags;
300
301 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
302
303 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
304
305 /* Ensure that we have a valid GPE number */
306
307 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
308 if (gpe_event_info) {
309 status = acpi_raw_enable_gpe(gpe_event_info);
310 }
311
312 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
313 return_ACPI_STATUS(status);
314}
315ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
316
317/*******************************************************************************
318 *
319 * FUNCTION: acpi_disable_gpe
320 *
321 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
322 * gpe_number - GPE level within the GPE block
323 *
324 * RETURN: Status
325 *
326 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
327 * removed, only then is the GPE disabled (for runtime GPEs), or
328 * the GPE mask bit disabled (for wake GPEs)
329 *
330 ******************************************************************************/
331acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
332{
333 acpi_status status = AE_BAD_PARAMETER;
334 struct acpi_gpe_event_info *gpe_event_info;
335 acpi_cpu_flags flags;
336
337 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
338
339 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
340
341 /* Ensure that we have a valid GPE number */
342
343 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
344 if (gpe_event_info) {
345 status = acpi_raw_disable_gpe(gpe_event_info) ;
346 }
347
348 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
349 return_ACPI_STATUS(status);
350}
351ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
352
353/*******************************************************************************
354 *
355 * FUNCTION: acpi_gpe_can_wake
356 *
357 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
358 * gpe_number - GPE level within the GPE block
359 *
360 * RETURN: Status
361 *
362 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE
363 * has a corresponding method and is currently enabled, disable it
364 * (GPEs with corresponding methods are enabled unconditionally
365 * during initialization, but GPEs that can wake up are expected
366 * to be initially disabled).
367 *
368 ******************************************************************************/
369acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
370{
371 acpi_status status = AE_OK;
372 struct acpi_gpe_event_info *gpe_event_info;
373 acpi_cpu_flags flags;
374
375 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
376
377 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
378
379 /* Ensure that we have a valid GPE number */
380
381 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
382 if (gpe_event_info) {
383 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
384 } else {
385 status = AE_BAD_PARAMETER;
386 }
387
388 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
389 return_ACPI_STATUS(status);
390}
391ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
392
393/*******************************************************************************
394 *
395 * FUNCTION: acpi_disable_event 209 * FUNCTION: acpi_disable_event
396 * 210 *
397 * PARAMETERS: Event - The fixed eventto be enabled 211 * PARAMETERS: Event - The fixed eventto be enabled
@@ -483,44 +297,6 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event)
483 297
484/******************************************************************************* 298/*******************************************************************************
485 * 299 *
486 * FUNCTION: acpi_clear_gpe
487 *
488 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
489 * gpe_number - GPE level within the GPE block
490 *
491 * RETURN: Status
492 *
493 * DESCRIPTION: Clear an ACPI event (general purpose)
494 *
495 ******************************************************************************/
496acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
497{
498 acpi_status status = AE_OK;
499 struct acpi_gpe_event_info *gpe_event_info;
500 acpi_cpu_flags flags;
501
502 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
503
504 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
505
506 /* Ensure that we have a valid GPE number */
507
508 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
509 if (!gpe_event_info) {
510 status = AE_BAD_PARAMETER;
511 goto unlock_and_exit;
512 }
513
514 status = acpi_hw_clear_gpe(gpe_event_info);
515
516 unlock_and_exit:
517 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
518 return_ACPI_STATUS(status);
519}
520
521ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
522/*******************************************************************************
523 *
524 * FUNCTION: acpi_get_event_status 300 * FUNCTION: acpi_get_event_status
525 * 301 *
526 * PARAMETERS: Event - The fixed event 302 * PARAMETERS: Event - The fixed event
@@ -575,379 +351,3 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
575} 351}
576 352
577ACPI_EXPORT_SYMBOL(acpi_get_event_status) 353ACPI_EXPORT_SYMBOL(acpi_get_event_status)
578
579/*******************************************************************************
580 *
581 * FUNCTION: acpi_get_gpe_status
582 *
583 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
584 * gpe_number - GPE level within the GPE block
585 * event_status - Where the current status of the event will
586 * be returned
587 *
588 * RETURN: Status
589 *
590 * DESCRIPTION: Get status of an event (general purpose)
591 *
592 ******************************************************************************/
593acpi_status
594acpi_get_gpe_status(acpi_handle gpe_device,
595 u32 gpe_number, acpi_event_status *event_status)
596{
597 acpi_status status = AE_OK;
598 struct acpi_gpe_event_info *gpe_event_info;
599 acpi_cpu_flags flags;
600
601 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
602
603 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
604
605 /* Ensure that we have a valid GPE number */
606
607 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
608 if (!gpe_event_info) {
609 status = AE_BAD_PARAMETER;
610 goto unlock_and_exit;
611 }
612
613 /* Obtain status on the requested GPE number */
614
615 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
616
617 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
618 *event_status |= ACPI_EVENT_FLAG_HANDLE;
619
620 unlock_and_exit:
621 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
622 return_ACPI_STATUS(status);
623}
624
625ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
626/*******************************************************************************
627 *
628 * FUNCTION: acpi_install_gpe_block
629 *
630 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
631 * gpe_block_address - Address and space_iD
632 * register_count - Number of GPE register pairs in the block
633 * interrupt_number - H/W interrupt for the block
634 *
635 * RETURN: Status
636 *
637 * DESCRIPTION: Create and Install a block of GPE registers
638 *
639 ******************************************************************************/
640acpi_status
641acpi_install_gpe_block(acpi_handle gpe_device,
642 struct acpi_generic_address *gpe_block_address,
643 u32 register_count, u32 interrupt_number)
644{
645 acpi_status status = AE_OK;
646 union acpi_operand_object *obj_desc;
647 struct acpi_namespace_node *node;
648 struct acpi_gpe_block_info *gpe_block;
649
650 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
651
652 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
653 return_ACPI_STATUS(AE_BAD_PARAMETER);
654 }
655
656 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
657 if (ACPI_FAILURE(status)) {
658 return (status);
659 }
660
661 node = acpi_ns_validate_handle(gpe_device);
662 if (!node) {
663 status = AE_BAD_PARAMETER;
664 goto unlock_and_exit;
665 }
666
667 /*
668 * For user-installed GPE Block Devices, the gpe_block_base_number
669 * is always zero
670 */
671 status =
672 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
673 interrupt_number, &gpe_block);
674 if (ACPI_FAILURE(status)) {
675 goto unlock_and_exit;
676 }
677
678 /* Install block in the device_object attached to the node */
679
680 obj_desc = acpi_ns_get_attached_object(node);
681 if (!obj_desc) {
682
683 /*
684 * No object, create a new one (Device nodes do not always have
685 * an attached object)
686 */
687 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
688 if (!obj_desc) {
689 status = AE_NO_MEMORY;
690 goto unlock_and_exit;
691 }
692
693 status =
694 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
695
696 /* Remove local reference to the object */
697
698 acpi_ut_remove_reference(obj_desc);
699
700 if (ACPI_FAILURE(status)) {
701 goto unlock_and_exit;
702 }
703 }
704
705 /* Now install the GPE block in the device_object */
706
707 obj_desc->device.gpe_block = gpe_block;
708
709 unlock_and_exit:
710 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
711 return_ACPI_STATUS(status);
712}
713
714ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
715
716/*******************************************************************************
717 *
718 * FUNCTION: acpi_remove_gpe_block
719 *
720 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
721 *
722 * RETURN: Status
723 *
724 * DESCRIPTION: Remove a previously installed block of GPE registers
725 *
726 ******************************************************************************/
727acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
728{
729 union acpi_operand_object *obj_desc;
730 acpi_status status;
731 struct acpi_namespace_node *node;
732
733 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
734
735 if (!gpe_device) {
736 return_ACPI_STATUS(AE_BAD_PARAMETER);
737 }
738
739 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
740 if (ACPI_FAILURE(status)) {
741 return (status);
742 }
743
744 node = acpi_ns_validate_handle(gpe_device);
745 if (!node) {
746 status = AE_BAD_PARAMETER;
747 goto unlock_and_exit;
748 }
749
750 /* Get the device_object attached to the node */
751
752 obj_desc = acpi_ns_get_attached_object(node);
753 if (!obj_desc || !obj_desc->device.gpe_block) {
754 return_ACPI_STATUS(AE_NULL_OBJECT);
755 }
756
757 /* Delete the GPE block (but not the device_object) */
758
759 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
760 if (ACPI_SUCCESS(status)) {
761 obj_desc->device.gpe_block = NULL;
762 }
763
764 unlock_and_exit:
765 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
766 return_ACPI_STATUS(status);
767}
768
769ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
770
771/*******************************************************************************
772 *
773 * FUNCTION: acpi_get_gpe_device
774 *
775 * PARAMETERS: Index - System GPE index (0-current_gpe_count)
776 * gpe_device - Where the parent GPE Device is returned
777 *
778 * RETURN: Status
779 *
780 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
781 * gpe device indicates that the gpe number is contained in one of
782 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
783 *
784 ******************************************************************************/
785acpi_status
786acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
787{
788 struct acpi_gpe_device_info info;
789 acpi_status status;
790
791 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
792
793 if (!gpe_device) {
794 return_ACPI_STATUS(AE_BAD_PARAMETER);
795 }
796
797 if (index >= acpi_current_gpe_count) {
798 return_ACPI_STATUS(AE_NOT_EXIST);
799 }
800
801 /* Setup and walk the GPE list */
802
803 info.index = index;
804 info.status = AE_NOT_EXIST;
805 info.gpe_device = NULL;
806 info.next_block_base_index = 0;
807
808 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
809 if (ACPI_FAILURE(status)) {
810 return_ACPI_STATUS(status);
811 }
812
813 *gpe_device = info.gpe_device;
814 return_ACPI_STATUS(info.status);
815}
816
817ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
818
819/*******************************************************************************
820 *
821 * FUNCTION: acpi_ev_get_gpe_device
822 *
823 * PARAMETERS: GPE_WALK_CALLBACK
824 *
825 * RETURN: Status
826 *
827 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
828 * block device. NULL if the GPE is one of the FADT-defined GPEs.
829 *
830 ******************************************************************************/
831static acpi_status
832acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
833 struct acpi_gpe_block_info *gpe_block, void *context)
834{
835 struct acpi_gpe_device_info *info = context;
836
837 /* Increment Index by the number of GPEs in this block */
838
839 info->next_block_base_index += gpe_block->gpe_count;
840
841 if (info->index < info->next_block_base_index) {
842 /*
843 * The GPE index is within this block, get the node. Leave the node
844 * NULL for the FADT-defined GPEs
845 */
846 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
847 info->gpe_device = gpe_block->node;
848 }
849
850 info->status = AE_OK;
851 return (AE_CTRL_END);
852 }
853
854 return (AE_OK);
855}
856
857/******************************************************************************
858 *
859 * FUNCTION: acpi_disable_all_gpes
860 *
861 * PARAMETERS: None
862 *
863 * RETURN: Status
864 *
865 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
866 *
867 ******************************************************************************/
868
869acpi_status acpi_disable_all_gpes(void)
870{
871 acpi_status status;
872
873 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
874
875 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
876 if (ACPI_FAILURE(status)) {
877 return_ACPI_STATUS(status);
878 }
879
880 status = acpi_hw_disable_all_gpes();
881 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
882
883 return_ACPI_STATUS(status);
884}
885
886/******************************************************************************
887 *
888 * FUNCTION: acpi_enable_all_runtime_gpes
889 *
890 * PARAMETERS: None
891 *
892 * RETURN: Status
893 *
894 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
895 *
896 ******************************************************************************/
897
898acpi_status acpi_enable_all_runtime_gpes(void)
899{
900 acpi_status status;
901
902 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
903
904 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
905 if (ACPI_FAILURE(status)) {
906 return_ACPI_STATUS(status);
907 }
908
909 status = acpi_hw_enable_all_runtime_gpes();
910 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
911
912 return_ACPI_STATUS(status);
913}
914
915/******************************************************************************
916 *
917 * FUNCTION: acpi_update_gpes
918 *
919 * PARAMETERS: None
920 *
921 * RETURN: None
922 *
923 * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and
924 * are not pointed to by any device _PRW methods indicating that
925 * these GPEs are generally intended for system or device wakeup
926 * (such GPEs have to be enabled directly when the devices whose
927 * _PRW methods point to them are set up for wakeup signaling).
928 *
929 ******************************************************************************/
930
931acpi_status acpi_update_gpes(void)
932{
933 acpi_status status;
934
935 ACPI_FUNCTION_TRACE(acpi_update_gpes);
936
937 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
938 if (ACPI_FAILURE(status)) {
939 return_ACPI_STATUS(status);
940 } else if (acpi_all_gpes_initialized) {
941 goto unlock;
942 }
943
944 status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
945 if (ACPI_SUCCESS(status)) {
946 acpi_all_gpes_initialized = TRUE;
947 }
948
949unlock:
950 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
951
952 return_ACPI_STATUS(status);
953}
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
new file mode 100644
index 000000000000..8068065d90eb
--- /dev/null
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -0,0 +1,610 @@
1/******************************************************************************
2 *
3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2010, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acevents.h"
47#include "acnamesp.h"
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evxfgpe")
51
52/******************************************************************************
53 *
54 * FUNCTION: acpi_update_gpes
55 *
56 * PARAMETERS: None
57 *
58 * RETURN: None
59 *
60 * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and
61 * are not pointed to by any device _PRW methods indicating that
62 * these GPEs are generally intended for system or device wakeup
63 * (such GPEs have to be enabled directly when the devices whose
64 * _PRW methods point to them are set up for wakeup signaling).
65 *
66 ******************************************************************************/
67
68acpi_status acpi_update_gpes(void)
69{
70 acpi_status status;
71
72 ACPI_FUNCTION_TRACE(acpi_update_gpes);
73
74 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
75 if (ACPI_FAILURE(status)) {
76 return_ACPI_STATUS(status);
77 } else if (acpi_all_gpes_initialized) {
78 goto unlock;
79 }
80
81 status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
82 if (ACPI_SUCCESS(status)) {
83 acpi_all_gpes_initialized = TRUE;
84 }
85
86unlock:
87 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
88
89 return_ACPI_STATUS(status);
90}
91
92/*******************************************************************************
93 *
94 * FUNCTION: acpi_enable_gpe
95 *
96 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
97 * gpe_number - GPE level within the GPE block
98 *
99 * RETURN: Status
100 *
101 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
102 * hardware-enabled.
103 *
104 ******************************************************************************/
105
106acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
107{
108 acpi_status status = AE_BAD_PARAMETER;
109 struct acpi_gpe_event_info *gpe_event_info;
110 acpi_cpu_flags flags;
111
112 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
113
114 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
115
116 /* Ensure that we have a valid GPE number */
117
118 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
119 if (gpe_event_info) {
120 status = acpi_raw_enable_gpe(gpe_event_info);
121 }
122
123 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
124 return_ACPI_STATUS(status);
125}
126ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
127
128/*******************************************************************************
129 *
130 * FUNCTION: acpi_disable_gpe
131 *
132 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
133 * gpe_number - GPE level within the GPE block
134 *
135 * RETURN: Status
136 *
137 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
138 * removed, only then is the GPE disabled (for runtime GPEs), or
139 * the GPE mask bit disabled (for wake GPEs)
140 *
141 ******************************************************************************/
142
143acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
144{
145 acpi_status status = AE_BAD_PARAMETER;
146 struct acpi_gpe_event_info *gpe_event_info;
147 acpi_cpu_flags flags;
148
149 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
150
151 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
152
153 /* Ensure that we have a valid GPE number */
154
155 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
156 if (gpe_event_info) {
157 status = acpi_raw_disable_gpe(gpe_event_info) ;
158 }
159
160 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
161 return_ACPI_STATUS(status);
162}
163ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
164
165/*******************************************************************************
166 *
167 * FUNCTION: acpi_gpe_can_wake
168 *
169 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
170 * gpe_number - GPE level within the GPE block
171 *
172 * RETURN: Status
173 *
174 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE
175 * has a corresponding method and is currently enabled, disable it
176 * (GPEs with corresponding methods are enabled unconditionally
177 * during initialization, but GPEs that can wake up are expected
178 * to be initially disabled).
179 *
180 ******************************************************************************/
181acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
182{
183 acpi_status status = AE_OK;
184 struct acpi_gpe_event_info *gpe_event_info;
185 acpi_cpu_flags flags;
186
187 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
188
189 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
190
191 /* Ensure that we have a valid GPE number */
192
193 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
194 if (gpe_event_info) {
195 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
196 } else {
197 status = AE_BAD_PARAMETER;
198 }
199
200 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
201 return_ACPI_STATUS(status);
202}
203ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
204
205/*******************************************************************************
206 *
207 * FUNCTION: acpi_gpe_wakeup
208 *
209 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
210 * gpe_number - GPE level within the GPE block
211 * Action - Enable or Disable
212 *
213 * RETURN: Status
214 *
215 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
216 *
217 ******************************************************************************/
218
219acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
220{
221 acpi_status status = AE_OK;
222 struct acpi_gpe_event_info *gpe_event_info;
223 struct acpi_gpe_register_info *gpe_register_info;
224 acpi_cpu_flags flags;
225 u32 register_bit;
226
227 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
228
229 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
230
231 /* Ensure that we have a valid GPE number */
232
233 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
234 if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
235 status = AE_BAD_PARAMETER;
236 goto unlock_and_exit;
237 }
238
239 gpe_register_info = gpe_event_info->register_info;
240 if (!gpe_register_info) {
241 status = AE_NOT_EXIST;
242 goto unlock_and_exit;
243 }
244
245 register_bit =
246 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
247
248 /* Perform the action */
249
250 switch (action) {
251 case ACPI_GPE_ENABLE:
252 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
253 (u8)register_bit);
254 break;
255
256 case ACPI_GPE_DISABLE:
257 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
258 (u8)register_bit);
259 break;
260
261 default:
262 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
263 status = AE_BAD_PARAMETER;
264 break;
265 }
266
267unlock_and_exit:
268 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
269 return_ACPI_STATUS(status);
270}
271
272ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
273
274/*******************************************************************************
275 *
276 * FUNCTION: acpi_clear_gpe
277 *
278 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
279 * gpe_number - GPE level within the GPE block
280 *
281 * RETURN: Status
282 *
283 * DESCRIPTION: Clear an ACPI event (general purpose)
284 *
285 ******************************************************************************/
286acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
287{
288 acpi_status status = AE_OK;
289 struct acpi_gpe_event_info *gpe_event_info;
290 acpi_cpu_flags flags;
291
292 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
293
294 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
295
296 /* Ensure that we have a valid GPE number */
297
298 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
299 if (!gpe_event_info) {
300 status = AE_BAD_PARAMETER;
301 goto unlock_and_exit;
302 }
303
304 status = acpi_hw_clear_gpe(gpe_event_info);
305
306 unlock_and_exit:
307 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
308 return_ACPI_STATUS(status);
309}
310
311ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
312
313/*******************************************************************************
314 *
315 * FUNCTION: acpi_get_gpe_status
316 *
317 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
318 * gpe_number - GPE level within the GPE block
319 * event_status - Where the current status of the event will
320 * be returned
321 *
322 * RETURN: Status
323 *
324 * DESCRIPTION: Get status of an event (general purpose)
325 *
326 ******************************************************************************/
327acpi_status
328acpi_get_gpe_status(acpi_handle gpe_device,
329 u32 gpe_number, acpi_event_status *event_status)
330{
331 acpi_status status = AE_OK;
332 struct acpi_gpe_event_info *gpe_event_info;
333 acpi_cpu_flags flags;
334
335 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
336
337 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
338
339 /* Ensure that we have a valid GPE number */
340
341 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
342 if (!gpe_event_info) {
343 status = AE_BAD_PARAMETER;
344 goto unlock_and_exit;
345 }
346
347 /* Obtain status on the requested GPE number */
348
349 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
350
351 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
352 *event_status |= ACPI_EVENT_FLAG_HANDLE;
353
354 unlock_and_exit:
355 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
356 return_ACPI_STATUS(status);
357}
358
359ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
360
361/******************************************************************************
362 *
363 * FUNCTION: acpi_disable_all_gpes
364 *
365 * PARAMETERS: None
366 *
367 * RETURN: Status
368 *
369 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
370 *
371 ******************************************************************************/
372
373acpi_status acpi_disable_all_gpes(void)
374{
375 acpi_status status;
376
377 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
378
379 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
380 if (ACPI_FAILURE(status)) {
381 return_ACPI_STATUS(status);
382 }
383
384 status = acpi_hw_disable_all_gpes();
385 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
386
387 return_ACPI_STATUS(status);
388}
389
390/******************************************************************************
391 *
392 * FUNCTION: acpi_enable_all_runtime_gpes
393 *
394 * PARAMETERS: None
395 *
396 * RETURN: Status
397 *
398 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
399 *
400 ******************************************************************************/
401
402acpi_status acpi_enable_all_runtime_gpes(void)
403{
404 acpi_status status;
405
406 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
407
408 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
409 if (ACPI_FAILURE(status)) {
410 return_ACPI_STATUS(status);
411 }
412
413 status = acpi_hw_enable_all_runtime_gpes();
414 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
415
416 return_ACPI_STATUS(status);
417}
418
419/*******************************************************************************
420 *
421 * FUNCTION: acpi_install_gpe_block
422 *
423 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
424 * gpe_block_address - Address and space_iD
425 * register_count - Number of GPE register pairs in the block
426 * interrupt_number - H/W interrupt for the block
427 *
428 * RETURN: Status
429 *
430 * DESCRIPTION: Create and Install a block of GPE registers
431 *
432 ******************************************************************************/
433acpi_status
434acpi_install_gpe_block(acpi_handle gpe_device,
435 struct acpi_generic_address *gpe_block_address,
436 u32 register_count, u32 interrupt_number)
437{
438 acpi_status status = AE_OK;
439 union acpi_operand_object *obj_desc;
440 struct acpi_namespace_node *node;
441 struct acpi_gpe_block_info *gpe_block;
442
443 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
444
445 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
446 return_ACPI_STATUS(AE_BAD_PARAMETER);
447 }
448
449 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
450 if (ACPI_FAILURE(status)) {
451 return (status);
452 }
453
454 node = acpi_ns_validate_handle(gpe_device);
455 if (!node) {
456 status = AE_BAD_PARAMETER;
457 goto unlock_and_exit;
458 }
459
460 /*
461 * For user-installed GPE Block Devices, the gpe_block_base_number
462 * is always zero
463 */
464 status =
465 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
466 interrupt_number, &gpe_block);
467 if (ACPI_FAILURE(status)) {
468 goto unlock_and_exit;
469 }
470
471 /* Install block in the device_object attached to the node */
472
473 obj_desc = acpi_ns_get_attached_object(node);
474 if (!obj_desc) {
475
476 /*
477 * No object, create a new one (Device nodes do not always have
478 * an attached object)
479 */
480 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
481 if (!obj_desc) {
482 status = AE_NO_MEMORY;
483 goto unlock_and_exit;
484 }
485
486 status =
487 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
488
489 /* Remove local reference to the object */
490
491 acpi_ut_remove_reference(obj_desc);
492
493 if (ACPI_FAILURE(status)) {
494 goto unlock_and_exit;
495 }
496 }
497
498 /* Now install the GPE block in the device_object */
499
500 obj_desc->device.gpe_block = gpe_block;
501
502 unlock_and_exit:
503 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
504 return_ACPI_STATUS(status);
505}
506
507ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
508
509/*******************************************************************************
510 *
511 * FUNCTION: acpi_remove_gpe_block
512 *
513 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
514 *
515 * RETURN: Status
516 *
517 * DESCRIPTION: Remove a previously installed block of GPE registers
518 *
519 ******************************************************************************/
520acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
521{
522 union acpi_operand_object *obj_desc;
523 acpi_status status;
524 struct acpi_namespace_node *node;
525
526 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
527
528 if (!gpe_device) {
529 return_ACPI_STATUS(AE_BAD_PARAMETER);
530 }
531
532 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
533 if (ACPI_FAILURE(status)) {
534 return (status);
535 }
536
537 node = acpi_ns_validate_handle(gpe_device);
538 if (!node) {
539 status = AE_BAD_PARAMETER;
540 goto unlock_and_exit;
541 }
542
543 /* Get the device_object attached to the node */
544
545 obj_desc = acpi_ns_get_attached_object(node);
546 if (!obj_desc || !obj_desc->device.gpe_block) {
547 return_ACPI_STATUS(AE_NULL_OBJECT);
548 }
549
550 /* Delete the GPE block (but not the device_object) */
551
552 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
553 if (ACPI_SUCCESS(status)) {
554 obj_desc->device.gpe_block = NULL;
555 }
556
557 unlock_and_exit:
558 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
559 return_ACPI_STATUS(status);
560}
561
562ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
563
564/*******************************************************************************
565 *
566 * FUNCTION: acpi_get_gpe_device
567 *
568 * PARAMETERS: Index - System GPE index (0-current_gpe_count)
569 * gpe_device - Where the parent GPE Device is returned
570 *
571 * RETURN: Status
572 *
573 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
574 * gpe device indicates that the gpe number is contained in one of
575 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
576 *
577 ******************************************************************************/
578acpi_status
579acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
580{
581 struct acpi_gpe_device_info info;
582 acpi_status status;
583
584 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
585
586 if (!gpe_device) {
587 return_ACPI_STATUS(AE_BAD_PARAMETER);
588 }
589
590 if (index >= acpi_current_gpe_count) {
591 return_ACPI_STATUS(AE_NOT_EXIST);
592 }
593
594 /* Setup and walk the GPE list */
595
596 info.index = index;
597 info.status = AE_NOT_EXIST;
598 info.gpe_device = NULL;
599 info.next_block_base_index = 0;
600
601 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
602 if (ACPI_FAILURE(status)) {
603 return_ACPI_STATUS(status);
604 }
605
606 *gpe_device = info.gpe_device;
607 return_ACPI_STATUS(info.status);
608}
609
610ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)