This source file includes following definitions.
- ACPI_MODULE_NAME
- acpi_ev_enable_gpe
- acpi_ev_mask_gpe
- acpi_ev_add_gpe_reference
- acpi_ev_remove_gpe_reference
- acpi_ev_low_get_gpe_info
- acpi_ev_get_gpe_event_info
- acpi_ev_gpe_detect
- acpi_ev_asynch_execute_gpe_method
- acpi_ev_asynch_enable_gpe
- acpi_ev_finish_gpe
- acpi_ev_detect_gpe
- acpi_ev_gpe_dispatch
1
2
3
4
5
6
7
8
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acevents.h"
13 #include "acnamesp.h"
14
15 #define _COMPONENT ACPI_EVENTS
16 ACPI_MODULE_NAME("evgpe")
17 #if (!ACPI_REDUCED_HARDWARE)
18
19 static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
20
21 static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context);
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 acpi_status
37 acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
38 {
39 struct acpi_gpe_register_info *gpe_register_info;
40 u32 register_bit;
41
42 ACPI_FUNCTION_TRACE(ev_update_gpe_enable_mask);
43
44 gpe_register_info = gpe_event_info->register_info;
45 if (!gpe_register_info) {
46 return_ACPI_STATUS(AE_NOT_EXIST);
47 }
48
49 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
50
51
52
53 ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit);
54
55
56
57 if (gpe_event_info->runtime_count) {
58 ACPI_SET_BIT(gpe_register_info->enable_for_run,
59 (u8)register_bit);
60 }
61
62 gpe_register_info->enable_mask = gpe_register_info->enable_for_run;
63 return_ACPI_STATUS(AE_OK);
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77
78 acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
79 {
80 acpi_status status;
81
82 ACPI_FUNCTION_TRACE(ev_enable_gpe);
83
84
85
86 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
87 return_ACPI_STATUS(status);
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 acpi_status
104 acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked)
105 {
106 struct acpi_gpe_register_info *gpe_register_info;
107 u32 register_bit;
108
109 ACPI_FUNCTION_TRACE(ev_mask_gpe);
110
111 gpe_register_info = gpe_event_info->register_info;
112 if (!gpe_register_info) {
113 return_ACPI_STATUS(AE_NOT_EXIST);
114 }
115
116 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
117
118
119
120 if (is_masked) {
121 if (register_bit & gpe_register_info->mask_for_run) {
122 return_ACPI_STATUS(AE_BAD_PARAMETER);
123 }
124
125 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
126 ACPI_SET_BIT(gpe_register_info->mask_for_run, (u8)register_bit);
127 } else {
128 if (!(register_bit & gpe_register_info->mask_for_run)) {
129 return_ACPI_STATUS(AE_BAD_PARAMETER);
130 }
131
132 ACPI_CLEAR_BIT(gpe_register_info->mask_for_run,
133 (u8)register_bit);
134 if (gpe_event_info->runtime_count
135 && !gpe_event_info->disable_for_dispatch) {
136 (void)acpi_hw_low_set_gpe(gpe_event_info,
137 ACPI_GPE_ENABLE);
138 }
139 }
140
141 return_ACPI_STATUS(AE_OK);
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 acpi_status
159 acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info,
160 u8 clear_on_enable)
161 {
162 acpi_status status = AE_OK;
163
164 ACPI_FUNCTION_TRACE(ev_add_gpe_reference);
165
166 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
167 return_ACPI_STATUS(AE_LIMIT);
168 }
169
170 gpe_event_info->runtime_count++;
171 if (gpe_event_info->runtime_count == 1) {
172
173
174
175 if (clear_on_enable) {
176 (void)acpi_hw_clear_gpe(gpe_event_info);
177 }
178
179 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
180 if (ACPI_SUCCESS(status)) {
181 status = acpi_ev_enable_gpe(gpe_event_info);
182 }
183
184 if (ACPI_FAILURE(status)) {
185 gpe_event_info->runtime_count--;
186 }
187 }
188
189 return_ACPI_STATUS(status);
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 acpi_status
206 acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
207 {
208 acpi_status status = AE_OK;
209
210 ACPI_FUNCTION_TRACE(ev_remove_gpe_reference);
211
212 if (!gpe_event_info->runtime_count) {
213 return_ACPI_STATUS(AE_LIMIT);
214 }
215
216 gpe_event_info->runtime_count--;
217 if (!gpe_event_info->runtime_count) {
218
219
220
221 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
222 if (ACPI_SUCCESS(status)) {
223 status =
224 acpi_hw_low_set_gpe(gpe_event_info,
225 ACPI_GPE_DISABLE);
226 }
227
228 if (ACPI_FAILURE(status)) {
229 gpe_event_info->runtime_count++;
230 }
231 }
232
233 return_ACPI_STATUS(status);
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
252 struct acpi_gpe_block_info
253 *gpe_block)
254 {
255 u32 gpe_index;
256
257
258
259
260
261 if (!gpe_block || (gpe_number < gpe_block->block_base_number)) {
262 return (NULL);
263 }
264
265 gpe_index = gpe_number - gpe_block->block_base_number;
266 if (gpe_index >= gpe_block->gpe_count) {
267 return (NULL);
268 }
269
270 return (&gpe_block->event_info[gpe_index]);
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
292 u32 gpe_number)
293 {
294 union acpi_operand_object *obj_desc;
295 struct acpi_gpe_event_info *gpe_info;
296 u32 i;
297
298 ACPI_FUNCTION_ENTRY();
299
300
301
302 if (!gpe_device) {
303
304
305
306 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) {
307 gpe_info = acpi_ev_low_get_gpe_info(gpe_number,
308 acpi_gbl_gpe_fadt_blocks
309 [i]);
310 if (gpe_info) {
311 return (gpe_info);
312 }
313 }
314
315
316
317 return (NULL);
318 }
319
320
321
322 obj_desc =
323 acpi_ns_get_attached_object((struct acpi_namespace_node *)
324 gpe_device);
325 if (!obj_desc || !obj_desc->device.gpe_block) {
326 return (NULL);
327 }
328
329 return (acpi_ev_low_get_gpe_info
330 (gpe_number, obj_desc->device.gpe_block));
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
348 {
349 struct acpi_gpe_block_info *gpe_block;
350 struct acpi_namespace_node *gpe_device;
351 struct acpi_gpe_register_info *gpe_register_info;
352 struct acpi_gpe_event_info *gpe_event_info;
353 u32 gpe_number;
354 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
355 acpi_cpu_flags flags;
356 u32 i;
357 u32 j;
358
359 ACPI_FUNCTION_NAME(ev_gpe_detect);
360
361
362
363 if (!gpe_xrupt_list) {
364 return (int_status);
365 }
366
367
368
369
370
371
372 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
373
374
375
376 gpe_block = gpe_xrupt_list->gpe_block_list_head;
377 while (gpe_block) {
378 gpe_device = gpe_block->node;
379
380
381
382
383
384 for (i = 0; i < gpe_block->register_count; i++) {
385
386
387
388 gpe_register_info = &gpe_block->register_info[i];
389
390
391
392
393
394 if (!(gpe_register_info->enable_for_run |
395 gpe_register_info->enable_for_wake)) {
396 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
397 "Ignore disabled registers for GPE %02X-%02X: "
398 "RunEnable=%02X, WakeEnable=%02X\n",
399 gpe_register_info->
400 base_gpe_number,
401 gpe_register_info->
402 base_gpe_number +
403 (ACPI_GPE_REGISTER_WIDTH - 1),
404 gpe_register_info->
405 enable_for_run,
406 gpe_register_info->
407 enable_for_wake));
408 continue;
409 }
410
411
412
413 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
414
415
416
417 gpe_event_info =
418 &gpe_block->
419 event_info[((acpi_size)i *
420 ACPI_GPE_REGISTER_WIDTH) + j];
421 gpe_number =
422 j + gpe_register_info->base_gpe_number;
423 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
424 int_status |=
425 acpi_ev_detect_gpe(gpe_device,
426 gpe_event_info,
427 gpe_number);
428 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
429 }
430 }
431
432 gpe_block = gpe_block->next;
433 }
434
435 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
436 return (int_status);
437 }
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455 static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
456 {
457 struct acpi_gpe_event_info *gpe_event_info = context;
458 acpi_status status = AE_OK;
459 struct acpi_evaluate_info *info;
460 struct acpi_gpe_notify_info *notify;
461
462 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
463
464
465
466 switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
467 case ACPI_GPE_DISPATCH_NOTIFY:
468
469
470
471
472
473
474
475
476
477
478
479 notify = gpe_event_info->dispatch.notify_list;
480 while (ACPI_SUCCESS(status) && notify) {
481 status =
482 acpi_ev_queue_notify_request(notify->device_node,
483 ACPI_NOTIFY_DEVICE_WAKE);
484
485 notify = notify->next;
486 }
487
488 break;
489
490 case ACPI_GPE_DISPATCH_METHOD:
491
492
493
494 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
495 if (!info) {
496 status = AE_NO_MEMORY;
497 } else {
498
499
500
501
502 info->prefix_node =
503 gpe_event_info->dispatch.method_node;
504 info->flags = ACPI_IGNORE_RETURN_VALUE;
505
506 status = acpi_ns_evaluate(info);
507 ACPI_FREE(info);
508 }
509
510 if (ACPI_FAILURE(status)) {
511 ACPI_EXCEPTION((AE_INFO, status,
512 "while evaluating GPE method [%4.4s]",
513 acpi_ut_get_node_name(gpe_event_info->
514 dispatch.
515 method_node)));
516 }
517 break;
518
519 default:
520
521 goto error_exit;
522 }
523
524
525
526 status = acpi_os_execute(OSL_NOTIFY_HANDLER,
527 acpi_ev_asynch_enable_gpe, gpe_event_info);
528 if (ACPI_SUCCESS(status)) {
529 return_VOID;
530 }
531
532 error_exit:
533 acpi_ev_asynch_enable_gpe(gpe_event_info);
534 return_VOID;
535 }
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
553 {
554 struct acpi_gpe_event_info *gpe_event_info = context;
555 acpi_cpu_flags flags;
556
557 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
558 (void)acpi_ev_finish_gpe(gpe_event_info);
559 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
560
561 return;
562 }
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578 acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info)
579 {
580 acpi_status status;
581
582 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
583 ACPI_GPE_LEVEL_TRIGGERED) {
584
585
586
587
588 status = acpi_hw_clear_gpe(gpe_event_info);
589 if (ACPI_FAILURE(status)) {
590 return (status);
591 }
592 }
593
594
595
596
597
598
599 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE);
600 gpe_event_info->disable_for_dispatch = FALSE;
601 return (AE_OK);
602 }
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625 u32
626 acpi_ev_detect_gpe(struct acpi_namespace_node *gpe_device,
627 struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
628 {
629 u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
630 u8 enabled_status_byte;
631 u64 status_reg;
632 u64 enable_reg;
633 u32 register_bit;
634 struct acpi_gpe_register_info *gpe_register_info;
635 struct acpi_gpe_handler_info *gpe_handler_info;
636 acpi_cpu_flags flags;
637 acpi_status status;
638
639 ACPI_FUNCTION_TRACE(ev_gpe_detect);
640
641 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
642
643 if (!gpe_event_info) {
644 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
645 if (!gpe_event_info)
646 goto error_exit;
647 }
648
649
650
651 gpe_register_info = gpe_event_info->register_info;
652
653
654
655 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
656
657
658
659 status = acpi_hw_read(&enable_reg, &gpe_register_info->enable_address);
660 if (ACPI_FAILURE(status)) {
661 goto error_exit;
662 }
663
664
665
666 status = acpi_hw_read(&status_reg, &gpe_register_info->status_address);
667 if (ACPI_FAILURE(status)) {
668 goto error_exit;
669 }
670
671
672
673 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
674 "Read registers for GPE %02X: Status=%02X, Enable=%02X, "
675 "RunEnable=%02X, WakeEnable=%02X\n",
676 gpe_number,
677 (u32)(status_reg & register_bit),
678 (u32)(enable_reg & register_bit),
679 gpe_register_info->enable_for_run,
680 gpe_register_info->enable_for_wake));
681
682 enabled_status_byte = (u8)(status_reg & enable_reg);
683 if (!(enabled_status_byte & register_bit)) {
684 goto error_exit;
685 }
686
687
688
689 acpi_gpe_count++;
690 if (acpi_gbl_global_event_handler) {
691 acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE,
692 gpe_device, gpe_number,
693 acpi_gbl_global_event_handler_context);
694 }
695
696
697
698 if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
699 ACPI_GPE_DISPATCH_RAW_HANDLER) {
700
701
702
703 gpe_handler_info = gpe_event_info->dispatch.handler;
704
705
706
707
708
709
710
711
712
713
714
715 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
716 int_status |=
717 gpe_handler_info->address(gpe_device, gpe_number,
718 gpe_handler_info->context);
719 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
720 } else {
721
722
723 int_status |= acpi_ev_gpe_dispatch(gpe_device,
724 gpe_event_info, gpe_number);
725 }
726
727 error_exit:
728 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
729 return (int_status);
730 }
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747 u32
748 acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
749 struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
750 {
751 acpi_status status;
752 u32 return_value;
753
754 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
755
756
757
758
759
760
761
762
763
764
765 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
766 if (ACPI_FAILURE(status)) {
767 ACPI_EXCEPTION((AE_INFO, status,
768 "Unable to disable GPE %02X", gpe_number));
769 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
770 }
771
772
773
774
775
776 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
777 ACPI_GPE_EDGE_TRIGGERED) {
778 status = acpi_hw_clear_gpe(gpe_event_info);
779 if (ACPI_FAILURE(status)) {
780 ACPI_EXCEPTION((AE_INFO, status,
781 "Unable to clear GPE %02X",
782 gpe_number));
783 (void)acpi_hw_low_set_gpe(gpe_event_info,
784 ACPI_GPE_CONDITIONAL_ENABLE);
785 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
786 }
787 }
788
789 gpe_event_info->disable_for_dispatch = TRUE;
790
791
792
793
794
795
796
797
798 switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
799 case ACPI_GPE_DISPATCH_HANDLER:
800
801
802
803 return_value =
804 gpe_event_info->dispatch.handler->address(gpe_device,
805 gpe_number,
806 gpe_event_info->
807 dispatch.handler->
808 context);
809
810
811
812 if (return_value & ACPI_REENABLE_GPE) {
813 (void)acpi_ev_finish_gpe(gpe_event_info);
814 }
815 break;
816
817 case ACPI_GPE_DISPATCH_METHOD:
818 case ACPI_GPE_DISPATCH_NOTIFY:
819
820
821
822
823 status = acpi_os_execute(OSL_GPE_HANDLER,
824 acpi_ev_asynch_execute_gpe_method,
825 gpe_event_info);
826 if (ACPI_FAILURE(status)) {
827 ACPI_EXCEPTION((AE_INFO, status,
828 "Unable to queue handler for GPE %02X - event disabled",
829 gpe_number));
830 }
831 break;
832
833 default:
834
835
836
837
838
839 ACPI_ERROR((AE_INFO,
840 "No handler or method for GPE %02X, disabling event",
841 gpe_number));
842
843 break;
844 }
845
846 return_UINT32(ACPI_INTERRUPT_HANDLED);
847 }
848
849 #endif