1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3 *
4 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
5 *
6 * Copyright (C) 2000 - 2025, Intel Corp.
7 *
8 *****************************************************************************/
9
10 #define EXPORT_ACPI_INTERFACES
11
12 #include <acpi/acpi.h>
13 #include "accommon.h"
14 #include "acevents.h"
15 #include "acnamesp.h"
16
17 #define _COMPONENT ACPI_EVENTS
18 ACPI_MODULE_NAME("evxfgpe")
19
20 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
21 /*******************************************************************************
22 *
23 * FUNCTION: acpi_update_all_gpes
24 *
25 * PARAMETERS: None
26 *
27 * RETURN: Status
28 *
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.)
35 *
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
39 * dynamic table load.
40 *
41 ******************************************************************************/
42
acpi_update_all_gpes(void)43 acpi_status acpi_update_all_gpes(void)
44 {
45 acpi_status status;
46 u8 is_polling_needed = FALSE;
47
48 ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
49
50 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
51 if (ACPI_FAILURE(status)) {
52 return_ACPI_STATUS(status);
53 }
54
55 if (acpi_gbl_all_gpes_initialized) {
56 goto unlock_and_exit;
57 }
58
59 status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block,
60 &is_polling_needed);
61 if (ACPI_SUCCESS(status)) {
62 acpi_gbl_all_gpes_initialized = TRUE;
63 }
64
65 unlock_and_exit:
66 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
67
68 if (is_polling_needed && acpi_gbl_all_gpes_initialized) {
69
70 /* Poll GPEs to handle already triggered events */
71
72 acpi_ev_gpe_detect(acpi_gbl_gpe_xrupt_list_head);
73 }
74 return_ACPI_STATUS(status);
75 }
76
ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)77 ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
78
79 /*******************************************************************************
80 *
81 * FUNCTION: acpi_enable_gpe_cond
82 *
83 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
84 * gpe_number - GPE level within the GPE block
85 * dispatch_type - GPE dispatch type to match
86 *
87 * RETURN: Status
88 *
89 * DESCRIPTION: Add a reference to a GPE so long as its dispatch type matches
90 * the supplied one, or it is different from ACPI_GPE_DISPATCH_NONE
91 * if the supplied one is ACPI_GPE_DISPATCH_MASK. On the first
92 * reference, the GPE is hardware-enabled.
93 *
94 ******************************************************************************/
95 acpi_status acpi_enable_gpe_cond(acpi_handle gpe_device, u32 gpe_number,
96 u8 dispatch_type)
97 {
98 acpi_status status = AE_BAD_PARAMETER;
99 struct acpi_gpe_event_info *gpe_event_info;
100 acpi_cpu_flags flags;
101
102 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
103
104 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
105
106 /*
107 * Ensure that we have a valid GPE number and that the dispatch type of
108 * the GPE matches the supplied one (or it is not ACPI_GPE_DISPATCH_NONE
109 * if the supplied one is ACPI_GPE_DISPATCH_MASK).
110 */
111 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
112 if (gpe_event_info) {
113 if (dispatch_type == ACPI_GPE_DISPATCH_MASK)
114 dispatch_type = ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags);
115 else if (dispatch_type != ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags))
116 dispatch_type = ACPI_GPE_DISPATCH_NONE;
117
118 if (dispatch_type != ACPI_GPE_DISPATCH_NONE) {
119 status = acpi_ev_add_gpe_reference(gpe_event_info, TRUE);
120 if (ACPI_SUCCESS(status) &&
121 ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
122
123 /* Poll edge-triggered GPEs to handle existing events */
124
125 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
126 (void)acpi_ev_detect_gpe(gpe_device,
127 gpe_event_info,
128 gpe_number);
129 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
130 }
131 } else {
132 status = AE_NO_HANDLER;
133 }
134 }
135
136 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
137 return_ACPI_STATUS(status);
138 }
ACPI_EXPORT_SYMBOL(acpi_enable_gpe_cond)139 ACPI_EXPORT_SYMBOL(acpi_enable_gpe_cond)
140
141 /*******************************************************************************
142 *
143 * FUNCTION: acpi_enable_gpe
144 *
145 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
146 * gpe_number - GPE level within the GPE block
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
151 * hardware-enabled.
152 *
153 ******************************************************************************/
154 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
155 {
156 /*
157 * Ensure that there is some way of handling the GPE (handler or a GPE
158 * method). In other words, we won't allow a valid GPE to be enabled if
159 * there is no way to handle it.
160 */
161 return acpi_enable_gpe_cond(gpe_device, gpe_number, ACPI_GPE_DISPATCH_MASK);
162 }
ACPI_EXPORT_SYMBOL(acpi_enable_gpe)163 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
164
165 /*******************************************************************************
166 *
167 * FUNCTION: acpi_disable_gpe
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: Remove a reference to a GPE. When the last reference is
175 * removed, only then is the GPE disabled (for runtime GPEs), or
176 * the GPE mask bit disabled (for wake GPEs)
177 *
178 ******************************************************************************/
179
180 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
181 {
182 acpi_status status = AE_BAD_PARAMETER;
183 struct acpi_gpe_event_info *gpe_event_info;
184 acpi_cpu_flags flags;
185
186 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
187
188 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
189
190 /* Ensure that we have a valid GPE number */
191
192 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
193 if (gpe_event_info) {
194 status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
195 }
196
197 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
198 return_ACPI_STATUS(status);
199 }
200
ACPI_EXPORT_SYMBOL(acpi_disable_gpe)201 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
202
203 /*******************************************************************************
204 *
205 * FUNCTION: acpi_set_gpe
206 *
207 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
208 * gpe_number - GPE level within the GPE block
209 * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
210 *
211 * RETURN: Status
212 *
213 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
214 * the reference count mechanism used in the acpi_enable_gpe(),
215 * acpi_disable_gpe() interfaces.
216 * This API is typically used by the GPE raw handler mode driver
217 * to switch between the polling mode and the interrupt mode after
218 * the driver has enabled the GPE.
219 * The APIs should be invoked in this order:
220 * acpi_enable_gpe() <- Ensure the reference count > 0
221 * acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode
222 * acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode
223 * acpi_disable_gpe() <- Decrease the reference count
224 *
225 * Note: If a GPE is shared by 2 silicon components, then both the drivers
226 * should support GPE polling mode or disabling the GPE for long period
227 * for one driver may break the other. So use it with care since all
228 * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
229 *
230 ******************************************************************************/
231 acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
232 {
233 struct acpi_gpe_event_info *gpe_event_info;
234 acpi_status status;
235 acpi_cpu_flags flags;
236
237 ACPI_FUNCTION_TRACE(acpi_set_gpe);
238
239 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
240
241 /* Ensure that we have a valid GPE number */
242
243 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
244 if (!gpe_event_info) {
245 status = AE_BAD_PARAMETER;
246 goto unlock_and_exit;
247 }
248
249 /* Perform the action */
250
251 switch (action) {
252 case ACPI_GPE_ENABLE:
253
254 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
255 gpe_event_info->disable_for_dispatch = FALSE;
256 break;
257
258 case ACPI_GPE_DISABLE:
259
260 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
261 gpe_event_info->disable_for_dispatch = TRUE;
262 break;
263
264 default:
265
266 status = AE_BAD_PARAMETER;
267 break;
268 }
269
270 unlock_and_exit:
271 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
272 return_ACPI_STATUS(status);
273 }
274
ACPI_EXPORT_SYMBOL(acpi_set_gpe)275 ACPI_EXPORT_SYMBOL(acpi_set_gpe)
276
277 /*******************************************************************************
278 *
279 * FUNCTION: acpi_mask_gpe
280 *
281 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
282 * gpe_number - GPE level within the GPE block
283 * is_masked - Whether the GPE is masked or not
284 *
285 * RETURN: Status
286 *
287 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
288 * prevent a GPE flooding.
289 *
290 ******************************************************************************/
291 acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked)
292 {
293 struct acpi_gpe_event_info *gpe_event_info;
294 acpi_status status;
295 acpi_cpu_flags flags;
296
297 ACPI_FUNCTION_TRACE(acpi_mask_gpe);
298
299 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
300
301 /* Ensure that we have a valid GPE number */
302
303 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
304 if (!gpe_event_info) {
305 status = AE_BAD_PARAMETER;
306 goto unlock_and_exit;
307 }
308
309 status = acpi_ev_mask_gpe(gpe_event_info, is_masked);
310
311 unlock_and_exit:
312 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
313 return_ACPI_STATUS(status);
314 }
315
ACPI_EXPORT_SYMBOL(acpi_mask_gpe)316 ACPI_EXPORT_SYMBOL(acpi_mask_gpe)
317
318 /*******************************************************************************
319 *
320 * FUNCTION: acpi_mark_gpe_for_wake
321 *
322 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
323 * gpe_number - GPE level within the GPE block
324 *
325 * RETURN: Status
326 *
327 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
328 * sets the ACPI_GPE_CAN_WAKE flag.
329 *
330 * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
331 * there won't be any notify handlers installed for device wake notifications
332 * from the given GPE (one example is a button GPE in Linux). For these cases,
333 * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
334 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
335 * setup implicit wake notification for it (since there's no handler method).
336 *
337 ******************************************************************************/
338 acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
339 {
340 struct acpi_gpe_event_info *gpe_event_info;
341 acpi_status status = AE_BAD_PARAMETER;
342 acpi_cpu_flags flags;
343
344 ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
345
346 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
347
348 /* Ensure that we have a valid GPE number */
349
350 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
351 if (gpe_event_info) {
352
353 /* Mark the GPE as a possible wake event */
354
355 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
356 status = AE_OK;
357 }
358
359 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
360 return_ACPI_STATUS(status);
361 }
362
ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)363 ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
364
365 /*******************************************************************************
366 *
367 * FUNCTION: acpi_setup_gpe_for_wake
368 *
369 * PARAMETERS: wake_device - Device associated with the GPE (via _PRW)
370 * gpe_device - Parent GPE Device. NULL for GPE0/GPE1
371 * gpe_number - GPE level within the GPE block
372 *
373 * RETURN: Status
374 *
375 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
376 * interface is intended to be used as the host executes the
377 * _PRW methods (Power Resources for Wake) in the system tables.
378 * Each _PRW appears under a Device Object (The wake_device), and
379 * contains the info for the wake GPE associated with the
380 * wake_device.
381 *
382 ******************************************************************************/
383 acpi_status
384 acpi_setup_gpe_for_wake(acpi_handle wake_device,
385 acpi_handle gpe_device, u32 gpe_number)
386 {
387 acpi_status status;
388 struct acpi_gpe_event_info *gpe_event_info;
389 struct acpi_namespace_node *device_node;
390 struct acpi_gpe_notify_info *notify;
391 struct acpi_gpe_notify_info *new_notify;
392 acpi_cpu_flags flags;
393
394 ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
395
396 /* Parameter Validation */
397
398 if (!wake_device) {
399 /*
400 * By forcing wake_device to be valid, we automatically enable the
401 * implicit notify feature on all hosts.
402 */
403 return_ACPI_STATUS(AE_BAD_PARAMETER);
404 }
405
406 /* Handle root object case */
407
408 if (wake_device == ACPI_ROOT_OBJECT) {
409 device_node = acpi_gbl_root_node;
410 } else {
411 device_node =
412 ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
413 }
414
415 /* Validate wake_device is of type Device */
416
417 if (device_node->type != ACPI_TYPE_DEVICE) {
418 return_ACPI_STATUS (AE_BAD_PARAMETER);
419 }
420
421 /*
422 * Allocate a new notify object up front, in case it is needed.
423 * Memory allocation while holding a spinlock is a big no-no
424 * on some hosts.
425 */
426 new_notify = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info));
427 if (!new_notify) {
428 return_ACPI_STATUS(AE_NO_MEMORY);
429 }
430
431 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
432
433 /* Ensure that we have a valid GPE number */
434
435 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
436 if (!gpe_event_info) {
437 status = AE_BAD_PARAMETER;
438 goto unlock_and_exit;
439 }
440
441 /*
442 * If there is no method or handler for this GPE, then the
443 * wake_device will be notified whenever this GPE fires. This is
444 * known as an "implicit notify". Note: The GPE is assumed to be
445 * level-triggered (for windows compatibility).
446 */
447 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
448 ACPI_GPE_DISPATCH_NONE) {
449 /*
450 * This is the first device for implicit notify on this GPE.
451 * Just set the flags here, and enter the NOTIFY block below.
452 */
453 gpe_event_info->flags =
454 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
455 } else if (gpe_event_info->flags & ACPI_GPE_AUTO_ENABLED) {
456 /*
457 * A reference to this GPE has been added during the GPE block
458 * initialization, so drop it now to prevent the GPE from being
459 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
460 */
461 (void)acpi_ev_remove_gpe_reference(gpe_event_info);
462 gpe_event_info->flags &= ~ACPI_GPE_AUTO_ENABLED;
463 }
464
465 /*
466 * If we already have an implicit notify on this GPE, add
467 * this device to the notify list.
468 */
469 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
470 ACPI_GPE_DISPATCH_NOTIFY) {
471
472 /* Ensure that the device is not already in the list */
473
474 notify = gpe_event_info->dispatch.notify_list;
475 while (notify) {
476 if (notify->device_node == device_node) {
477 status = AE_ALREADY_EXISTS;
478 goto unlock_and_exit;
479 }
480 notify = notify->next;
481 }
482
483 /* Add this device to the notify list for this GPE */
484
485 new_notify->device_node = device_node;
486 new_notify->next = gpe_event_info->dispatch.notify_list;
487 gpe_event_info->dispatch.notify_list = new_notify;
488 new_notify = NULL;
489 }
490
491 /* Mark the GPE as a possible wake event */
492
493 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
494 status = AE_OK;
495
496 unlock_and_exit:
497 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
498
499 /* Delete the notify object if it was not used above */
500
501 if (new_notify) {
502 ACPI_FREE(new_notify);
503 }
504 return_ACPI_STATUS(status);
505 }
ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)506 ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
507
508 /*******************************************************************************
509 *
510 * FUNCTION: acpi_set_gpe_wake_mask
511 *
512 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
513 * gpe_number - GPE level within the GPE block
514 * action - Enable or Disable
515 *
516 * RETURN: Status
517 *
518 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
519 * already be marked as a WAKE GPE.
520 *
521 ******************************************************************************/
522
523 acpi_status
524 acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
525 {
526 acpi_status status = AE_OK;
527 struct acpi_gpe_event_info *gpe_event_info;
528 struct acpi_gpe_register_info *gpe_register_info;
529 acpi_cpu_flags flags;
530 u32 register_bit;
531
532 ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
533
534 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
535
536 /*
537 * Ensure that we have a valid GPE number and that this GPE is in
538 * fact a wake GPE
539 */
540 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
541 if (!gpe_event_info) {
542 status = AE_BAD_PARAMETER;
543 goto unlock_and_exit;
544 }
545
546 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
547 status = AE_TYPE;
548 goto unlock_and_exit;
549 }
550
551 gpe_register_info = gpe_event_info->register_info;
552 if (!gpe_register_info) {
553 status = AE_NOT_EXIST;
554 goto unlock_and_exit;
555 }
556
557 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
558
559 /* Perform the action */
560
561 switch (action) {
562 case ACPI_GPE_ENABLE:
563
564 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
565 (u8)register_bit);
566 break;
567
568 case ACPI_GPE_DISABLE:
569
570 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
571 (u8)register_bit);
572 break;
573
574 default:
575
576 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
577 status = AE_BAD_PARAMETER;
578 break;
579 }
580
581 unlock_and_exit:
582 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
583 return_ACPI_STATUS(status);
584 }
585
ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)586 ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
587
588 /*******************************************************************************
589 *
590 * FUNCTION: acpi_clear_gpe
591 *
592 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
593 * gpe_number - GPE level within the GPE block
594 *
595 * RETURN: Status
596 *
597 * DESCRIPTION: Clear an ACPI event (general purpose)
598 *
599 ******************************************************************************/
600 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
601 {
602 acpi_status status = AE_OK;
603 struct acpi_gpe_event_info *gpe_event_info;
604 acpi_cpu_flags flags;
605
606 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
607
608 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
609
610 /* Ensure that we have a valid GPE number */
611
612 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
613 if (!gpe_event_info) {
614 status = AE_BAD_PARAMETER;
615 goto unlock_and_exit;
616 }
617
618 status = acpi_hw_clear_gpe(gpe_event_info);
619
620 unlock_and_exit:
621 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
622 return_ACPI_STATUS(status);
623 }
624
ACPI_EXPORT_SYMBOL(acpi_clear_gpe)625 ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
626
627 /*******************************************************************************
628 *
629 * FUNCTION: acpi_get_gpe_status
630 *
631 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
632 * gpe_number - GPE level within the GPE block
633 * event_status - Where the current status of the event
634 * will be returned
635 *
636 * RETURN: Status
637 *
638 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
639 *
640 ******************************************************************************/
641 acpi_status
642 acpi_get_gpe_status(acpi_handle gpe_device,
643 u32 gpe_number, acpi_event_status *event_status)
644 {
645 acpi_status status = AE_OK;
646 struct acpi_gpe_event_info *gpe_event_info;
647 acpi_cpu_flags flags;
648
649 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
650
651 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
652
653 /* Ensure that we have a valid GPE number */
654
655 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
656 if (!gpe_event_info) {
657 status = AE_BAD_PARAMETER;
658 goto unlock_and_exit;
659 }
660
661 /* Obtain status on the requested GPE number */
662
663 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
664
665 unlock_and_exit:
666 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
667 return_ACPI_STATUS(status);
668 }
669
ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)670 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
671
672 /*******************************************************************************
673 *
674 * FUNCTION: acpi_gispatch_gpe
675 *
676 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
677 * gpe_number - GPE level within the GPE block
678 *
679 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
680 *
681 * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
682 * (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
683 *
684 ******************************************************************************/
685 u32 acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number)
686 {
687 ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
688
689 return acpi_ev_detect_gpe(gpe_device, NULL, gpe_number);
690 }
691
ACPI_EXPORT_SYMBOL(acpi_dispatch_gpe)692 ACPI_EXPORT_SYMBOL(acpi_dispatch_gpe)
693
694 /*******************************************************************************
695 *
696 * FUNCTION: acpi_finish_gpe
697 *
698 * PARAMETERS: gpe_device - Namespace node for the GPE Block
699 * (NULL for FADT defined GPEs)
700 * gpe_number - GPE level within the GPE block
701 *
702 * RETURN: Status
703 *
704 * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
705 * processing. Intended for use by asynchronous host-installed
706 * GPE handlers. The GPE is only re-enabled if the enable_for_run bit
707 * is set in the GPE info.
708 *
709 ******************************************************************************/
710 acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number)
711 {
712 struct acpi_gpe_event_info *gpe_event_info;
713 acpi_status status;
714 acpi_cpu_flags flags;
715
716 ACPI_FUNCTION_TRACE(acpi_finish_gpe);
717
718 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
719
720 /* Ensure that we have a valid GPE number */
721
722 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
723 if (!gpe_event_info) {
724 status = AE_BAD_PARAMETER;
725 goto unlock_and_exit;
726 }
727
728 status = acpi_ev_finish_gpe(gpe_event_info);
729
730 unlock_and_exit:
731 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
732 return_ACPI_STATUS(status);
733 }
734
ACPI_EXPORT_SYMBOL(acpi_finish_gpe)735 ACPI_EXPORT_SYMBOL(acpi_finish_gpe)
736
737 /******************************************************************************
738 *
739 * FUNCTION: acpi_disable_all_gpes
740 *
741 * PARAMETERS: None
742 *
743 * RETURN: Status
744 *
745 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
746 *
747 ******************************************************************************/
748
749 acpi_status acpi_disable_all_gpes(void)
750 {
751 acpi_status status;
752
753 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
754
755 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
756 if (ACPI_FAILURE(status)) {
757 return_ACPI_STATUS(status);
758 }
759
760 status = acpi_hw_disable_all_gpes();
761 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
762
763 return_ACPI_STATUS(status);
764 }
765
ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)766 ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
767
768 /******************************************************************************
769 *
770 * FUNCTION: acpi_enable_all_runtime_gpes
771 *
772 * PARAMETERS: None
773 *
774 * RETURN: Status
775 *
776 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
777 *
778 ******************************************************************************/
779
780 acpi_status acpi_enable_all_runtime_gpes(void)
781 {
782 acpi_status status;
783
784 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
785
786 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
787 if (ACPI_FAILURE(status)) {
788 return_ACPI_STATUS(status);
789 }
790
791 status = acpi_hw_enable_all_runtime_gpes();
792 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
793
794 return_ACPI_STATUS(status);
795 }
796
ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)797 ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
798
799 /******************************************************************************
800 *
801 * FUNCTION: acpi_enable_all_wakeup_gpes
802 *
803 * PARAMETERS: None
804 *
805 * RETURN: Status
806 *
807 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
808 * all GPE blocks.
809 *
810 ******************************************************************************/
811 acpi_status acpi_enable_all_wakeup_gpes(void)
812 {
813 acpi_status status;
814
815 ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes);
816
817 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
818 if (ACPI_FAILURE(status)) {
819 return_ACPI_STATUS(status);
820 }
821
822 status = acpi_hw_enable_all_wakeup_gpes();
823 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
824
825 return_ACPI_STATUS(status);
826 }
827
ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)828 ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)
829
830 /******************************************************************************
831 *
832 * FUNCTION: acpi_any_gpe_status_set
833 *
834 * PARAMETERS: gpe_skip_number - Number of the GPE to skip
835 *
836 * RETURN: Whether or not the status bit is set for any GPE
837 *
838 * DESCRIPTION: Check the status bits of all enabled GPEs, except for the one
839 * represented by the "skip" argument, and return TRUE if any of
840 * them is set or FALSE otherwise.
841 *
842 ******************************************************************************/
843 u32 acpi_any_gpe_status_set(u32 gpe_skip_number)
844 {
845 acpi_status status;
846 acpi_handle gpe_device;
847 u8 ret;
848
849 ACPI_FUNCTION_TRACE(acpi_any_gpe_status_set);
850
851 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
852 if (ACPI_FAILURE(status)) {
853 return (FALSE);
854 }
855
856 status = acpi_get_gpe_device(gpe_skip_number, &gpe_device);
857 if (ACPI_FAILURE(status)) {
858 gpe_device = NULL;
859 }
860
861 ret = acpi_hw_check_all_gpes(gpe_device, gpe_skip_number);
862 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
863
864 return (ret);
865 }
866
ACPI_EXPORT_SYMBOL(acpi_any_gpe_status_set)867 ACPI_EXPORT_SYMBOL(acpi_any_gpe_status_set)
868
869 /*******************************************************************************
870 *
871 * FUNCTION: acpi_install_gpe_block
872 *
873 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
874 * gpe_block_address - Address and space_ID
875 * register_count - Number of GPE register pairs in the block
876 * interrupt_number - H/W interrupt for the block
877 *
878 * RETURN: Status
879 *
880 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
881 * enabled here.
882 *
883 ******************************************************************************/
884 acpi_status
885 acpi_install_gpe_block(acpi_handle gpe_device,
886 struct acpi_generic_address *gpe_block_address,
887 u32 register_count, u32 interrupt_number)
888 {
889 acpi_status status;
890 union acpi_operand_object *obj_desc;
891 struct acpi_namespace_node *node;
892 struct acpi_gpe_block_info *gpe_block;
893
894 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
895
896 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
897 return_ACPI_STATUS(AE_BAD_PARAMETER);
898 }
899
900 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
901 if (ACPI_FAILURE(status)) {
902 return_ACPI_STATUS(status);
903 }
904
905 node = acpi_ns_validate_handle(gpe_device);
906 if (!node) {
907 status = AE_BAD_PARAMETER;
908 goto unlock_and_exit;
909 }
910
911 /* Validate the parent device */
912
913 if (node->type != ACPI_TYPE_DEVICE) {
914 status = AE_TYPE;
915 goto unlock_and_exit;
916 }
917
918 if (node->object) {
919 status = AE_ALREADY_EXISTS;
920 goto unlock_and_exit;
921 }
922
923 /*
924 * For user-installed GPE Block Devices, the gpe_block_base_number
925 * is always zero
926 */
927 status = acpi_ev_create_gpe_block(node, gpe_block_address->address,
928 gpe_block_address->space_id,
929 register_count, 0, interrupt_number,
930 &gpe_block);
931 if (ACPI_FAILURE(status)) {
932 goto unlock_and_exit;
933 }
934
935 /* Install block in the device_object attached to the node */
936
937 obj_desc = acpi_ns_get_attached_object(node);
938 if (!obj_desc) {
939
940 /*
941 * No object, create a new one (Device nodes do not always have
942 * an attached object)
943 */
944 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
945 if (!obj_desc) {
946 status = AE_NO_MEMORY;
947 goto unlock_and_exit;
948 }
949
950 status =
951 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
952
953 /* Remove local reference to the object */
954
955 acpi_ut_remove_reference(obj_desc);
956
957 if (ACPI_FAILURE(status)) {
958 goto unlock_and_exit;
959 }
960 }
961
962 /* Now install the GPE block in the device_object */
963
964 obj_desc->device.gpe_block = gpe_block;
965
966 unlock_and_exit:
967 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
968 return_ACPI_STATUS(status);
969 }
970
ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)971 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
972
973 /*******************************************************************************
974 *
975 * FUNCTION: acpi_remove_gpe_block
976 *
977 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
978 *
979 * RETURN: Status
980 *
981 * DESCRIPTION: Remove a previously installed block of GPE registers
982 *
983 ******************************************************************************/
984 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
985 {
986 union acpi_operand_object *obj_desc;
987 acpi_status status;
988 struct acpi_namespace_node *node;
989
990 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
991
992 if (!gpe_device) {
993 return_ACPI_STATUS(AE_BAD_PARAMETER);
994 }
995
996 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
997 if (ACPI_FAILURE(status)) {
998 return_ACPI_STATUS(status);
999 }
1000
1001 node = acpi_ns_validate_handle(gpe_device);
1002 if (!node) {
1003 status = AE_BAD_PARAMETER;
1004 goto unlock_and_exit;
1005 }
1006
1007 /* Validate the parent device */
1008
1009 if (node->type != ACPI_TYPE_DEVICE) {
1010 status = AE_TYPE;
1011 goto unlock_and_exit;
1012 }
1013
1014 /* Get the device_object attached to the node */
1015
1016 obj_desc = acpi_ns_get_attached_object(node);
1017 if (!obj_desc || !obj_desc->device.gpe_block) {
1018 return_ACPI_STATUS(AE_NULL_OBJECT);
1019 }
1020
1021 /* Delete the GPE block (but not the device_object) */
1022
1023 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
1024 if (ACPI_SUCCESS(status)) {
1025 obj_desc->device.gpe_block = NULL;
1026 }
1027
1028 unlock_and_exit:
1029 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
1030 return_ACPI_STATUS(status);
1031 }
1032
ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)1033 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
1034
1035 /*******************************************************************************
1036 *
1037 * FUNCTION: acpi_get_gpe_device
1038 *
1039 * PARAMETERS: index - System GPE index (0-current_gpe_count)
1040 * gpe_device - Where the parent GPE Device is returned
1041 *
1042 * RETURN: Status
1043 *
1044 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1045 * gpe device indicates that the gpe number is contained in one of
1046 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
1047 *
1048 ******************************************************************************/
1049 acpi_status acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
1050 {
1051 struct acpi_gpe_device_info info;
1052 acpi_status status;
1053
1054 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
1055
1056 if (!gpe_device) {
1057 return_ACPI_STATUS(AE_BAD_PARAMETER);
1058 }
1059
1060 if (index >= acpi_current_gpe_count) {
1061 return_ACPI_STATUS(AE_NOT_EXIST);
1062 }
1063
1064 /* Setup and walk the GPE list */
1065
1066 info.index = index;
1067 info.status = AE_NOT_EXIST;
1068 info.gpe_device = NULL;
1069 info.next_block_base_index = 0;
1070
1071 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
1072 if (ACPI_FAILURE(status)) {
1073 return_ACPI_STATUS(status);
1074 }
1075
1076 *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
1077 return_ACPI_STATUS(info.status);
1078 }
1079
1080 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
1081 #endif /* !ACPI_REDUCED_HARDWARE */
1082