1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
6 * Copyright (C) 2000 - 2020, Intel Corp.
8 *****************************************************************************/
10 #define EXPORT_ACPI_INTERFACES
12 #include <acpi/acpi.h>
17 #define _COMPONENT ACPI_EVENTS
18 ACPI_MODULE_NAME("evxfgpe")
20 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
21 /*******************************************************************************
23 * FUNCTION: acpi_update_all_gpes
29 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
30 * associated _Lxx or _Exx methods and are not pointed to by any
31 * device _PRW methods (this indicates that these GPEs are
32 * generally intended for system or device wakeup. Such GPEs
33 * have to be enabled directly when the devices whose _PRW
34 * methods point to them are set up for wakeup signaling.)
36 * NOTE: Should be called after any GPEs are added to the system. Primarily,
37 * after the system _PRW methods have been run, but also after a GPE Block
38 * Device has been added or if any new GPE methods have been added via a
41 ******************************************************************************/
43 acpi_status
acpi_update_all_gpes(void)
46 u8 is_polling_needed
= FALSE
;
48 ACPI_FUNCTION_TRACE(acpi_update_all_gpes
);
50 status
= acpi_ut_acquire_mutex(ACPI_MTX_EVENTS
);
51 if (ACPI_FAILURE(status
)) {
52 return_ACPI_STATUS(status
);
55 if (acpi_gbl_all_gpes_initialized
) {
59 status
= acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block
,
61 if (ACPI_SUCCESS(status
)) {
62 acpi_gbl_all_gpes_initialized
= TRUE
;
66 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS
);
68 if (is_polling_needed
&& acpi_gbl_all_gpes_initialized
) {
70 /* Poll GPEs to handle already triggered events */
72 acpi_ev_gpe_detect(acpi_gbl_gpe_xrupt_list_head
);
74 return_ACPI_STATUS(status
);
77 ACPI_EXPORT_SYMBOL(acpi_update_all_gpes
)
79 /*******************************************************************************
81 * FUNCTION: acpi_enable_gpe
83 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
84 * gpe_number - GPE level within the GPE block
88 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
91 ******************************************************************************/
92 acpi_status
acpi_enable_gpe(acpi_handle gpe_device
, u32 gpe_number
)
94 acpi_status status
= AE_BAD_PARAMETER
;
95 struct acpi_gpe_event_info
*gpe_event_info
;
98 ACPI_FUNCTION_TRACE(acpi_enable_gpe
);
100 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
103 * Ensure that we have a valid GPE number and that there is some way
104 * of handling the GPE (handler or a GPE method). In other words, we
105 * won't allow a valid GPE to be enabled if there is no way to handle it.
107 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
108 if (gpe_event_info
) {
109 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info
->flags
) !=
110 ACPI_GPE_DISPATCH_NONE
) {
111 status
= acpi_ev_add_gpe_reference(gpe_event_info
, TRUE
);
112 if (ACPI_SUCCESS(status
) &&
113 ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info
)) {
115 /* Poll edge-triggered GPEs to handle existing events */
117 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
118 (void)acpi_ev_detect_gpe(gpe_device
,
121 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
124 status
= AE_NO_HANDLER
;
128 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
129 return_ACPI_STATUS(status
);
131 ACPI_EXPORT_SYMBOL(acpi_enable_gpe
)
133 /*******************************************************************************
135 * FUNCTION: acpi_disable_gpe
137 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
138 * gpe_number - GPE level within the GPE block
142 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
143 * removed, only then is the GPE disabled (for runtime GPEs), or
144 * the GPE mask bit disabled (for wake GPEs)
146 ******************************************************************************/
148 acpi_status
acpi_disable_gpe(acpi_handle gpe_device
, u32 gpe_number
)
150 acpi_status status
= AE_BAD_PARAMETER
;
151 struct acpi_gpe_event_info
*gpe_event_info
;
152 acpi_cpu_flags flags
;
154 ACPI_FUNCTION_TRACE(acpi_disable_gpe
);
156 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
158 /* Ensure that we have a valid GPE number */
160 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
161 if (gpe_event_info
) {
162 status
= acpi_ev_remove_gpe_reference(gpe_event_info
) ;
165 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
166 return_ACPI_STATUS(status
);
169 ACPI_EXPORT_SYMBOL(acpi_disable_gpe
)
171 /*******************************************************************************
173 * FUNCTION: acpi_set_gpe
175 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
176 * gpe_number - GPE level within the GPE block
177 * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
181 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
182 * the reference count mechanism used in the acpi_enable_gpe(),
183 * acpi_disable_gpe() interfaces.
184 * This API is typically used by the GPE raw handler mode driver
185 * to switch between the polling mode and the interrupt mode after
186 * the driver has enabled the GPE.
187 * The APIs should be invoked in this order:
188 * acpi_enable_gpe() <- Ensure the reference count > 0
189 * acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode
190 * acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode
191 * acpi_disable_gpe() <- Decrease the reference count
193 * Note: If a GPE is shared by 2 silicon components, then both the drivers
194 * should support GPE polling mode or disabling the GPE for long period
195 * for one driver may break the other. So use it with care since all
196 * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
198 ******************************************************************************/
199 acpi_status
acpi_set_gpe(acpi_handle gpe_device
, u32 gpe_number
, u8 action
)
201 struct acpi_gpe_event_info
*gpe_event_info
;
203 acpi_cpu_flags flags
;
205 ACPI_FUNCTION_TRACE(acpi_set_gpe
);
207 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
209 /* Ensure that we have a valid GPE number */
211 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
212 if (!gpe_event_info
) {
213 status
= AE_BAD_PARAMETER
;
214 goto unlock_and_exit
;
217 /* Perform the action */
220 case ACPI_GPE_ENABLE
:
222 status
= acpi_hw_low_set_gpe(gpe_event_info
, ACPI_GPE_ENABLE
);
223 gpe_event_info
->disable_for_dispatch
= FALSE
;
226 case ACPI_GPE_DISABLE
:
228 status
= acpi_hw_low_set_gpe(gpe_event_info
, ACPI_GPE_DISABLE
);
229 gpe_event_info
->disable_for_dispatch
= TRUE
;
234 status
= AE_BAD_PARAMETER
;
239 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
240 return_ACPI_STATUS(status
);
243 ACPI_EXPORT_SYMBOL(acpi_set_gpe
)
245 /*******************************************************************************
247 * FUNCTION: acpi_mask_gpe
249 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
250 * gpe_number - GPE level within the GPE block
251 * is_masked - Whether the GPE is masked or not
255 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
256 * prevent a GPE flooding.
258 ******************************************************************************/
259 acpi_status
acpi_mask_gpe(acpi_handle gpe_device
, u32 gpe_number
, u8 is_masked
)
261 struct acpi_gpe_event_info
*gpe_event_info
;
263 acpi_cpu_flags flags
;
265 ACPI_FUNCTION_TRACE(acpi_mask_gpe
);
267 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
269 /* Ensure that we have a valid GPE number */
271 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
272 if (!gpe_event_info
) {
273 status
= AE_BAD_PARAMETER
;
274 goto unlock_and_exit
;
277 status
= acpi_ev_mask_gpe(gpe_event_info
, is_masked
);
280 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
281 return_ACPI_STATUS(status
);
284 ACPI_EXPORT_SYMBOL(acpi_mask_gpe
)
286 /*******************************************************************************
288 * FUNCTION: acpi_mark_gpe_for_wake
290 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
291 * gpe_number - GPE level within the GPE block
295 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
296 * sets the ACPI_GPE_CAN_WAKE flag.
298 * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
299 * there won't be any notify handlers installed for device wake notifications
300 * from the given GPE (one example is a button GPE in Linux). For these cases,
301 * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
302 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
303 * setup implicit wake notification for it (since there's no handler method).
305 ******************************************************************************/
306 acpi_status
acpi_mark_gpe_for_wake(acpi_handle gpe_device
, u32 gpe_number
)
308 struct acpi_gpe_event_info
*gpe_event_info
;
309 acpi_status status
= AE_BAD_PARAMETER
;
310 acpi_cpu_flags flags
;
312 ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake
);
314 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
316 /* Ensure that we have a valid GPE number */
318 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
319 if (gpe_event_info
) {
321 /* Mark the GPE as a possible wake event */
323 gpe_event_info
->flags
|= ACPI_GPE_CAN_WAKE
;
327 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
328 return_ACPI_STATUS(status
);
331 ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake
)
333 /*******************************************************************************
335 * FUNCTION: acpi_setup_gpe_for_wake
337 * PARAMETERS: wake_device - Device associated with the GPE (via _PRW)
338 * gpe_device - Parent GPE Device. NULL for GPE0/GPE1
339 * gpe_number - GPE level within the GPE block
343 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
344 * interface is intended to be used as the host executes the
345 * _PRW methods (Power Resources for Wake) in the system tables.
346 * Each _PRW appears under a Device Object (The wake_device), and
347 * contains the info for the wake GPE associated with the
350 ******************************************************************************/
352 acpi_setup_gpe_for_wake(acpi_handle wake_device
,
353 acpi_handle gpe_device
, u32 gpe_number
)
356 struct acpi_gpe_event_info
*gpe_event_info
;
357 struct acpi_namespace_node
*device_node
;
358 struct acpi_gpe_notify_info
*notify
;
359 struct acpi_gpe_notify_info
*new_notify
;
360 acpi_cpu_flags flags
;
362 ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake
);
364 /* Parameter Validation */
368 * By forcing wake_device to be valid, we automatically enable the
369 * implicit notify feature on all hosts.
371 return_ACPI_STATUS(AE_BAD_PARAMETER
);
374 /* Handle root object case */
376 if (wake_device
== ACPI_ROOT_OBJECT
) {
377 device_node
= acpi_gbl_root_node
;
380 ACPI_CAST_PTR(struct acpi_namespace_node
, wake_device
);
383 /* Validate wake_device is of type Device */
385 if (device_node
->type
!= ACPI_TYPE_DEVICE
) {
386 return_ACPI_STATUS (AE_BAD_PARAMETER
);
390 * Allocate a new notify object up front, in case it is needed.
391 * Memory allocation while holding a spinlock is a big no-no
394 new_notify
= ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info
));
396 return_ACPI_STATUS(AE_NO_MEMORY
);
399 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
401 /* Ensure that we have a valid GPE number */
403 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
404 if (!gpe_event_info
) {
405 status
= AE_BAD_PARAMETER
;
406 goto unlock_and_exit
;
410 * If there is no method or handler for this GPE, then the
411 * wake_device will be notified whenever this GPE fires. This is
412 * known as an "implicit notify". Note: The GPE is assumed to be
413 * level-triggered (for windows compatibility).
415 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info
->flags
) ==
416 ACPI_GPE_DISPATCH_NONE
) {
418 * This is the first device for implicit notify on this GPE.
419 * Just set the flags here, and enter the NOTIFY block below.
421 gpe_event_info
->flags
=
422 (ACPI_GPE_DISPATCH_NOTIFY
| ACPI_GPE_LEVEL_TRIGGERED
);
423 } else if (gpe_event_info
->flags
& ACPI_GPE_AUTO_ENABLED
) {
425 * A reference to this GPE has been added during the GPE block
426 * initialization, so drop it now to prevent the GPE from being
427 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
429 (void)acpi_ev_remove_gpe_reference(gpe_event_info
);
430 gpe_event_info
->flags
&= ~ACPI_GPE_AUTO_ENABLED
;
434 * If we already have an implicit notify on this GPE, add
435 * this device to the notify list.
437 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info
->flags
) ==
438 ACPI_GPE_DISPATCH_NOTIFY
) {
440 /* Ensure that the device is not already in the list */
442 notify
= gpe_event_info
->dispatch
.notify_list
;
444 if (notify
->device_node
== device_node
) {
445 status
= AE_ALREADY_EXISTS
;
446 goto unlock_and_exit
;
448 notify
= notify
->next
;
451 /* Add this device to the notify list for this GPE */
453 new_notify
->device_node
= device_node
;
454 new_notify
->next
= gpe_event_info
->dispatch
.notify_list
;
455 gpe_event_info
->dispatch
.notify_list
= new_notify
;
459 /* Mark the GPE as a possible wake event */
461 gpe_event_info
->flags
|= ACPI_GPE_CAN_WAKE
;
465 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
467 /* Delete the notify object if it was not used above */
470 ACPI_FREE(new_notify
);
472 return_ACPI_STATUS(status
);
474 ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake
)
476 /*******************************************************************************
478 * FUNCTION: acpi_set_gpe_wake_mask
480 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
481 * gpe_number - GPE level within the GPE block
482 * action - Enable or Disable
486 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
487 * already be marked as a WAKE GPE.
489 ******************************************************************************/
492 acpi_set_gpe_wake_mask(acpi_handle gpe_device
, u32 gpe_number
, u8 action
)
494 acpi_status status
= AE_OK
;
495 struct acpi_gpe_event_info
*gpe_event_info
;
496 struct acpi_gpe_register_info
*gpe_register_info
;
497 acpi_cpu_flags flags
;
500 ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask
);
502 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
505 * Ensure that we have a valid GPE number and that this GPE is in
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
;
514 if (!(gpe_event_info
->flags
& ACPI_GPE_CAN_WAKE
)) {
516 goto unlock_and_exit
;
519 gpe_register_info
= gpe_event_info
->register_info
;
520 if (!gpe_register_info
) {
521 status
= AE_NOT_EXIST
;
522 goto unlock_and_exit
;
525 register_bit
= acpi_hw_get_gpe_register_bit(gpe_event_info
);
527 /* Perform the action */
530 case ACPI_GPE_ENABLE
:
532 ACPI_SET_BIT(gpe_register_info
->enable_for_wake
,
536 case ACPI_GPE_DISABLE
:
538 ACPI_CLEAR_BIT(gpe_register_info
->enable_for_wake
,
544 ACPI_ERROR((AE_INFO
, "%u, Invalid action", action
));
545 status
= AE_BAD_PARAMETER
;
550 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
551 return_ACPI_STATUS(status
);
554 ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask
)
556 /*******************************************************************************
558 * FUNCTION: acpi_clear_gpe
560 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
561 * gpe_number - GPE level within the GPE block
565 * DESCRIPTION: Clear an ACPI event (general purpose)
567 ******************************************************************************/
568 acpi_status
acpi_clear_gpe(acpi_handle gpe_device
, u32 gpe_number
)
570 acpi_status status
= AE_OK
;
571 struct acpi_gpe_event_info
*gpe_event_info
;
572 acpi_cpu_flags flags
;
574 ACPI_FUNCTION_TRACE(acpi_clear_gpe
);
576 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
578 /* Ensure that we have a valid GPE number */
580 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
581 if (!gpe_event_info
) {
582 status
= AE_BAD_PARAMETER
;
583 goto unlock_and_exit
;
586 status
= acpi_hw_clear_gpe(gpe_event_info
);
589 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
590 return_ACPI_STATUS(status
);
593 ACPI_EXPORT_SYMBOL(acpi_clear_gpe
)
595 /*******************************************************************************
597 * FUNCTION: acpi_get_gpe_status
599 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
600 * gpe_number - GPE level within the GPE block
601 * event_status - Where the current status of the event
606 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
608 ******************************************************************************/
610 acpi_get_gpe_status(acpi_handle gpe_device
,
611 u32 gpe_number
, acpi_event_status
*event_status
)
613 acpi_status status
= AE_OK
;
614 struct acpi_gpe_event_info
*gpe_event_info
;
615 acpi_cpu_flags flags
;
617 ACPI_FUNCTION_TRACE(acpi_get_gpe_status
);
619 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
621 /* Ensure that we have a valid GPE number */
623 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
624 if (!gpe_event_info
) {
625 status
= AE_BAD_PARAMETER
;
626 goto unlock_and_exit
;
629 /* Obtain status on the requested GPE number */
631 status
= acpi_hw_get_gpe_status(gpe_event_info
, event_status
);
634 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
635 return_ACPI_STATUS(status
);
638 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status
)
640 /*******************************************************************************
642 * FUNCTION: acpi_gispatch_gpe
644 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
645 * gpe_number - GPE level within the GPE block
647 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
649 * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
650 * (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
652 ******************************************************************************/
653 u32
acpi_dispatch_gpe(acpi_handle gpe_device
, u32 gpe_number
)
655 ACPI_FUNCTION_TRACE(acpi_dispatch_gpe
);
657 return acpi_ev_detect_gpe(gpe_device
, NULL
, gpe_number
);
660 ACPI_EXPORT_SYMBOL(acpi_dispatch_gpe
)
662 /*******************************************************************************
664 * FUNCTION: acpi_finish_gpe
666 * PARAMETERS: gpe_device - Namespace node for the GPE Block
667 * (NULL for FADT defined GPEs)
668 * gpe_number - GPE level within the GPE block
672 * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
673 * processing. Intended for use by asynchronous host-installed
674 * GPE handlers. The GPE is only re-enabled if the enable_for_run bit
675 * is set in the GPE info.
677 ******************************************************************************/
678 acpi_status
acpi_finish_gpe(acpi_handle gpe_device
, u32 gpe_number
)
680 struct acpi_gpe_event_info
*gpe_event_info
;
682 acpi_cpu_flags flags
;
684 ACPI_FUNCTION_TRACE(acpi_finish_gpe
);
686 flags
= acpi_os_acquire_lock(acpi_gbl_gpe_lock
);
688 /* Ensure that we have a valid GPE number */
690 gpe_event_info
= acpi_ev_get_gpe_event_info(gpe_device
, gpe_number
);
691 if (!gpe_event_info
) {
692 status
= AE_BAD_PARAMETER
;
693 goto unlock_and_exit
;
696 status
= acpi_ev_finish_gpe(gpe_event_info
);
699 acpi_os_release_lock(acpi_gbl_gpe_lock
, flags
);
700 return_ACPI_STATUS(status
);
703 ACPI_EXPORT_SYMBOL(acpi_finish_gpe
)
705 /******************************************************************************
707 * FUNCTION: acpi_disable_all_gpes
713 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
715 ******************************************************************************/
717 acpi_status
acpi_disable_all_gpes(void)
721 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes
);
723 status
= acpi_ut_acquire_mutex(ACPI_MTX_EVENTS
);
724 if (ACPI_FAILURE(status
)) {
725 return_ACPI_STATUS(status
);
728 status
= acpi_hw_disable_all_gpes();
729 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS
);
731 return_ACPI_STATUS(status
);
734 ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes
)
736 /******************************************************************************
738 * FUNCTION: acpi_enable_all_runtime_gpes
744 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
746 ******************************************************************************/
748 acpi_status
acpi_enable_all_runtime_gpes(void)
752 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes
);
754 status
= acpi_ut_acquire_mutex(ACPI_MTX_EVENTS
);
755 if (ACPI_FAILURE(status
)) {
756 return_ACPI_STATUS(status
);
759 status
= acpi_hw_enable_all_runtime_gpes();
760 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS
);
762 return_ACPI_STATUS(status
);
765 ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes
)
767 /******************************************************************************
769 * FUNCTION: acpi_enable_all_wakeup_gpes
775 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
778 ******************************************************************************/
779 acpi_status
acpi_enable_all_wakeup_gpes(void)
783 ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes
);
785 status
= acpi_ut_acquire_mutex(ACPI_MTX_EVENTS
);
786 if (ACPI_FAILURE(status
)) {
787 return_ACPI_STATUS(status
);
790 status
= acpi_hw_enable_all_wakeup_gpes();
791 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS
);
793 return_ACPI_STATUS(status
);
796 ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes
)
798 /*******************************************************************************
800 * FUNCTION: acpi_install_gpe_block
802 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
803 * gpe_block_address - Address and space_ID
804 * register_count - Number of GPE register pairs in the block
805 * interrupt_number - H/W interrupt for the block
809 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
812 ******************************************************************************/
814 acpi_install_gpe_block(acpi_handle gpe_device
,
815 struct acpi_generic_address
*gpe_block_address
,
816 u32 register_count
, u32 interrupt_number
)
819 union acpi_operand_object
*obj_desc
;
820 struct acpi_namespace_node
*node
;
821 struct acpi_gpe_block_info
*gpe_block
;
823 ACPI_FUNCTION_TRACE(acpi_install_gpe_block
);
825 if ((!gpe_device
) || (!gpe_block_address
) || (!register_count
)) {
826 return_ACPI_STATUS(AE_BAD_PARAMETER
);
829 status
= acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE
);
830 if (ACPI_FAILURE(status
)) {
831 return_ACPI_STATUS(status
);
834 node
= acpi_ns_validate_handle(gpe_device
);
836 status
= AE_BAD_PARAMETER
;
837 goto unlock_and_exit
;
840 /* Validate the parent device */
842 if (node
->type
!= ACPI_TYPE_DEVICE
) {
844 goto unlock_and_exit
;
848 status
= AE_ALREADY_EXISTS
;
849 goto unlock_and_exit
;
853 * For user-installed GPE Block Devices, the gpe_block_base_number
856 status
= acpi_ev_create_gpe_block(node
, gpe_block_address
->address
,
857 gpe_block_address
->space_id
,
858 register_count
, 0, interrupt_number
,
860 if (ACPI_FAILURE(status
)) {
861 goto unlock_and_exit
;
864 /* Install block in the device_object attached to the node */
866 obj_desc
= acpi_ns_get_attached_object(node
);
870 * No object, create a new one (Device nodes do not always have
871 * an attached object)
873 obj_desc
= acpi_ut_create_internal_object(ACPI_TYPE_DEVICE
);
875 status
= AE_NO_MEMORY
;
876 goto unlock_and_exit
;
880 acpi_ns_attach_object(node
, obj_desc
, ACPI_TYPE_DEVICE
);
882 /* Remove local reference to the object */
884 acpi_ut_remove_reference(obj_desc
);
886 if (ACPI_FAILURE(status
)) {
887 goto unlock_and_exit
;
891 /* Now install the GPE block in the device_object */
893 obj_desc
->device
.gpe_block
= gpe_block
;
896 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE
);
897 return_ACPI_STATUS(status
);
900 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block
)
902 /*******************************************************************************
904 * FUNCTION: acpi_remove_gpe_block
906 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
910 * DESCRIPTION: Remove a previously installed block of GPE registers
912 ******************************************************************************/
913 acpi_status
acpi_remove_gpe_block(acpi_handle gpe_device
)
915 union acpi_operand_object
*obj_desc
;
917 struct acpi_namespace_node
*node
;
919 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block
);
922 return_ACPI_STATUS(AE_BAD_PARAMETER
);
925 status
= acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE
);
926 if (ACPI_FAILURE(status
)) {
927 return_ACPI_STATUS(status
);
930 node
= acpi_ns_validate_handle(gpe_device
);
932 status
= AE_BAD_PARAMETER
;
933 goto unlock_and_exit
;
936 /* Validate the parent device */
938 if (node
->type
!= ACPI_TYPE_DEVICE
) {
940 goto unlock_and_exit
;
943 /* Get the device_object attached to the node */
945 obj_desc
= acpi_ns_get_attached_object(node
);
946 if (!obj_desc
|| !obj_desc
->device
.gpe_block
) {
947 return_ACPI_STATUS(AE_NULL_OBJECT
);
950 /* Delete the GPE block (but not the device_object) */
952 status
= acpi_ev_delete_gpe_block(obj_desc
->device
.gpe_block
);
953 if (ACPI_SUCCESS(status
)) {
954 obj_desc
->device
.gpe_block
= NULL
;
958 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE
);
959 return_ACPI_STATUS(status
);
962 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block
)
964 /*******************************************************************************
966 * FUNCTION: acpi_get_gpe_device
968 * PARAMETERS: index - System GPE index (0-current_gpe_count)
969 * gpe_device - Where the parent GPE Device is returned
973 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
974 * gpe device indicates that the gpe number is contained in one of
975 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
977 ******************************************************************************/
978 acpi_status
acpi_get_gpe_device(u32 index
, acpi_handle
*gpe_device
)
980 struct acpi_gpe_device_info info
;
983 ACPI_FUNCTION_TRACE(acpi_get_gpe_device
);
986 return_ACPI_STATUS(AE_BAD_PARAMETER
);
989 if (index
>= acpi_current_gpe_count
) {
990 return_ACPI_STATUS(AE_NOT_EXIST
);
993 /* Setup and walk the GPE list */
996 info
.status
= AE_NOT_EXIST
;
997 info
.gpe_device
= NULL
;
998 info
.next_block_base_index
= 0;
1000 status
= acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device
, &info
);
1001 if (ACPI_FAILURE(status
)) {
1002 return_ACPI_STATUS(status
);
1005 *gpe_device
= ACPI_CAST_PTR(acpi_handle
, info
.gpe_device
);
1006 return_ACPI_STATUS(info
.status
);
1009 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device
)
1010 #endif /* !ACPI_REDUCED_HARDWARE */