ReactOS 0.4.17-dev-1190-g4c812f4
event.c
Go to the documentation of this file.
4#include <uacpi/internal/io.h>
13#include <uacpi/acpi.h>
14
15#define UACPI_EVENT_DISABLED 0
16#define UACPI_EVENT_ENABLED 1
17
18#if !defined(UACPI_REDUCED_HARDWARE) && !defined(UACPI_BAREBONES_MODE)
19
20/*
21 * Protects the state of every GPE, as well as the lists that a GPE is found
22 * via. This is the only lock that is taken by the interrupt handler, by the
23 * deferred work that re-enables an event, and by the part of the API that is
24 * allowed to be called from an interrupt context.
25 *
26 * An event that was looked up with nothing but this lock held is only
27 * guaranteed to be there for as long as the lock is held.
28 */
31
32/*
33 * Serializes the API that reconfigures an event, which has to wait for the
34 * in-flight interrupts & work to complete in order to do that safely. The
35 * event lock is dropped while waiting, see wait_for_work_completion_unlocked,
36 * so this is what keeps the event from being reconfigured or freed by someone
37 * else in the meantime.
38 *
39 * Unlike the event lock, this one is never taken by the work itself, which
40 * makes it safe to wait under. It's always acquired before the event lock.
41 */
44
46{
48
51 return ret;
52
56
57 return ret;
58}
59
60static void event_config_unlock(void)
61{
64}
65
66/*
67 * The work that we're waiting for is allowed to take the event lock: a GPE
68 * handler might load a table, in which case we have to match the GPE methods
69 * it has brought in, and a notify handler is free to use most of the event
70 * API. Waiting for it with the event lock held would hang both sides forever.
71 *
72 * The caller must hold both the config & the event lock. Since the latter is
73 * released while we wait, any event state that was looked at prior to this
74 * call must be considered stale.
75 */
77{
81}
82
88};
89
93};
94
97 .status_field = UACPI_REGISTER_FIELD_GBL_STS,
98 .enable_field = UACPI_REGISTER_FIELD_GBL_EN,
99 .enable_mask = ACPI_PM1_EN_GBL_EN_MASK,
100 .status_mask = ACPI_PM1_STS_GBL_STS_MASK,
101 },
103 .status_field = UACPI_REGISTER_FIELD_TMR_STS,
104 .enable_field = UACPI_REGISTER_FIELD_TMR_EN,
105 .enable_mask = ACPI_PM1_EN_TMR_EN_MASK,
106 .status_mask = ACPI_PM1_STS_TMR_STS_MASK,
107 },
109 .status_field = UACPI_REGISTER_FIELD_PWRBTN_STS,
110 .enable_field = UACPI_REGISTER_FIELD_PWRBTN_EN,
111 .enable_mask = ACPI_PM1_EN_PWRBTN_EN_MASK,
112 .status_mask = ACPI_PM1_STS_PWRBTN_STS_MASK,
113 },
115 .status_field = UACPI_REGISTER_FIELD_SLPBTN_STS,
116 .enable_field = UACPI_REGISTER_FIELD_SLPBTN_EN,
117 .enable_mask = ACPI_PM1_EN_SLPBTN_EN_MASK,
118 .status_mask = ACPI_PM1_STS_SLPBTN_STS_MASK,
119 },
121 .status_field = UACPI_REGISTER_FIELD_RTC_STS,
122 .enable_field = UACPI_REGISTER_FIELD_RTC_EN,
123 .enable_mask = ACPI_PM1_EN_RTC_EN_MASK,
124 .status_mask = ACPI_PM1_STS_RTC_STS_MASK,
125 },
126};
127
128static struct fixed_event_handler
130
131/*
132 * Protects the handlers above, as well as the enable bit of every fixed event.
133 *
134 * A handler is installed & removed with the event lock held, but that's not
135 * something the interrupt handler is able to take, and neither is the API
136 * that is allowed to be called from it. This is what they use instead.
137 */
139
141{
143
144 for (i = 0; i <= UACPI_FIXED_EVENT_MAX; ++i) {
146 fixed_events[i].enable_field, UACPI_EVENT_DISABLED
147 );
148 }
149
150 return UACPI_STATUS_OK;
151}
152
154{
156 uacpi_u64 raw_value;
157 const struct fixed_event *ev = &fixed_events[event];
158
161 return ret;
162
163 ret = uacpi_read_register_field(ev->enable_field, &raw_value);
165 return ret;
166
167 if (raw_value != value) {
168 uacpi_error("failed to %sable fixed event %d",
169 value ? "en" : "dis", event);
171 }
172
173 uacpi_trace("fixed event %d %sabled successfully",
174 event, value ? "en" : "dis");
175 return UACPI_STATUS_OK;
176}
177
179{
182
184
185 if (uacpi_unlikely(event < 0 || event > UACPI_FIXED_EVENT_MAX))
188 return UACPI_STATUS_OK;
189
191
192 /*
193 * Attempting to enable an event that doesn't have a handler is most likely
194 * an error, don't allow it. This includes an event that is in the process
195 * of having its handler removed, which is why the check is a part of the
196 * same critical section as the enable.
197 */
200 goto out;
201 }
202
204
205out:
207 return ret;
208}
209
211{
214
216
217 if (uacpi_unlikely(event < 0 || event > UACPI_FIXED_EVENT_MAX))
220 return UACPI_STATUS_OK;
221
225
226 return ret;
227}
228
230{
232
233 if (uacpi_unlikely(event < 0 || event > UACPI_FIXED_EVENT_MAX))
236 return UACPI_STATUS_OK;
237
240 );
241}
242
244{
245 static const uacpi_u8 buttons[] = {
248 };
252
254 return;
255
256 for (i = 0; i < UACPI_ARRAY_SIZE(buttons); ++i) {
257 event = buttons[i];
258
259 /*
260 * The button that has woken us up is still pending at this point. Get
261 * rid of it so that it's not delivered as if it was pressed once again,
262 * which tends to be handled by going right back to sleep, or by
263 * shutting down.
264 */
267 );
268
269 /*
270 * Don't rely on the button still being enabled after the sleep, it
271 * has to be if there's a handler that is waiting for it.
272 *
273 * Same as uacpi_enable_fixed_event, this must not enable a button that
274 * is in the process of having its handler removed.
275 */
280 }
281}
282
284 const struct fixed_event *ev, uacpi_fixed_event event
285)
286{
288 struct fixed_event_handler evh;
289 uacpi_u64 is_enabled;
291
292 /*
293 * The event was enabled at the time we were invoked, but that might not
294 * be the case anymore: it's disabled by whoever is uninstalling its
295 * handler, in which case the handler must not be called, or by someone
296 * who doesn't want to hear from it for now. Take another look with the
297 * lock held, which is also what makes the handler safe to look at.
298 */
300 ret = uacpi_read_register_field(ev->enable_field, &is_enabled);
303
304 if (uacpi_unlikely_error(ret) || !is_enabled)
306
310
311 if (uacpi_unlikely(evh.handler == UACPI_NULL)) {
313 "fixed event %u fired but no handler installed, disabling...",
314 event
315 );
318 }
319
320 return evh.handler(evh.ctx);
321}
322
324{
327 uacpi_u64 enable_mask, status_mask;
329
332 return int_ret;
333
336 return int_ret;
337
338 for (i = 0; i <= UACPI_FIXED_EVENT_MAX; ++i)
339 {
340 const struct fixed_event *ev = &fixed_events[i];
341
342 if (!(status_mask & ev->status_mask) ||
343 !(enable_mask & ev->enable_mask))
344 continue;
345
346 int_ret |= dispatch_fixed_event(ev, i);
347 }
348
349 return int_ret;
350}
351
355
356 /*
357 * Preserved values to be used for state restoration if this handler is
358 * removed at any point.
359 */
364};
365
369};
370
371#define EVENTS_PER_GPE_REGISTER 8
372
373/*
374 * NOTE:
375 * This API and handler types are inspired by ACPICA, let's not reinvent the
376 * wheel and follow a similar path that people ended up finding useful after
377 * years of dealing with ACPI. Obviously credit goes to them for inventing
378 * "implicit notify" and other neat API.
379 */
386};
387
388struct gp_event {
389 union {
394 };
395
397
398 /*
399 * What the deferred work for this event is scheduled with. This is done
400 * by the interrupt handler, which is no place to be allocating anything,
401 * so an event gets one as soon as it's given a handler that needs it.
402 */
404
406
410
411 /*
412 * Set for an event that has a user that it was given automatically when
413 * the GPE initialization was finalized, which is taken away from it once
414 * it's set up for wake.
415 */
417
418 /*
419 * Everything below is the state of the event, which unlike the above is
420 * also modified by the interrupt handler & the deferred work, neither of
421 * which is able to take the event lock. It's protected by the GPE state
422 * spinlock instead, and is the reason why none of it is a part of the
423 * bitfield above.
424 */
425
426 // "reference count" of the number of times this event has been enabled
428
429 /*
430 * Set for an event that is to stay disabled no matter how many users it
431 * has: one that is being handled at the moment, or one that was suspended.
432 */
434
435 /*
436 * Set for as long as the work item is in use, from the moment the event
437 * is dispatched and until it's restored.
438 */
440
441 /*
442 * Set for an event that was dispatched without having its status cleared,
443 * which is left until it's restored. This is decided at the time that the
444 * event is dispatched: the way it's triggered might get replaced along
445 * with its handler while it's still being handled.
446 */
448};
449
453
454 /*
455 * The masks below, as well as the enable register itself, are protected
456 * by the GPE state spinlock, see the note in struct gp_event.
457 */
462
463 /*
464 * The events that were enabled at any point since they were last known to
465 * be quiescent, and might therefore still be in use by an interrupt
466 * handler or by the work that it has scheduled, even if they're disabled
467 * by now.
468 */
470
472};
473
474struct gpe_block {
476
477 /*
478 * Technically this can only refer to \_GPE, but there's also apparently a
479 * "GPE Block Device" with id "ACPI0006", which is not used by anyone. We
480 * still keep it as a possibility that someone might eventually use it, so
481 * it is supported here.
482 */
484
488
492
493 // Set once the events of this block have been enabled by the finalization
495};
496
499
503};
505
507{
508 return 1 << (event->idx - event->reg->base_idx);
509}
510
515};
516
517// Must be called with the GPE state lock held
519 struct gp_event *event, enum gpe_state state
520)
521{
523 struct gpe_register *reg = event->reg;
524 uacpi_u64 enable_mask;
525 uacpi_u8 event_bit;
526
527 event_bit = gpe_get_mask(event);
528 if (state != GPE_STATE_DISABLED && (reg->masked_mask & event_bit))
529 return UACPI_STATUS_OK;
530
532 if (!(reg->current_mask & event_bit))
533 return UACPI_STATUS_OK;
534
536 }
537
538 ret = uacpi_gas_read_mapped(&reg->enable, &enable_mask);
540 return ret;
541
542 switch (state) {
544 enable_mask |= event_bit;
545 reg->armed_mask |= event_bit;
546 break;
548 enable_mask &= ~event_bit;
549 break;
550 default:
552 }
553
554 return uacpi_gas_write_mapped(&reg->enable, enable_mask);
555}
556
558{
561
565
566 return ret;
567}
568
570{
571 struct gpe_register *reg = event->reg;
572
573 return uacpi_gas_write_mapped(&reg->status, gpe_get_mask(event));
574}
575
577{
580
582 ret = (event->reg->armed_mask & gpe_get_mask(event)) != 0;
584
585 return ret;
586}
587
588static void gpe_disarm(struct gp_event *event)
589{
591
593 event->reg->armed_mask &= ~gpe_get_mask(event);
595}
596
597// Must be called with the GPE state lock held
599{
601
602 /*
603 * A level triggered event is cleared once it's been handled. It might not
604 * be level triggered anymore if its handler was replaced in the meantime,
605 * so go by what it was when it was dispatched as well.
606 */
607 if (event->clear_on_restore ||
608 event->triggering == UACPI_GPE_TRIGGERING_LEVEL) {
611 return ret;
612 }
613
615 event->block_interrupts = UACPI_FALSE;
616 event->clear_on_restore = UACPI_FALSE;
617
618 return ret;
619}
620
622{
625
629
630 return ret;
631}
632
633static void gpe_work_done(struct gp_event *event)
634{
636
638 event->work_item_in_use = UACPI_FALSE;
640}
641
643{
645 struct gp_event *event = opaque;
646
647 /*
648 * This is the last thing that we need the work item for, so the event is
649 * free to make use of it again as soon as it's enabled below.
650 */
652
655 uacpi_error("unable to restore GPE(%02X): %s",
657 }
658}
659
661{
663 struct gp_event *event = opaque;
664
667 goto out_no_unlock;
668
669 switch (event->handler_type) {
671 uacpi_object *method_obj;
673
675 event->aml_handler, UACPI_OBJECT_METHOD_BIT
676 );
677 if (uacpi_unlikely(method_obj == UACPI_NULL)) {
678 uacpi_error("GPE(%02X) AML handler gone", event->idx);
679 break;
680 }
681
682 name = uacpi_namespace_node_name(event->aml_handler);
684 "executing GPE(%02X) handler %.4s",
685 event->idx, name.text
686 );
687
689 event->aml_handler, method_obj->method, UACPI_NULL, UACPI_NULL
690 );
693 "error while executing GPE(%02X) handler %.4s: %s",
694 event->idx, event->aml_handler->name.text,
696 );
697 }
698 break;
699 }
700
703
704 handler = event->implicit_handler;
705 while (handler) {
706 /*
707 * 2 - Device Wake. Used to notify OSPM that the device has signaled
708 * its wake event, and that OSPM needs to notify OSPM native device
709 * driver for the device.
710 */
711 uacpi_notify_all(handler->device, 2);
712
713 /*
714 * The namespace is unlocked for a moment while the notification
715 * is being scheduled, which is all it takes for a table that has
716 * a method for this event to get loaded. The list is gone in that
717 * case, and so is the need to notify anyone else.
718 */
719 if (event->handler_type != GPE_HANDLER_TYPE_IMPLICIT_NOTIFY)
720 break;
721
722 handler = handler->next;
723 }
724 break;
725 }
726
727 default:
728 break;
729 }
730
732
733out_no_unlock:
734 /*
735 * We schedule the work as NOTIFICATION to make sure all other notifications
736 * finish before this GPE is re-enabled.
737 *
738 * The work item is the one that we're being executed as: it's ours to
739 * reuse now that we were invoked, and it's not needed for anything else
740 * until the event is restored.
741 */
744 );
745}
746
748 // The handler of the interrupt that the event has raised
750
751 // Whoever has enabled the event, and is checking if it's pending already
753};
754
755/*
756 * Makes sure that an event is only ever dispatched by one of those who notice
757 * that it's pending, which besides the interrupt handler might be someone who
758 * is polling it, possibly on a different CPU.
759 *
760 * This is done by disabling the event if it's both pending and enabled, with
761 * the lock held from the moment it's looked at and until it's disabled. Anyone
762 * else finds it disabled, and leaves it alone. A raw handler is the exception:
763 * the event is not ours to manage in that case, so it's only checked for being
764 * able to fire to begin with, and is otherwise left the way it was found.
765 *
766 * That leaves us with nothing to tell that such an event was already taken
767 * care of, so it's never claimed by a poll: a raw handler is only ever invoked
768 * for an interrupt, and is expected to do any polling that it needs itself.
769 */
771 struct gp_event *event, enum gpe_dispatcher dispatcher,
772 uacpi_u8 *out_handler_type, uacpi_u8 *out_triggering,
773 uacpi_bool *out_did_claim
774)
775{
777 struct gpe_register *reg = event->reg;
779 uacpi_u8 event_bit;
781
782 *out_did_claim = UACPI_FALSE;
783 event_bit = gpe_get_mask(event);
784
786
787 /*
788 * The caller goes by this snapshot, as the handler might be replaced as
789 * soon as we let go of the lock. It's always replaced with the lock held,
790 * which is also what orders these loads against whoever has set it up,
791 * possibly on a different CPU just now.
792 */
793 *out_handler_type = event->handler_type;
794 *out_triggering = event->triggering;
795
796 ret = uacpi_gas_read_mapped(&reg->status, &status);
798 goto out;
799
800 ret = uacpi_gas_read_mapped(&reg->enable, &enable);
802 goto out;
803
804 if (!(status & enable & event_bit))
805 goto out;
806
807 if (*out_handler_type == GPE_HANDLER_TYPE_NATIVE_HANDLER_RAW) {
808 *out_did_claim = dispatcher == GPE_DISPATCHER_INTERRUPT;
809 goto out;
810 }
811
812 ret = uacpi_gas_write_mapped(&reg->enable, enable & ~event_bit);
814 event->block_interrupts = UACPI_TRUE;
815
816 if (*out_triggering == UACPI_GPE_TRIGGERING_LEVEL)
817 event->clear_on_restore = UACPI_TRUE;
818
819 *out_did_claim = UACPI_TRUE;
820 }
821
822out:
824 return ret;
825}
826
828 uacpi_namespace_node *device_node, struct gp_event *event,
829 enum gpe_dispatcher dispatcher
830)
831{
834 uacpi_u8 handler_type, triggering;
835 uacpi_bool did_claim, in_use;
837
839 event, dispatcher, &handler_type, &triggering, &did_claim
840 );
842 uacpi_error("failed to claim GPE(%02X): %s",
844 return int_ret;
845 }
846
847 // Either someone else got to it first, or there's nothing to handle
848 if (!did_claim)
849 return int_ret;
850
851 /*
852 * For raw handlers we don't do any management whatsoever, we just let the
853 * handler know a GPE has triggered and let it handle disable/enable as
854 * well as clearing.
855 */
856 if (handler_type == GPE_HANDLER_TYPE_NATIVE_HANDLER_RAW) {
857 return event->native_handler->cb(
858 event->native_handler->ctx, device_node, event->idx
859 );
860 }
861
862 if (handler_type == GPE_HANDLER_TYPE_AML_HANDLER ||
863 handler_type == GPE_HANDLER_TYPE_IMPLICIT_NOTIFY) {
864 /*
865 * A work item must never be scheduled while it's still pending. The
866 * event stays disabled until it's restored, so this only happens if
867 * it was enabled behind our back while still being handled, e.g. via
868 * uacpi_resume_gpe or uacpi_enable_all_runtime_gpes.
869 *
870 * Leave it both disabled & pending in that case: it fires again as
871 * soon as it's restored, which is when the work item is free.
872 */
874 in_use = event->work_item_in_use;
875 event->work_item_in_use = UACPI_TRUE;
877
878 if (uacpi_unlikely(in_use))
880 }
881
885 uacpi_error("unable to clear GPE(%02X): %s",
887
888 // No work was scheduled, see above
889 if (handler_type == GPE_HANDLER_TYPE_AML_HANDLER ||
890 handler_type == GPE_HANDLER_TYPE_IMPLICIT_NOTIFY)
892
893 /*
894 * Nobody is going to handle this event, which means that nobody is
895 * going to restore it either, so undo all of the claim.
896 */
899 event->block_interrupts = UACPI_FALSE;
901
902 return int_ret;
903 }
904 }
905
906 switch (handler_type) {
908 int_ret = event->native_handler->cb(
909 event->native_handler->ctx, device_node, event->idx
910 );
911 if (!(int_ret & UACPI_GPE_REENABLE))
912 break;
913
916 uacpi_error("unable to restore GPE(%02X): %s",
918 }
919 break;
920
925 event
926 );
927 break;
928
929 default:
930 uacpi_warn("GPE(%02X) fired but no handler, keeping disabled",
931 event->idx);
932 break;
933 }
934
936}
937
938/*
939 * The lists of interrupt contexts & blocks are modified with both the event
940 * lock and the GPE state lock held, so having either one is enough to walk
941 * them.
942 *
943 * The interrupt handlers walk the blocks with no locks at all though. A block
944 * is fully initialized before it's linked in, and is only freed after every
945 * interrupt handler that might've been looking at it at the time it was
946 * unlinked has returned.
947 */
948static struct gpe_block *load_gpe_block(struct gpe_block **block)
949{
950 return (struct gpe_block*)uacpi_atomic_load_ptr(block);
951}
952
954 struct gpe_interrupt_ctx *ctx, enum gpe_dispatcher dispatcher
955)
956{
959 struct gpe_block *block;
960 struct gpe_register *reg;
961 struct gp_event *event;
963 uacpi_size i, j;
964 uacpi_bool is_unused;
966
967 block = load_gpe_block(&ctx->gpe_head);
968
969 while (block) {
970 for (i = 0; i < block->num_registers; ++i) {
971 reg = &block->registers[i];
972
974 is_unused = !reg->runtime_mask && !reg->wake_mask;
976
977 if (is_unused)
978 continue;
979
980 ret = uacpi_gas_read_mapped(&reg->status, &status);
982 return int_ret;
983
984 ret = uacpi_gas_read_mapped(&reg->enable, &enable);
986 return int_ret;
987
988 if (status == 0)
989 continue;
990
991 for (j = 0; j < EVENTS_PER_GPE_REGISTER; ++j) {
992 if (!((status & enable) & (1ull << j)))
993 continue;
994
995 event = &block->events[j + i * EVENTS_PER_GPE_REGISTER];
996 int_ret |= dispatch_gpe(
997 block->device_node, event, dispatcher
998 );
999 }
1000 }
1001
1002 block = load_gpe_block(&block->next);
1003 }
1004
1005 return int_ret;
1006}
1007
1009 uacpi_namespace_node *gpe_device, struct gp_event *event
1010)
1011{
1013 struct gpe_register *reg = event->reg;
1015
1016 ret = uacpi_gas_read_mapped(&reg->status, &status);
1018 return ret;
1019
1020 if (!(status & gpe_get_mask(event)))
1021 return ret;
1022
1024 return ret;
1025}
1026
1028{
1029 struct gpe_interrupt_ctx *ctx = opaque;
1030
1033
1035}
1036
1038 uacpi_u32 irq, struct gpe_interrupt_ctx **out_ctx
1039)
1040{
1044
1045 while (entry) {
1046 if (entry->irq == irq) {
1047 *out_ctx = entry;
1048 return UACPI_STATUS_OK;
1049 }
1050
1051 entry = entry->next;
1052 }
1053
1057
1058 /*
1059 * SCI interrupt is installed by other code and is responsible for more
1060 * things than just the GPE handling. Don't install it here.
1061 */
1062 if (irq != g_uacpi_rt_ctx.fadt.sci_int) {
1064 irq, handle_gpes, entry, &entry->irq_handle
1065 );
1067 uacpi_free(entry, sizeof(*entry));
1068 return ret;
1069 }
1070 }
1071
1072 entry->irq = irq;
1073
1080
1081 *out_ctx = entry;
1082 return UACPI_STATUS_OK;
1083}
1084
1085/*
1086 * Makes sure the context is no longer used by anyone, it's up to the caller to
1087 * free it once that's safe to do. The event lock is dropped while the handler
1088 * of the context is being uninstalled.
1089 */
1091{
1093
1095
1096 if (ctx->prev != UACPI_NULL)
1097 ctx->prev->next = ctx->next;
1098 else
1099 g_gpe_interrupt_head = ctx->next;
1100
1101 if (ctx->next != UACPI_NULL)
1102 ctx->next->prev = ctx->prev;
1103
1105
1106 /*
1107 * This might have to wait for the handler to return, and the handler is
1108 * free to take the lock, so it can't be done with it held.
1109 *
1110 * The same goes for the event lock: the handler might be executing the
1111 * work that it has scheduled right away, and that is free to end up
1112 * waiting for it, e.g. by loading a table. Everything that the handler
1113 * is still able to get to stays around until the caller has waited for
1114 * it, so there's nothing for it to break in the meantime.
1115 */
1116 if (ctx->irq != g_uacpi_rt_ctx.fadt.sci_int) {
1119 handle_gpes, ctx->irq_handle
1120 );
1122 }
1123}
1124
1126{
1127 if (event->work_item != UACPI_NULL)
1128 return UACPI_STATUS_OK;
1129
1130 event->work_item = uacpi_kernel_create_work_item();
1131 if (uacpi_unlikely(event->work_item == UACPI_NULL))
1133
1134 return UACPI_STATUS_OK;
1135}
1136
1138{
1139 struct gpe_implicit_notify_handler *handler, *next_handler;
1140
1141 handler = event->implicit_handler;
1142 while (handler) {
1143 next_handler = handler->next;
1144 uacpi_free(handler, sizeof(*handler));
1145 handler = next_handler;
1146 }
1147
1148 event->implicit_handler = UACPI_NULL;
1149}
1150
1152{
1157};
1158
1161)
1162{
1164 uacpi_size i;
1166 struct gpe_register *reg;
1168
1169 for (i = 0; i < block->num_registers; ++i) {
1170 reg = &block->registers[i];
1171
1173 ret = uacpi_gas_write_mapped(&reg->status, 0xFF);
1175 return ret;
1176 continue;
1177 }
1178
1179 /*
1180 * This is one critical section on purpose: the mask that we pick must
1181 * still be the one that is in effect by the time it's written to the
1182 * register.
1183 */
1185
1186 switch (action) {
1188 value = reg->runtime_mask;
1189 break;
1191 value = reg->wake_mask;
1192 break;
1193 default:
1194 value = 0;
1195 break;
1196 }
1197
1198 reg->current_mask = value;
1199
1200 /*
1201 * A masked event is kept disabled for as long as we're running, but
1202 * it still counts as enabled as far as the current mask goes. This is
1203 * what allows it to be enabled as soon as it's unmasked.
1204 */
1206 value &= ~reg->masked_mask;
1207
1208 reg->armed_mask |= value;
1209 ret = uacpi_gas_write_mapped(&reg->enable, value);
1211
1213 return ret;
1214 }
1215
1216 return UACPI_STATUS_OK;
1217}
1218
1219/*
1220 * Releases a block that is not reachable by anyone: it's either not installed
1221 * yet, or was unlinked with everything that might've been using it long gone.
1222 */
1223static void free_gpe_block(struct gpe_block *block)
1224{
1225 if (block->registers != UACPI_NULL) {
1226 struct gpe_register *reg;
1227 uacpi_size i;
1228
1229 for (i = 0; i < block->num_registers; ++i) {
1230 reg = &block->registers[i];
1231
1232 if (reg->enable.total_bit_width)
1233 uacpi_unmap_gas_nofree(&reg->enable);
1234 if (reg->status.total_bit_width)
1235 uacpi_unmap_gas_nofree(&reg->status);
1236 }
1237 }
1238
1239 if (block->events != UACPI_NULL) {
1240 uacpi_size i;
1241 struct gp_event *event;
1242 struct gpe_native_handler *native_handler;
1243
1244 for (i = 0; i < block->num_events; ++i) {
1245 event = &block->events[i];
1246
1247 switch (event->handler_type) {
1250 break;
1251
1254 native_handler = event->native_handler;
1255
1256 /*
1257 * The handler that this one has replaced is still around in
1258 * case this one gets uninstalled, so we have to free it as
1259 * well.
1260 */
1261 if (native_handler->previous_handler_type ==
1263 event->implicit_handler = native_handler->previous_handler;
1265 }
1266
1267 uacpi_free(native_handler, sizeof(*native_handler));
1268 break;
1269
1272 break;
1273 }
1274
1275 default:
1276 break;
1277 }
1278
1279 if (event->work_item != UACPI_NULL)
1281 }
1282
1283 }
1284
1285 uacpi_free(block->registers,
1286 sizeof(*block->registers) * block->num_registers);
1287 uacpi_free(block->events,
1288 sizeof(*block->events) * block->num_events);
1289 uacpi_free(block, sizeof(*block));
1290}
1291
1292/*
1293 * This must be called with the config & event locks held, the latter is
1294 * dropped while we wait.
1295 */
1297{
1298 struct gpe_interrupt_ctx *ctx = block->irq_ctx;
1299 uacpi_bool ctx_is_unused;
1301 uacpi_size i;
1302
1303 /*
1304 * 1. Mask the GPEs, this makes sure their state is no longer modifyable
1305 *
1306 * This is done for every register up front: we drop the event lock while
1307 * waiting below, and nobody should be able to enable an event in the
1308 * meantime. The one thing that still is, which is enabling an event for
1309 * wake, is the reason why the events are only disabled after the wait.
1310 */
1312 for (i = 0; i < block->num_registers; ++i)
1313 block->registers[i].masked_mask = 0xFF;
1315
1316 /*
1317 * 2. Wait for in-flight work & IRQs to finish, these might already
1318 * be past the respective "if (masked)" check and therefore may
1319 * try to re-enable a masked GPE.
1320 */
1322
1323 /*
1324 * 3. Now that the state of these GPEs is unmodifyable and we know that
1325 * currently in-flight IRQs will see the masked state, we can safely
1326 * disable all events knowing they won't be re-enabled by a racing IRQ.
1327 */
1328 for (i = 0; i < block->num_registers; ++i) {
1329 /*
1330 * An interrupt handler that is disabling one of the events right now
1331 * does so by reading the register and writing it back with one bit
1332 * cleared. Don't let it undo what we do here.
1333 */
1335 uacpi_gas_write_mapped(&block->registers[i].enable, 0x00);
1337 }
1338
1339 // 4. Make sure the interrupt handler is no longer able to find the block
1341
1342 if (block == ctx->gpe_head) {
1343 uacpi_atomic_store_ptr(&ctx->gpe_head, block->next);
1344 } else {
1345 struct gpe_block *prev_block = ctx->gpe_head;
1346
1347 while (prev_block) {
1348 if (prev_block->next == block) {
1349 uacpi_atomic_store_ptr(&prev_block->next, block->next);
1350 break;
1351 }
1352
1353 prev_block = prev_block->next;
1354 }
1355 }
1356
1358
1359 /*
1360 * This GPE block was the last user of this interrupt context, remove it
1361 *
1362 * The context of the SCI is an exception: it's what the SCI handler
1363 * uses to find the blocks to dispatch, so it stays around for as long
1364 * as the handler does.
1365 */
1366 ctx_is_unused = ctx->gpe_head == UACPI_NULL &&
1367 ctx->irq != g_uacpi_rt_ctx.fadt.sci_int;
1368 if (ctx_is_unused)
1370
1371 /*
1372 * 5. Wait for the last possible IRQ to finish, as well as any work that
1373 * still refers to one of the events.
1374 *
1375 * This is done no matter what: an interrupt handler that was invoked for
1376 * some other block might've been looking at this one right as we were
1377 * unlinking it, and an event that is disabled by now might still have
1378 * work in flight from back when it wasn't.
1379 */
1381
1382 if (ctx_is_unused)
1383 uacpi_free(ctx, sizeof(*ctx));
1384
1386}
1387
1389{
1391
1392 if (idx < block->base_idx)
1393 return UACPI_NULL;
1394
1395 offset = idx - block->base_idx;
1396 if (offset >= block->num_events)
1397 return UACPI_NULL;
1398
1399 return &block->events[offset];
1400}
1401
1406};
1407
1408/*
1409 * The interrupt handler looks at the handler of an event, as well as at how
1410 * it's triggered, with the GPE state lock held, so that's what both have to
1411 * be replaced under for it to see them in their entirety.
1412 */
1416)
1417{
1419
1421 event->any_handler = handler;
1422 event->handler_type = type;
1423 event->triggering = triggering;
1425}
1426
1427/*
1428 * An event that was claimed by the interrupt handler stays blocked until it's
1429 * restored, which is up to whoever is handling it. If the handler is replaced
1430 * while that is still the case there's nobody left to do that, and it's not
1431 * something that the next handler would know to do either, so the claim has
1432 * to go along with the handler that it was made for.
1433 *
1434 * This is only safe to do for an event that is quiescent.
1435 */
1436static void gpe_drop_claim(struct gp_event *event)
1437{
1439
1441 event->block_interrupts = UACPI_FALSE;
1442 event->clear_on_restore = UACPI_FALSE;
1444}
1445
1446/*
1447 * An event that is configured for implicit notify might be in use at the
1448 * moment: its work looks at the handler with the namespace locked, and the
1449 * interrupt handler does so with the GPE state lock held. We can't wait for
1450 * either one to be done with it, as it might be that very work that got us
1451 * here by loading a table, so take both locks instead.
1452 */
1455)
1456{
1458
1461 return ret;
1462
1463 /*
1464 * This had implicit notify configured but this is no longer needed as we
1465 * now have an actual AML handler. Free the implicit notify list and switch
1466 * this handler to AML mode.
1467 */
1468 if (event->handler_type == GPE_HANDLER_TYPE_IMPLICIT_NOTIFY)
1470
1472
1474 return UACPI_STATUS_OK;
1475}
1476
1479)
1480{
1482 struct gpe_match_ctx *ctx = opaque;
1483 struct gp_event *event;
1485 uacpi_u64 idx;
1486
1488
1489 if (node->name.text[0] != '_')
1491
1492 switch (node->name.text[1]) {
1493 case 'L':
1495 break;
1496 case 'E':
1498 break;
1499 default:
1501 }
1502
1503 ret = uacpi_string_to_integer(&node->name.text[2], 2, UACPI_BASE_HEX, &idx);
1505 uacpi_trace("invalid GPE method name %.4s, ignored", node->name.text);
1507 }
1508
1509 event = gpe_from_block(ctx->block, idx);
1510 if (event == UACPI_NULL)
1512
1513 if (event->handler_type == GPE_HANDLER_TYPE_NONE ||
1514 event->handler_type == GPE_HANDLER_TYPE_IMPLICIT_NOTIFY) {
1515 // The method is executed as deferred work, make sure that's possible
1518 uacpi_warn(
1519 "unable to assign GPE(%02X) to %.4s: %s", (uacpi_u32)idx,
1520 node->name.text, uacpi_status_to_string(ret)
1521 );
1523 }
1524 }
1525
1526 switch (event->handler_type) {
1531 uacpi_warn(
1532 "unable to assign GPE(%02X) to %.4s: %s", (uacpi_u32)idx,
1533 node->name.text, uacpi_status_to_string(ret)
1534 );
1536 }
1537 break;
1538
1540 // This is okay, since we're re-running the detection code
1541 if (!ctx->post_dynamic_table_load) {
1542 uacpi_warn(
1543 "GPE(%02X) already matched %.4s, skipping %.4s",
1544 (uacpi_u32)idx, event->aml_handler->name.text, node->name.text
1545 );
1546 }
1548
1552 "not assigning GPE(%02X) to %.4s, override "
1553 "installed by user", (uacpi_u32)idx, node->name.text
1554 );
1556 default:
1558 }
1559
1560 uacpi_trace("assigned GPE(%02X) -> %.4s",
1561 (uacpi_u32)idx, node->name.text);
1562 ctx->matched_count++;
1563
1565}
1566
1568{
1569 struct gpe_match_ctx match_ctx = {
1571 };
1572 struct gpe_interrupt_ctx *irq_ctx;
1573
1575 return;
1576
1578
1580 goto out_no_unlock;
1581
1582 irq_ctx = g_gpe_interrupt_head;
1583
1584 while (irq_ctx) {
1585 match_ctx.block = irq_ctx->gpe_head;
1586
1587 while (match_ctx.block) {
1589 match_ctx.block->device_node, do_match_gpe_methods, UACPI_NULL,
1592 );
1593 match_ctx.block = match_ctx.block->next;
1594 }
1595
1596 irq_ctx = irq_ctx->next;
1597 }
1598
1599 if (match_ctx.matched_count) {
1600 uacpi_info("matched %u additional GPEs post dynamic table load",
1601 match_ctx.matched_count);
1602 }
1603
1605
1606out_no_unlock:
1608}
1609
1611 uacpi_namespace_node *device_node, uacpi_u32 irq, uacpi_u16 base_idx,
1613)
1614{
1616 struct gpe_match_ctx match_ctx = { 0 };
1617 struct gpe_block *block;
1618 struct gpe_register *reg;
1619 struct gp_event *event;
1620 struct acpi_gas tmp_gas = { 0 };
1621 uacpi_size i, j;
1622 uacpi_u32 num_events;
1624
1625 if (uacpi_unlikely(num_registers == 0))
1627
1628 // An event is identified by a 16-bit index
1630 if (uacpi_unlikely(base_idx + num_events > 0xFFFF))
1632
1633 tmp_gas.address_space_id = address_space_id;
1634 tmp_gas.register_bit_width = 8;
1635
1638 return ret;
1639
1640 block->device_node = device_node;
1641 block->base_idx = base_idx;
1642
1643 block->num_registers = num_registers;
1644 block->registers = uacpi_kernel_alloc_zeroed(
1645 num_registers * sizeof(*block->registers)
1646 );
1647 if (uacpi_unlikely(block->registers == UACPI_NULL))
1648 goto error_out;
1649
1652 block->num_events * sizeof(*block->events)
1653 );
1654 if (uacpi_unlikely(block->events == UACPI_NULL))
1655 goto error_out;
1656
1657 for (reg = block->registers, event = block->events, i = 0;
1658 i < num_registers; ++i, ++reg) {
1659
1660 /*
1661 * Initialize this register pair as well as all the events within it.
1662 *
1663 * Each register has two sub registers: status & enable, 8 bits each.
1664 * Each bit corresponds to one event that we initialize below.
1665 */
1666 reg->base_idx = base_idx + (i * EVENTS_PER_GPE_REGISTER);
1667
1668
1669 tmp_gas.address = address + i;
1670 ret = uacpi_map_gas_noalloc(&tmp_gas, &reg->status);
1672 goto error_out;
1673
1674 tmp_gas.address += num_registers;
1675 ret = uacpi_map_gas_noalloc(&tmp_gas, &reg->enable);
1677 goto error_out;
1678
1679 for (j = 0; j < EVENTS_PER_GPE_REGISTER; ++j, ++event) {
1680 event->idx = reg->base_idx + j;
1681 event->reg = reg;
1682 }
1683
1684 /*
1685 * Disable all GPEs in this register & clear anything that might be
1686 * pending from earlier.
1687 */
1688 ret = uacpi_gas_write_mapped(&reg->enable, 0x00);
1690 goto error_out;
1691
1692 ret = uacpi_gas_write_mapped(&reg->status, 0xFF);
1694 goto error_out;
1695 }
1696
1699 goto error_out;
1700
1701 match_ctx.block = block;
1702
1704 device_node, do_match_gpe_methods, UACPI_NULL,
1707 );
1708
1709 // The block is complete, make it visible to the interrupt handler
1711 block->next = block->irq_ctx->gpe_head;
1712 uacpi_atomic_store_ptr(&block->irq_ctx->gpe_head, block);
1714
1715 /*
1716 * The events of this block are only enabled once the initialization is
1717 * finalized. Make sure that happens even if it's been done before, which
1718 * is the case for a block that is installed at runtime.
1719 */
1721
1722 uacpi_trace("initialized GPE block %.4s[%d->%d], %u AML handlers (IRQ %u)",
1723 device_node->name.text, base_idx, base_idx + block->num_events,
1724 match_ctx.matched_count, irq);
1725 return UACPI_STATUS_OK;
1726
1727error_out:
1728 // The block is not visible to anyone at this point, so just get rid of it
1730 return ret;
1731}
1732
1734 (struct gpe_block*, uacpi_handle);
1735
1738)
1739{
1740 uacpi_iteration_decision decision;
1741 struct gpe_interrupt_ctx *irq_ctx = g_gpe_interrupt_head;
1742 struct gpe_block *block;
1743
1744 while (irq_ctx) {
1745 block = irq_ctx->gpe_head;
1746
1747 while (block) {
1748 decision = cb(block, handle);
1749 if (decision == UACPI_ITERATION_DECISION_BREAK)
1750 return;
1751
1752 block = block->next;
1753 }
1754
1755 irq_ctx = irq_ctx->next;
1756 }
1757}
1758
1764};
1765
1767 struct gpe_block *block, uacpi_handle opaque
1768)
1769{
1770 struct gpe_search_ctx *ctx = opaque;
1771
1772 if (block->device_node != ctx->gpe_device)
1774
1775 ctx->out_block = block;
1776 ctx->out_event = gpe_from_block(block, ctx->idx);
1777 if (ctx->out_event == UACPI_NULL)
1779
1781}
1782
1783static struct gp_event *get_gpe(
1785)
1786{
1787 struct gpe_search_ctx ctx = { 0 };
1788
1789 ctx.gpe_device = gpe_device;
1790 ctx.idx = idx;
1791
1793 return ctx.out_event;
1794}
1795
1797{
1798 uacpi_u8 this_mask;
1799 struct gpe_register *reg = event->reg;
1800
1801 this_mask = gpe_get_mask(event);
1802
1803 if (set_on) {
1804 reg->runtime_mask |= this_mask;
1805 reg->current_mask = reg->runtime_mask;
1806 return;
1807 }
1808
1809 reg->runtime_mask &= ~this_mask;
1810 reg->current_mask = reg->runtime_mask;
1811}
1812
1813// Must be called with the GPE state lock held
1815{
1817
1818 if (uacpi_unlikely(event->num_users == 0))
1820
1821 if (--event->num_users == 0) {
1823
1827 event->num_users++;
1828 }
1829 }
1830
1831 return ret;
1832}
1833
1835{
1838
1842
1843 return ret;
1844}
1845
1849};
1850
1852 struct gp_event *event, enum event_clear_if_first clear_if_first,
1853 uacpi_bool *out_is_first
1854)
1855{
1858
1859 *out_is_first = UACPI_FALSE;
1860
1862
1863 if (uacpi_unlikely(event->num_users == 0xFF)) {
1865 goto out;
1866 }
1867
1868 if (++event->num_users == 1) {
1869 if (clear_if_first == EVENT_CLEAR_IF_FIRST_YES)
1871
1873
1877 event->num_users--;
1878 goto out;
1879 }
1880
1881 *out_is_first = UACPI_TRUE;
1882 }
1883
1884out:
1886 return ret;
1887}
1888
1891)
1892{
1893 switch (triggering) {
1895 return "edge";
1897 return "level";
1898 default:
1899 return "invalid";
1900 }
1901}
1902
1903/*
1904 * Some hardware doesn't raise an interrupt for an edge triggered event that
1905 * is already pending by the time it's enabled, so it has to be checked for by
1906 * hand. That's only the case for the user that got it enabled: it's up to the
1907 * interrupt handler from there on.
1908 */
1910 struct gp_event *event, uacpi_bool is_first_user
1911)
1912{
1913 return is_first_user && event->triggering == UACPI_GPE_TRIGGERING_EDGE;
1914}
1915
1916/*
1917 * Mask the event, and get it to the point where it's no longer in use by
1918 * anyone. The event lock is dropped while we wait.
1919 *
1920 * This fails if the event couldn't be disabled, in which case it's still
1921 * masked, and it's up to the caller to decide what to do about that.
1922 */
1924{
1927
1928 // 1. Mask the GPE, this makes sure its state is no longer modifyable
1930 event->reg->masked_mask |= gpe_get_mask(event);
1932
1933 /*
1934 * 2. Wait for in-flight work & IRQs to finish, these might already
1935 * be past the respective "if (masked)" check and therefore may
1936 * try to re-enable a masked GPE.
1937 */
1939
1940 do {
1941 /*
1942 * 3. Now that this GPE's state is unmodifyable and we know that
1943 * currently in-flight IRQs will see the masked state, we can safely
1944 * disable this event knowing it won't be re-enabled by a racing
1945 * IRQ.
1946 */
1948
1949 /*
1950 * An event that we were not able to disable is free to fire for as
1951 * long as it wants to, so there's no getting it to quiesce.
1952 */
1954 uacpi_error("failed to disable GPE(%02X): %s",
1956 return ret;
1957 }
1958
1959 /*
1960 * Whatever is still using this event is taken care of by the wait
1961 * below, so it only has to be flushed again if it gets enabled from
1962 * here on.
1963 */
1965
1966 /*
1967 * 4. Wait for the last possible IRQ to finish, now that this event is
1968 * disabled.
1969 */
1971
1972 /*
1973 * The event lock is dropped while we wait, and there's one thing that
1974 * is able to enable a masked event, which is enabling it for wake. If
1975 * that happened in the meantime, none of the above is true anymore.
1976 * It can't happen for as long as we hold the lock though, so do this
1977 * until it doesn't.
1978 */
1979 } while (gpe_is_armed(event));
1980
1981 return UACPI_STATUS_OK;
1982}
1983
1985 struct gp_event *event, uacpi_bool should_mask
1986)
1987{
1989 struct gpe_register *reg;
1990 uacpi_u8 mask;
1991 uacpi_bool is_masked;
1993
1994 reg = event->reg;
1996
1998
1999 is_masked = (reg->masked_mask & mask) != 0;
2000 if (is_masked == should_mask) {
2002 goto out;
2003 }
2004
2005 if (!should_mask) {
2006 reg->masked_mask &= ~mask;
2007
2008 if (!event->block_interrupts && event->num_users) {
2011 );
2012 }
2013
2014 // Still masked as far as everyone is concerned, so this can be retried
2016 reg->masked_mask |= mask;
2017 }
2018
2019out:
2021
2022 if (!should_mask || uacpi_unlikely_error(ret))
2023 return ret;
2024
2025 // This has to wait for the event to quiesce, so can't be done above
2027
2028 // An event that is still able to fire is not masked in any way that counts
2031
2032 return ret;
2033}
2034
2035/*
2036 * Safely mask the event before we modify its handlers.
2037 *
2038 * This makes sure we can't get an IRQ in the middle of modifying this
2039 * event's structures.
2040 *
2041 * NOTE: the event lock is dropped while we wait for the event to quiesce, so
2042 * anything other than the native handlers, which are protected by the
2043 * config lock, may change by the time this returns.
2044 *
2045 * This fails if the event couldn't be made quiescent, in which case it's left
2046 * the way it was found, and none of its structures are safe to modify.
2047 */
2049 struct gp_event *event, uacpi_bool *out_did_mask
2050)
2051{
2053 struct gpe_register *reg = event->reg;
2054 uacpi_u8 mask;
2055 uacpi_bool was_masked, is_armed;
2057
2059
2060 /*
2061 * Mask the event before looking at anything else: an event that is not
2062 * masked can be enabled by anyone at any moment, with nothing but the
2063 * state lock held.
2064 *
2065 * If the event was already masked by the user it's not up to us to unmask
2066 * it once we're done.
2067 */
2069 was_masked = (reg->masked_mask & mask) != 0;
2070 reg->masked_mask |= mask;
2071 is_armed = (reg->armed_mask & mask) != 0;
2073
2074 *out_did_mask = !was_masked;
2075
2076 /*
2077 * No need to flush if it was never enabled since the last time we did
2078 * that. Note that it's not enough for the event to be disabled right now:
2079 * the work that was scheduled for it earlier might still be pending.
2080 *
2081 * This is done even if the event was masked by the user, as there's one
2082 * way for a masked event to end up enabled, which is being enabled for
2083 * wake.
2084 */
2085 if (!is_armed)
2086 return UACPI_STATUS_OK;
2087
2090 // Leave the event the way we have found it
2091 if (!was_masked)
2093
2094 *out_did_mask = UACPI_FALSE;
2095 }
2096
2097 return ret;
2098}
2099
2101 struct gpe_block *block, uacpi_handle opaque
2102)
2103{
2105 uacpi_bool *poll_blocks = opaque;
2106 uacpi_size i, j, count_enabled = 0;
2107 struct gp_event *event;
2108 uacpi_bool is_first_user;
2110
2111 // Already taken care of by one of the previous calls
2112 if (block->finalized)
2114
2115 for (i = 0; i < block->num_registers; ++i) {
2116 for (j = 0; j < EVENTS_PER_GPE_REGISTER; ++j) {
2117 event = &block->events[j + i * EVENTS_PER_GPE_REGISTER];
2118
2119 if (event->wake ||
2120 event->handler_type != GPE_HANDLER_TYPE_AML_HANDLER)
2121 continue;
2122
2123 ret = gpe_add_user(
2124 event, EVENT_CLEAR_IF_FIRST_NO, &is_first_user
2125 );
2127 uacpi_warn("failed to enable GPE(%02X): %s",
2129 continue;
2130 }
2131
2132 // This shares a byte with the handler type, see gpe_set_handler
2134 event->has_auto_user = UACPI_TRUE;
2136
2137 *poll_blocks |= gpe_needs_polling(event, is_first_user);
2138 count_enabled++;
2139 }
2140 }
2141
2142 if (count_enabled) {
2143 uacpi_info(
2144 "enabled %zu GPEs in block %.4s@[%d->%d]",
2145 count_enabled, block->device_node->name.text,
2146 block->base_idx, block->base_idx + block->num_events
2147 );
2148 }
2149
2150 block->finalized = UACPI_TRUE;
2152}
2153
2155{
2157 uacpi_bool poll_blocks = UACPI_FALSE;
2158 struct gpe_interrupt_ctx *irq_ctx;
2159
2161
2163 return UACPI_STATUS_OK;
2164
2167 return ret;
2168
2169 if (g_gpes_finalized)
2170 goto out;
2171
2173
2175 if (poll_blocks) {
2176 irq_ctx = g_gpe_interrupt_head;
2177
2178 while (irq_ctx) {
2180 irq_ctx = irq_ctx->next;
2181 }
2182 }
2183
2184out:
2186 return ret;
2187}
2188
2190 uacpi_namespace_node **gpe_device, uacpi_u16 idx,
2191 struct gp_event **out_event
2192)
2193{
2194 if (*gpe_device == UACPI_NULL) {
2195 *gpe_device = uacpi_namespace_get_predefined(
2197 );
2198 }
2199
2200 *out_event = get_gpe(*gpe_device, idx);
2201 if (*out_event == UACPI_NULL)
2203
2204 return UACPI_STATUS_OK;
2205}
2206
2208 uacpi_namespace_node *gpe_device, uacpi_u16 idx,
2211)
2212{
2214 struct gp_event *event;
2215 struct gpe_native_handler *native_handler;
2216 uacpi_bool did_mask;
2217
2219
2222
2225
2228 return ret;
2229
2230 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2232 goto out;
2233
2234 if (event->handler_type == GPE_HANDLER_TYPE_NATIVE_HANDLER ||
2235 event->handler_type == GPE_HANDLER_TYPE_NATIVE_HANDLER_RAW) {
2237 goto out;
2238 }
2239
2240 native_handler = uacpi_kernel_alloc(sizeof(*native_handler));
2241 if (uacpi_unlikely(native_handler == UACPI_NULL)) {
2243 goto out;
2244 }
2245
2246 native_handler->cb = handler;
2247 native_handler->ctx = ctx;
2248
2249 ret = gpe_mask_safe(event, &did_mask);
2251 uacpi_free(native_handler, sizeof(*native_handler));
2252 goto out;
2253 }
2254
2255 /*
2256 * Only look at the current handler after the event is masked, as it might
2257 * get replaced while we wait, e.g. if a table that was loaded dynamically
2258 * has brought in a GPE method for it.
2259 */
2260 native_handler->previous_handler = event->any_handler;
2261 native_handler->previous_handler_type = event->handler_type;
2262 native_handler->previous_triggering = event->triggering;
2263 native_handler->previously_enabled = UACPI_FALSE;
2264
2265 if ((event->handler_type == GPE_HANDLER_TYPE_AML_HANDLER ||
2266 event->handler_type == GPE_HANDLER_TYPE_IMPLICIT_NOTIFY) &&
2268 native_handler->previously_enabled = UACPI_TRUE;
2269
2270 if (uacpi_unlikely(event->triggering != triggering)) {
2271 uacpi_warn(
2272 "GPE(%02X) user handler claims %s triggering, originally "
2273 "configured as %s", idx,
2276 );
2277 }
2278 }
2279
2280 gpe_set_handler(event, native_handler, type, triggering);
2282
2283 if (did_mask)
2285out:
2287 return ret;
2288}
2289
2291 uacpi_namespace_node *gpe_device, uacpi_u16 idx,
2294)
2295{
2298 handler, ctx
2299 );
2300}
2301
2303 uacpi_namespace_node *gpe_device, uacpi_u16 idx,
2306)
2307{
2310 handler, ctx
2311 );
2312}
2313
2315 uacpi_namespace_node *gpe_device, uacpi_u16 idx,
2317)
2318{
2320 struct gp_event *event;
2321 struct gpe_native_handler *native_handler;
2322 uacpi_bool did_mask, is_first_user = UACPI_FALSE;
2323
2325
2328
2331 return ret;
2332
2333 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2335 goto out;
2336
2337 if (event->handler_type != GPE_HANDLER_TYPE_NATIVE_HANDLER &&
2338 event->handler_type != GPE_HANDLER_TYPE_NATIVE_HANDLER_RAW) {
2340 goto out;
2341 }
2342
2343 native_handler = event->native_handler;
2344 if (uacpi_unlikely(native_handler->cb != handler)) {
2346 goto out;
2347 }
2348
2349 ret = gpe_mask_safe(event, &did_mask);
2351 goto out;
2352
2353 /*
2354 * The handler that we're about to bring back gets the user that was taken
2355 * away from it, which is only ever done for an AML or an implicit notify
2356 * one. This is the one thing here that might not work out, as an event
2357 * only has room for so many, so do it while there's still nothing to
2358 * undo. The event is masked, so it's not enabled until we're done.
2359 */
2360 if (native_handler->previously_enabled) {
2361 ret = gpe_add_user(event, EVENT_CLEAR_IF_FIRST_NO, &is_first_user);
2363 goto out_unmask;
2364 }
2365
2367 event, native_handler->previous_handler,
2368 native_handler->previous_handler_type,
2369 native_handler->previous_triggering
2370 );
2372
2373 uacpi_free(native_handler, sizeof(*native_handler));
2374
2375out_unmask:
2376 if (did_mask)
2378
2379 /*
2380 * An event that we had to mask was disabled for as long as it took to
2381 * replace its handler, so it's no different from one that was only now
2382 * enabled by getting its first user: it might've become pending without
2383 * anyone noticing.
2384 */
2385 if (gpe_needs_polling(event, is_first_user || did_mask))
2386 maybe_dispatch_gpe(gpe_device, event);
2387out:
2389 return ret;
2390}
2391
2394)
2395{
2397 struct gp_event *event;
2398 uacpi_bool is_first_user;
2399
2401
2404
2405 /*
2406 * Unlike the rest of the API that manages a single event, this takes the
2407 * event lock: an event that is already pending is dispatched by us right
2408 * here, and the lock is what keeps it from being reconfigured or freed
2409 * while that is being done.
2410 */
2413 return ret;
2414
2415 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2417 goto out;
2418
2419 if (uacpi_unlikely(event->handler_type == GPE_HANDLER_TYPE_NONE)) {
2421 goto out;
2422 }
2423
2424 ret = gpe_add_user(event, EVENT_CLEAR_IF_FIRST_YES, &is_first_user);
2426 goto out;
2427
2428 if (gpe_needs_polling(event, is_first_user))
2429 maybe_dispatch_gpe(gpe_device, event);
2430
2431out:
2433 return ret;
2434}
2435
2438)
2439{
2441 struct gp_event *event;
2443
2445
2448
2450
2451 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2453 goto out;
2454
2456out:
2458 return ret;
2459}
2460
2463)
2464{
2466 struct gp_event *event;
2468
2470
2473
2475
2476 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2478 goto out;
2479
2480 ret = clear_gpe(event);
2481out:
2483 return ret;
2484}
2485
2488)
2489{
2491 struct gp_event *event;
2493
2495
2498
2500
2501 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2503 goto out;
2504
2505 event->block_interrupts = state == GPE_STATE_DISABLED;
2507out:
2509 return ret;
2510}
2511
2514)
2515{
2516 return gpe_suspend_resume(gpe_device, idx, GPE_STATE_DISABLED);
2517}
2518
2521)
2522{
2523 return gpe_suspend_resume(gpe_device, idx, GPE_STATE_ENABLED);
2524}
2525
2528)
2529{
2531 struct gp_event *event;
2533
2535
2538
2540
2541 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2543 goto out;
2544
2546out:
2548 return ret;
2549}
2550
2552 uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_bool should_mask
2553)
2554{
2556 struct gp_event *event;
2557
2559
2562
2565 return ret;
2566
2567 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2569 goto out;
2570
2571 ret = gpe_mask_unmask(event, should_mask);
2572
2573out:
2575 return ret;
2576}
2577
2580)
2581{
2582 return gpe_get_mask_unmask(gpe_device, idx, UACPI_TRUE);
2583}
2584
2587)
2588{
2589 return gpe_get_mask_unmask(gpe_device, idx, UACPI_FALSE);
2590}
2591
2593 uacpi_namespace_node *gpe_device, uacpi_u16 idx,
2594 uacpi_namespace_node *wake_device
2595)
2596{
2598 struct gp_event *event;
2599 uacpi_bool did_mask;
2601
2603
2606
2607 if (wake_device != UACPI_NULL) {
2608 uacpi_bool is_dev = wake_device == uacpi_namespace_root();
2609
2610 if (!is_dev) {
2611 ret = uacpi_namespace_node_is(wake_device, UACPI_OBJECT_DEVICE, &is_dev);
2613 return ret;
2614 }
2615
2616 if (!is_dev)
2618 }
2619
2622 return ret;
2623
2624 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2626 goto out;
2627
2628 ret = gpe_mask_safe(event, &did_mask);
2630 goto out;
2631
2632 if (wake_device != UACPI_NULL) {
2633 struct gpe_implicit_notify_handler *implicit_handler;
2634 uacpi_u8 num_users;
2635
2636 switch (event->handler_type) {
2638 implicit_handler = event->implicit_handler;
2639 while (implicit_handler) {
2640 if (implicit_handler->device == wake_device) {
2642 goto out_unmask;
2643 }
2644
2645 implicit_handler = implicit_handler->next;
2646 }
2649 /*
2650 * This GPE has no known AML handler, so we configure it to receive
2651 * implicit notifications for wake devices when we get a
2652 * corresponding GPE triggered. Usually it's the job of a matching
2653 * AML handler, but we didn't find any.
2654 *
2655 * The device is notified via deferred work, so get everything
2656 * that it takes ready before the event is touched: there's nothing
2657 * to undo this way if any of it fails.
2658 */
2659 implicit_handler = uacpi_kernel_alloc(sizeof(*implicit_handler));
2660 if (uacpi_unlikely(implicit_handler == UACPI_NULL)) {
2662 goto out_unmask;
2663 }
2664
2667 uacpi_free(implicit_handler, sizeof(*implicit_handler));
2668 goto out_unmask;
2669 }
2670
2671 if (event->handler_type == GPE_HANDLER_TYPE_NONE) {
2675 );
2676 }
2677
2678 implicit_handler->device = wake_device;
2679 implicit_handler->next = event->implicit_handler;
2680 event->implicit_handler = implicit_handler;
2681 break;
2682
2684 /*
2685 * An AML handler already exists, we expect it to call Notify() as
2686 * it sees fit. For now just make sure this event is disabled if it
2687 * had been enabled automatically previously during initialization.
2688 *
2689 * This is only done for the user that it was given back then: any
2690 * other one belongs to somebody else, and is not ours to take.
2691 */
2692 if (!event->has_auto_user)
2693 break;
2694
2695 /*
2696 * The user might be gone already if the event was disabled by
2697 * someone who has never enabled it, in which case there's nothing
2698 * left to take away. Otherwise only forget about it if it was
2699 * actually removed.
2700 */
2702 num_users = event->num_users;
2703 if (uacpi_likely(num_users != 0))
2706 event->has_auto_user = UACPI_FALSE;
2708
2709 if (uacpi_unlikely(num_users == 0))
2710 uacpi_warn("inconsistent use count for GPE(%02X)", event->idx);
2711
2713 goto out_unmask;
2714 break;
2715
2718 uacpi_warn(
2719 "not configuring implicit notify for GPE(%02X) -> %.4s: "
2720 "a user handler already installed", event->idx,
2721 wake_device->name.text
2722 );
2723 break;
2724
2725 default:
2726 uacpi_warn("invalid GPE(%02X) handler type: %d",
2727 event->idx, event->handler_type);
2729 goto out_unmask;
2730 }
2731 }
2732
2733 // This shares a byte with the above, so the same goes for it as well
2735 event->wake = UACPI_TRUE;
2737
2738out_unmask:
2739 if (did_mask)
2741out:
2743 return ret;
2744}
2745
2748)
2749{
2751 struct gp_event *event;
2752 struct gpe_register *reg;
2753 uacpi_u8 mask;
2755
2757
2760
2762
2763 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
2765 goto out;
2766
2767 if (!event->wake) {
2769 goto out;
2770 }
2771
2772 reg = event->reg;
2774
2775 if (enabled)
2776 reg->wake_mask |= mask;
2777 else
2778 reg->wake_mask &= ~mask;
2779
2780out:
2782 return ret;
2783}
2784
2787)
2788{
2789 return gpe_enable_disable_for_wake(gpe_device, idx, UACPI_TRUE);
2790}
2791
2794)
2795{
2796 return gpe_enable_disable_for_wake(gpe_device, idx, UACPI_FALSE);
2797}
2798
2802};
2803
2805 struct gpe_block *block, uacpi_handle opaque
2806)
2807{
2808 struct do_for_all_gpes_ctx *ctx = opaque;
2809
2810 ctx->ret = gpe_block_apply_action(block, ctx->action);
2811 if (uacpi_unlikely_error(ctx->ret))
2813
2815}
2816
2818{
2820
2822
2825
2828 return ret;
2829
2831
2833 return ctx->ret;
2834}
2835
2837{
2838 struct do_for_all_gpes_ctx ctx = {
2840 };
2841 return for_all_gpes_locked(&ctx);
2842}
2843
2845{
2846 struct do_for_all_gpes_ctx ctx = {
2848 };
2849 return for_all_gpes_locked(&ctx);
2850}
2851
2853{
2854 struct do_for_all_gpes_ctx ctx = {
2856 };
2857 return for_all_gpes_locked(&ctx);
2858}
2859
2861{
2863 uacpi_namespace_node *gpe_node;
2864 struct acpi_fadt *fadt = &g_uacpi_rt_ctx.fadt;
2865 uacpi_u8 gpe0_regs = 0, gpe1_regs = 0;
2866
2868
2869 if (fadt->x_gpe0_blk.address && fadt->gpe0_blk_len) {
2870 gpe0_regs = fadt->gpe0_blk_len / 2;
2871
2873 gpe_node, fadt->sci_int, 0, fadt->x_gpe0_blk.address,
2874 fadt->x_gpe0_blk.address_space_id, gpe0_regs
2875 );
2877 uacpi_error("unable to create FADT GPE block 0: %s",
2879 }
2880 }
2881
2882 if (fadt->x_gpe1_blk.address && fadt->gpe1_blk_len) {
2883 gpe1_regs = fadt->gpe1_blk_len / 2;
2884
2885 if (uacpi_unlikely((gpe0_regs * EVENTS_PER_GPE_REGISTER) >
2886 fadt->gpe1_base)) {
2888 "FADT GPE block 1 [%d->%d] collides with GPE block 0 "
2889 "[%d->%d], ignoring",
2890 0, gpe0_regs * EVENTS_PER_GPE_REGISTER, fadt->gpe1_base,
2891 gpe1_regs * EVENTS_PER_GPE_REGISTER
2892 );
2893 gpe1_regs = 0;
2894 goto out;
2895 }
2896
2898 gpe_node, fadt->sci_int, fadt->gpe1_base, fadt->x_gpe1_blk.address,
2899 fadt->x_gpe1_blk.address_space_id, gpe1_regs
2900 );
2902 uacpi_error("unable to create FADT GPE block 1: %s",
2904 }
2905 }
2906
2907 if (gpe0_regs == 0 && gpe1_regs == 0)
2908 uacpi_trace("platform has no FADT GPE events");
2909
2910out:
2911 return UACPI_STATUS_OK;
2912}
2913
2917)
2918{
2920 uacpi_bool is_dev;
2921
2923
2926
2927 ret = uacpi_namespace_node_is(gpe_device, UACPI_OBJECT_DEVICE, &is_dev);
2929 return ret;
2930 if (!is_dev)
2932
2935 return ret;
2936
2937 if (uacpi_unlikely(get_gpe(gpe_device, 0) != UACPI_NULL)) {
2939 goto out;
2940 }
2941
2943 gpe_device, irq, 0, address, address_space, num_registers
2944 );
2945
2946out:
2948 return ret;
2949}
2950
2952 uacpi_namespace_node *gpe_device
2953)
2954{
2956 uacpi_bool is_dev;
2957 struct gpe_search_ctx search_ctx = { 0 };
2958
2959 search_ctx.idx = 0;
2960 search_ctx.gpe_device = gpe_device;
2961
2963
2966
2969 return ret;
2970 if (!is_dev)
2972
2975 return ret;
2976
2977 for_each_gpe_block(do_find_gpe, &search_ctx);
2978 if (search_ctx.out_block == UACPI_NULL) {
2980 goto out;
2981 }
2982
2983 uninstall_gpe_block(search_ctx.out_block);
2984
2985out:
2987 return ret;
2988}
2989
2991{
2994
2995 if (uacpi_unlikely(!g_uacpi_rt_ctx.has_global_lock)) {
2996 uacpi_warn("platform has no global lock but a release event "
2997 "was fired anyway?");
2999 }
3000
3001 flags = uacpi_kernel_lock_spinlock(g_uacpi_rt_ctx.global_lock_spinlock);
3002 if (!g_uacpi_rt_ctx.global_lock_pending) {
3003 uacpi_trace("spurious firmware global lock release notification");
3004 goto out;
3005 }
3006
3007 uacpi_trace("received a firmware global lock release notification");
3008
3009 uacpi_signal_native_event(g_uacpi_rt_ctx.global_lock_event);
3010 g_uacpi_rt_ctx.global_lock_pending = UACPI_FALSE;
3011
3012out:
3013 uacpi_kernel_unlock_spinlock(g_uacpi_rt_ctx.global_lock_spinlock, flags);
3015}
3016
3018{
3020
3021 int_ret |= handle_fixed_events();
3022 int_ret |= handle_gpes(ctx);
3023
3024 return int_ret;
3025}
3026
3028{
3030
3032 return UACPI_STATUS_OK;
3033
3037
3041
3044 return ret;
3045
3048 return ret;
3049
3052 return ret;
3053
3054 return UACPI_STATUS_OK;
3055}
3056
3058{
3060 struct gpe_interrupt_ctx *sci_ctx;
3061
3063 return UACPI_STATUS_OK;
3064
3065 ret = initialize_gpes();
3067 return ret;
3068
3069 /*
3070 * The SCI handler is responsible for every GPE block that shares its
3071 * interrupt. Make sure it has a context to look for them in even if the
3072 * FADT doesn't describe any, as one might still be installed later on.
3073 */
3075 g_uacpi_rt_ctx.fadt.sci_int, &sci_ctx
3076 );
3078 return ret;
3079
3081 g_uacpi_rt_ctx.fadt.sci_int, handle_sci, sci_ctx,
3082 &g_uacpi_rt_ctx.sci_handle
3083 );
3086 "unable to install SCI interrupt handler: %s",
3088 );
3089 return ret;
3090 }
3091 g_uacpi_rt_ctx.sci_handle_valid = UACPI_TRUE;
3092
3093 g_uacpi_rt_ctx.global_lock_event = uacpi_create_native_event();
3094 if (uacpi_unlikely(g_uacpi_rt_ctx.global_lock_event == UACPI_NULL))
3096
3097 g_uacpi_rt_ctx.global_lock_spinlock = uacpi_kernel_create_spinlock();
3098 if (uacpi_unlikely(g_uacpi_rt_ctx.global_lock_spinlock == UACPI_NULL))
3100
3103 );
3107 uacpi_warn("platform has global lock but no FACS was provided");
3108 return ret;
3109 }
3110 g_uacpi_rt_ctx.has_global_lock = UACPI_TRUE;
3111 } else if (ret == UACPI_STATUS_HARDWARE_TIMEOUT) {
3112 // has_global_lock remains set to false
3113 uacpi_trace("platform has no global lock");
3115 }
3116
3117 return ret;
3118}
3119
3121{
3122 struct gpe_interrupt_ctx *ctx, *next_ctx = g_gpe_interrupt_head;
3123 uacpi_size i;
3124 uacpi_bool locked;
3125
3127 return;
3128
3130
3131 if (g_uacpi_rt_ctx.sci_handle_valid) {
3133 handle_sci, g_uacpi_rt_ctx.sci_handle
3134 );
3135 g_uacpi_rt_ctx.sci_handle_valid = UACPI_FALSE;
3136 }
3137
3138 /*
3139 * The locks don't exist if we never got far enough to initialize them, but
3140 * that also means there are no GPE blocks that we would need them for.
3141 */
3143
3144 while (next_ctx) {
3145 struct gpe_block *block, *next_block;
3146 uacpi_bool is_sci_ctx;
3147
3148 ctx = next_ctx;
3149 next_ctx = ctx->next;
3150 is_sci_ctx = ctx->irq == g_uacpi_rt_ctx.fadt.sci_int;
3151
3152 next_block = ctx->gpe_head;
3153 while (next_block) {
3154 block = next_block;
3155 next_block = block->next;
3157 }
3158
3159 /*
3160 * Any other context is gone at this point, as it's removed along with
3161 * the last block that was using it.
3162 */
3163 if (is_sci_ctx) {
3165 uacpi_free(ctx, sizeof(*ctx));
3166 }
3167 }
3168
3169 if (locked)
3171
3172 for (i = 0; i <= UACPI_FIXED_EVENT_MAX; ++i) {
3175 }
3176
3180 }
3181
3185 }
3186
3189
3191}
3192
3196)
3197{
3199 struct fixed_event_handler *ev;
3201
3203
3204 if (uacpi_unlikely(event < 0 || event > UACPI_FIXED_EVENT_MAX))
3207 return UACPI_STATUS_OK;
3208
3211 return ret;
3212
3214
3216
3217 if (ev->handler != UACPI_NULL) {
3219 goto out;
3220 }
3221
3222 ev->handler = handler;
3223 ev->ctx = user;
3224
3227 ev->handler = UACPI_NULL;
3228 ev->ctx = UACPI_NULL;
3229 }
3230
3231out:
3234 return ret;
3235}
3236
3239)
3240{
3242 struct fixed_event_handler *ev;
3244
3246
3247 if (uacpi_unlikely(event < 0 || event > UACPI_FIXED_EVENT_MAX))
3250 return UACPI_STATUS_OK;
3251
3254 return ret;
3255
3257
3258 /*
3259 * The handler is gone as far as everyone else is concerned as soon as the
3260 * lock is dropped: the event can't be enabled without one, and an
3261 * interrupt handler that is yet to look at it finds the event disabled.
3262 */
3264
3267 ev->handler = UACPI_NULL;
3268 ev->ctx = UACPI_NULL;
3269 }
3270
3272
3274 goto out;
3275
3276 // The handler might still be in use by the interrupts that are in flight
3278
3279out:
3281 return ret;
3282}
3283
3286)
3287{
3289 const struct fixed_event *ev;
3290 uacpi_u64 raw_value;
3293
3295
3296 if (uacpi_unlikely(event < 0 || event > UACPI_FIXED_EVENT_MAX))
3300
3302
3304 info |= UACPI_EVENT_INFO_HAS_HANDLER;
3305
3306 ev = &fixed_events[event];
3307
3308 ret = uacpi_read_register_field(ev->enable_field, &raw_value);
3310 goto out;
3311 if (raw_value)
3312 info |= UACPI_EVENT_INFO_ENABLED | UACPI_EVENT_INFO_HW_ENABLED;
3313
3314 ret = uacpi_read_register_field(ev->status_field, &raw_value);
3316 goto out;
3317 if (raw_value)
3318 info |= UACPI_EVENT_INFO_HW_STATUS;
3319
3320 *out_info = info;
3321out:
3323 return ret;
3324}
3325
3327 uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_event_info *out_info
3328)
3329{
3331 struct gp_event *event;
3332 struct gpe_register *reg;
3333 uacpi_u8 mask;
3334 uacpi_u64 raw_value;
3337
3339
3342
3344
3345 ret = sanitize_device_and_find_gpe(&gpe_device, idx, &event);
3347 goto out;
3348
3349 if (event->handler_type != GPE_HANDLER_TYPE_NONE)
3350 info |= UACPI_EVENT_INFO_HAS_HANDLER;
3351
3353 reg = event->reg;
3354
3355 if (reg->runtime_mask & mask)
3356 info |= UACPI_EVENT_INFO_ENABLED;
3357 if (reg->masked_mask & mask)
3358 info |= UACPI_EVENT_INFO_MASKED;
3359 if (reg->wake_mask & mask)
3360 info |= UACPI_EVENT_INFO_ENABLED_FOR_WAKE;
3361
3362 ret = uacpi_gas_read_mapped(&reg->enable, &raw_value);
3364 goto out;
3365 if (raw_value & mask)
3366 info |= UACPI_EVENT_INFO_HW_ENABLED;
3367
3368 ret = uacpi_gas_read_mapped(&reg->status, &raw_value);
3370 goto out;
3371 if (raw_value & mask)
3372 info |= UACPI_EVENT_INFO_HW_STATUS;
3373
3374 *out_info = info;
3375out:
3377 return ret;
3378}
3379
3380#define PM1_STATUS_BITS ( \
3381 ACPI_PM1_STS_TMR_STS_MASK | \
3382 ACPI_PM1_STS_BM_STS_MASK | \
3383 ACPI_PM1_STS_GBL_STS_MASK | \
3384 ACPI_PM1_STS_PWRBTN_STS_MASK | \
3385 ACPI_PM1_STS_SLPBTN_STS_MASK | \
3386 ACPI_PM1_STS_RTC_STS_MASK | \
3387 ACPI_PM1_STS_PCIEXP_WAKE_STS_MASK | \
3388 ACPI_PM1_STS_WAKE_STS_MASK \
3389)
3390
3392{
3394 struct do_for_all_gpes_ctx ctx = {
3396 };
3397
3399
3401 return UACPI_STATUS_OK;
3402
3405 return ret;
3406
3409 goto out;
3410
3412 ret = ctx.ret;
3413
3414out:
3416 return ret;
3417}
3418
3419#endif // !UACPI_REDUCED_HARDWARE && !UACPI_BAREBONES_MODE
static int state
Definition: maze.c:121
unsigned long uacpi_cpu_flags
Definition: arch_helpers.h:13
void user(int argc, const char *argv[])
Definition: cmds.c:1350
uacpi_status uacpi_recursive_lock_deinit(struct uacpi_recursive_lock *lock)
Definition: mutex.c:265
static void uacpi_signal_native_event(uacpi_handle evt)
Definition: mutex.h:95
uacpi_status uacpi_recursive_lock_init(struct uacpi_recursive_lock *lock)
Definition: mutex.c:253
static uacpi_handle uacpi_create_native_event(void)
Definition: mutex.h:78
uacpi_status uacpi_recursive_lock_acquire(struct uacpi_recursive_lock *lock)
Definition: mutex.c:285
uacpi_status uacpi_recursive_lock_release(struct uacpi_recursive_lock *lock)
Definition: mutex.c:305
#define uacpi_atomic_store_ptr(ptr_to_ptr, value)
Definition: atomic.h:344
#define uacpi_atomic_load_ptr(ptr_to_ptr)
Definition: atomic.h:343
unsigned int idx
Definition: utils.c:40
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7708
#define ACPI_PM1_EN_PWRBTN_EN_MASK
Definition: acpi.h:891
#define ACPI_PM1_STS_SLPBTN_STS_MASK
Definition: acpi.h:873
#define ACPI_PM1_EN_RTC_EN_MASK
Definition: acpi.h:893
#define ACPI_PM1_EN_SLPBTN_EN_MASK
Definition: acpi.h:892
#define ACPI_PM1_EN_TMR_EN_MASK
Definition: acpi.h:889
#define ACPI_PM1_STS_CLEAR
Definition: acpi.h:879
#define ACPI_PM1_STS_RTC_STS_MASK
Definition: acpi.h:874
#define ACPI_PM1_STS_TMR_STS_MASK
Definition: acpi.h:869
#define ACPI_PM1_STS_PWRBTN_STS_MASK
Definition: acpi.h:872
#define ACPI_PM1_EN_GBL_EN_MASK
Definition: acpi.h:890
#define ACPI_PM1_STS_GBL_STS_MASK
Definition: acpi.h:871
uacpi_interrupt_ret(* uacpi_gpe_handler)(uacpi_handle ctx, uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.h:112
#define UACPI_GPE_REENABLE
Definition: event.h:110
uacpi_u16 uacpi_gpe_triggering uacpi_gpe_handler uacpi_handle ctx uacpi_u16 uacpi_namespace_node *wake_device uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u64 uacpi_address_space uacpi_u16 num_registers
Definition: event.h:401
uacpi_gpe_triggering
Definition: event.h:116
@ UACPI_GPE_TRIGGERING_MAX
Definition: event.h:119
@ UACPI_GPE_TRIGGERING_EDGE
Definition: event.h:118
@ UACPI_GPE_TRIGGERING_LEVEL
Definition: event.h:117
uacpi_fixed_event
Definition: event.h:12
@ UACPI_FIXED_EVENT_TIMER_STATUS
Definition: event.h:13
@ UACPI_FIXED_EVENT_RTC
Definition: event.h:16
@ UACPI_FIXED_EVENT_SLEEP_BUTTON
Definition: event.h:15
@ UACPI_FIXED_EVENT_POWER_BUTTON
Definition: event.h:14
@ UACPI_FIXED_EVENT_MAX
Definition: event.h:17
uacpi_event_info
Definition: event.h:82
uacpi_u16 uacpi_gpe_triggering triggering
Definition: event.h:170
uacpi_u16 uacpi_gpe_triggering uacpi_gpe_handler uacpi_handle ctx uacpi_u16 uacpi_namespace_node *wake_device uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u64 uacpi_address_space address_space
Definition: event.h:401
#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl)
Definition: context.h:127
static uacpi_bool uacpi_is_hardware_reduced(void)
Definition: context.h:100
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:18
#define UACPI_FIXED_EVENT_GLOBAL_LOCK
Definition: event.h:6
#define UACPI_ARRAY_SIZE(arr)
Definition: helpers.h:5
#define UACPI_UNUSED(x)
Definition: helpers.h:7
void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas)
Definition: io.c:1049
uacpi_status uacpi_map_gas_noalloc(const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped)
Definition: io.c:992
#define uacpi_trace(...)
Definition: log.h:33
#define uacpi_info(...)
Definition: log.h:34
#define uacpi_error(...)
Definition: log.h:36
#define uacpi_warn(...)
Definition: log.h:35
uacpi_status uacpi_namespace_do_for_each_child(uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback, uacpi_iteration_callback ascending_callback, uacpi_object_type_bits, uacpi_u32 max_depth, enum uacpi_should_lock, enum uacpi_permanent_only, void *user)
Definition: namespace.c:841
uacpi_status uacpi_namespace_write_unlock(void)
Definition: namespace.c:51
uacpi_object * uacpi_namespace_node_get_object_typed(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask)
Definition: namespace.c:661
@ UACPI_PERMANENT_ONLY_YES
Definition: namespace.h:94
@ UACPI_SHOULD_LOCK_YES
Definition: namespace.h:99
uacpi_status uacpi_namespace_write_lock(void)
Definition: namespace.c:46
#define uacpi_kernel_alloc_zeroed
Definition: stdlib.h:127
#define uacpi_free(mem, _)
Definition: stdlib.h:96
uacpi_status uacpi_gas_read_mapped(const uacpi_mapped_gas *gas, uacpi_u64 *value)
Definition: io.c:911
uacpi_status uacpi_gas_write_mapped(const uacpi_mapped_gas *gas, uacpi_u64 value)
Definition: io.c:950
uacpi_status uacpi_namespace_node_is(const uacpi_namespace_node *node, uacpi_object_type type, uacpi_bool *out)
Definition: namespace.c:832
uacpi_namespace_node * uacpi_namespace_get_predefined(uacpi_predefined_namespace)
Definition: namespace.c:269
#define UACPI_MAX_DEPTH_ANY
Definition: namespace.h:102
@ UACPI_PREDEFINED_NAMESPACE_GPE
Definition: namespace.h:18
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:264
uacpi_object_name uacpi_namespace_node_name(const uacpi_namespace_node *node)
Definition: namespace.c:759
#define UACPI_FALLTHROUGH
Definition: compiler.h:100
#define uacpi_likely(expr)
Definition: compiler.h:89
#define uacpi_unlikely(expr)
Definition: compiler.h:88
size_t uacpi_size
Definition: types.h:37
uint32_t uacpi_u32
Definition: types.h:21
bool uacpi_bool
Definition: types.h:31
#define UACPI_FALSE
Definition: types.h:30
uint64_t uacpi_u64
Definition: types.h:22
char uacpi_char
Definition: types.h:44
uint16_t uacpi_u16
Definition: types.h:20
#define UACPI_NULL
Definition: types.h:33
uint8_t uacpi_u8
Definition: types.h:19
#define UACPI_TRUE
Definition: types.h:29
@ UACPI_REGISTER_FIELD_PWRBTN_EN
Definition: registers.h:68
@ UACPI_REGISTER_FIELD_PWRBTN_STS
Definition: registers.h:60
@ UACPI_REGISTER_FIELD_RTC_STS
Definition: registers.h:62
@ UACPI_REGISTER_FIELD_RTC_EN
Definition: registers.h:70
@ UACPI_REGISTER_FIELD_GBL_EN
Definition: registers.h:67
@ UACPI_REGISTER_FIELD_SLPBTN_STS
Definition: registers.h:61
@ UACPI_REGISTER_FIELD_SLPBTN_EN
Definition: registers.h:69
@ UACPI_REGISTER_FIELD_GBL_STS
Definition: registers.h:59
@ UACPI_REGISTER_FIELD_TMR_STS
Definition: registers.h:57
@ UACPI_REGISTER_FIELD_TMR_EN
Definition: registers.h:66
uacpi_status uacpi_read_register_field(uacpi_register_field, uacpi_u64 *)
Definition: registers.c:487
uacpi_status uacpi_read_register(uacpi_register, uacpi_u64 *)
Definition: registers.c:227
uacpi_status uacpi_write_register(uacpi_register, uacpi_u64)
Definition: registers.c:286
uacpi_status uacpi_write_register_field(uacpi_register_field, uacpi_u64)
Definition: registers.c:518
@ UACPI_REGISTER_PM1_EN
Definition: registers.h:18
@ UACPI_REGISTER_PM1_STS
Definition: registers.h:17
#define uacpi_likely_success(expr)
Definition: status.h:54
#define uacpi_unlikely_error(expr)
Definition: status.h:50
uacpi_status
Definition: status.h:10
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
@ UACPI_STATUS_INTERNAL_ERROR
Definition: status.h:21
@ UACPI_STATUS_NOT_FOUND
Definition: status.h:17
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
@ UACPI_STATUS_ALREADY_EXISTS
Definition: status.h:20
@ UACPI_STATUS_OK
Definition: status.h:11
@ UACPI_STATUS_HARDWARE_TIMEOUT
Definition: status.h:28
@ UACPI_STATUS_NO_HANDLER
Definition: status.h:25
const uacpi_char * uacpi_status_to_string(uacpi_status)
Definition: uacpi.c:61
#define UACPI_INTERRUPT_HANDLED
Definition: types.h:551
void * uacpi_handle
Definition: types.h:21
uacpi_iteration_decision
Definition: types.h:28
@ UACPI_ITERATION_DECISION_BREAK
Definition: types.h:30
@ UACPI_ITERATION_DECISION_CONTINUE
Definition: types.h:29
@ UACPI_OBJECT_METHOD_BIT
Definition: types.h:142
@ UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED
Definition: types.h:72
@ UACPI_INIT_LEVEL_NAMESPACE_LOADED
Definition: types.h:78
uacpi_interrupt_ret(* uacpi_interrupt_handler)(uacpi_handle)
Definition: types.h:554
@ UACPI_OBJECT_DEVICE
Definition: types.h:117
uacpi_u32 uacpi_interrupt_ret
Definition: types.h:552
#define UACPI_INTERRUPT_NOT_HANDLED
Definition: types.h:550
uacpi_address_space
Definition: types.h:42
static struct gp_event * get_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:1783
gpe_handler_type
Definition: event.c:380
@ GPE_HANDLER_TYPE_NATIVE_HANDLER
Definition: event.c:383
@ GPE_HANDLER_TYPE_NATIVE_HANDLER_RAW
Definition: event.c:384
@ GPE_HANDLER_TYPE_IMPLICIT_NOTIFY
Definition: event.c:385
@ GPE_HANDLER_TYPE_NONE
Definition: event.c:381
@ GPE_HANDLER_TYPE_AML_HANDLER
Definition: event.c:382
static void gpe_work_done(struct gp_event *event)
Definition: event.c:633
const uacpi_char * uacpi_gpe_triggering_to_string(uacpi_gpe_triggering triggering)
Definition: event.c:1889
static uacpi_status gpe_enable_disable_for_wake(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_bool enabled)
Definition: event.c:2746
uacpi_status uacpi_install_gpe_handler_raw(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_gpe_triggering triggering, uacpi_gpe_handler handler, uacpi_handle ctx)
Definition: event.c:2302
static uacpi_handle g_gpe_state_slock
Definition: event.c:29
static struct uacpi_recursive_lock g_event_lock
Definition: event.c:30
uacpi_status uacpi_initialize_events_early(void)
Definition: event.c:3027
static uacpi_status set_gpe_state(struct gp_event *event, enum gpe_state state)
Definition: event.c:557
uacpi_status uacpi_disable_gpe_for_wake(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2792
event_clear_if_first
Definition: event.c:1846
@ EVENT_CLEAR_IF_FIRST_YES
Definition: event.c:1847
@ EVENT_CLEAR_IF_FIRST_NO
Definition: event.c:1848
uacpi_status uacpi_suspend_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2512
static void free_gpe_block(struct gpe_block *block)
Definition: event.c:1223
#define PM1_STATUS_BITS
Definition: event.c:3380
uacpi_status uacpi_enable_fixed_event(uacpi_fixed_event event)
Definition: event.c:178
static const struct fixed_event fixed_events[UACPI_FIXED_EVENT_MAX+1]
Definition: event.c:95
static uacpi_status sanitize_device_and_find_gpe(uacpi_namespace_node **gpe_device, uacpi_u16 idx, struct gp_event **out_event)
Definition: event.c:2189
static uacpi_status set_gpe_state_unlocked(struct gp_event *event, enum gpe_state state)
Definition: event.c:518
uacpi_status uacpi_initialize_events(void)
Definition: event.c:3057
static void async_run_gpe_handler(uacpi_handle opaque)
Definition: event.c:660
uacpi_status uacpi_resume_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2519
uacpi_status uacpi_enable_all_wake_gpes(void)
Definition: event.c:2852
static uacpi_interrupt_ret handle_global_lock(uacpi_handle ctx)
Definition: event.c:2990
static uacpi_status find_or_create_gpe_interrupt_ctx(uacpi_u32 irq, struct gpe_interrupt_ctx **out_ctx)
Definition: event.c:1037
uacpi_status uacpi_enable_gpe_for_wake(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2785
uacpi_status uacpi_disable_all_gpes(void)
Definition: event.c:2836
static struct fixed_event_handler fixed_event_handlers[UACPI_FIXED_EVENT_MAX+1]
Definition: event.c:128
static uacpi_interrupt_ret handle_sci(uacpi_handle ctx)
Definition: event.c:3017
static struct gpe_interrupt_ctx * g_gpe_interrupt_head
Definition: event.c:504
gpe_dispatcher
Definition: event.c:747
@ GPE_DISPATCHER_INTERRUPT
Definition: event.c:749
@ GPE_DISPATCHER_POLL
Definition: event.c:752
uacpi_status uacpi_install_gpe_block(uacpi_namespace_node *gpe_device, uacpi_u64 address, uacpi_address_space address_space, uacpi_u16 num_registers, uacpi_u32 irq)
Definition: event.c:2914
static uacpi_status set_event(uacpi_u8 event, uacpi_u8 value)
Definition: event.c:153
static uacpi_status gpe_mask_unmask(struct gp_event *event, uacpi_bool should_mask)
Definition: event.c:1984
uacpi_status uacpi_uninstall_gpe_handler(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_gpe_handler handler)
Definition: event.c:2314
static uacpi_status maybe_dispatch_gpe(uacpi_namespace_node *gpe_device, struct gp_event *event)
Definition: event.c:1008
static void gpe_disarm(struct gp_event *event)
Definition: event.c:588
static uacpi_status create_gpe_block(uacpi_namespace_node *device_node, uacpi_u32 irq, uacpi_u16 base_idx, uacpi_u64 address, uacpi_u8 address_space_id, uacpi_u16 num_registers)
Definition: event.c:1610
static struct gpe_block * load_gpe_block(struct gpe_block **block)
Definition: event.c:948
static uacpi_status restore_gpe(struct gp_event *event)
Definition: event.c:621
uacpi_status uacpi_enable_all_runtime_gpes(void)
Definition: event.c:2844
static uacpi_iteration_decision do_match_gpe_methods(uacpi_handle opaque, uacpi_namespace_node *node, uacpi_u32 depth)
Definition: event.c:1477
static void uninstall_gpe_block(struct gpe_block *block)
Definition: event.c:1296
static uacpi_iteration_decision do_initialize_gpe_block(struct gpe_block *block, uacpi_handle opaque)
Definition: event.c:2100
static void gpe_set_handler(struct gp_event *event, uacpi_handle handler, enum gpe_handler_type type, uacpi_u8 triggering)
Definition: event.c:1413
#define EVENTS_PER_GPE_REGISTER
Definition: event.c:371
uacpi_iteration_decision(* gpe_block_iteration_callback)(struct gpe_block *, uacpi_handle)
Definition: event.c:1734
uacpi_status uacpi_disable_fixed_event(uacpi_fixed_event event)
Definition: event.c:210
static uacpi_status gpe_mask_safe(struct gp_event *event, uacpi_bool *out_did_mask)
Definition: event.c:2048
static uacpi_iteration_decision do_find_gpe(struct gpe_block *block, uacpi_handle opaque)
Definition: event.c:1766
uacpi_status uacpi_mask_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2578
uacpi_status uacpi_gpe_info(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_event_info *out_info)
Definition: event.c:3326
uacpi_status uacpi_uninstall_fixed_event_handler(uacpi_fixed_event event)
Definition: event.c:3237
static void gpe_release_implicit_notify_handlers(struct gp_event *event)
Definition: event.c:1137
uacpi_status uacpi_uninstall_gpe_block(uacpi_namespace_node *gpe_device)
Definition: event.c:2951
uacpi_status uacpi_finalize_gpe_initialization(void)
Definition: event.c:2154
static uacpi_interrupt_ret handle_gpes(uacpi_handle opaque)
Definition: event.c:1027
static uacpi_u8 gpe_get_mask(struct gp_event *event)
Definition: event.c:506
static void gpe_drop_claim(struct gp_event *event)
Definition: event.c:1436
static void event_config_unlock(void)
Definition: event.c:60
uacpi_status uacpi_fixed_event_info(uacpi_fixed_event event, uacpi_event_info *out_info)
Definition: event.c:3284
static uacpi_status gpe_add_user(struct gp_event *event, enum event_clear_if_first clear_if_first, uacpi_bool *out_is_first)
Definition: event.c:1851
static uacpi_status gpe_suspend_resume(uacpi_namespace_node *gpe_device, uacpi_u16 idx, enum gpe_state state)
Definition: event.c:2486
static uacpi_status gpe_set_aml_handler(struct gp_event *event, uacpi_namespace_node *node, uacpi_u8 triggering)
Definition: event.c:1453
static uacpi_interrupt_ret dispatch_fixed_event(const struct fixed_event *ev, uacpi_fixed_event event)
Definition: event.c:283
static uacpi_status restore_gpe_unlocked(struct gp_event *event)
Definition: event.c:598
static uacpi_status gpe_try_claim(struct gp_event *event, enum gpe_dispatcher dispatcher, uacpi_u8 *out_handler_type, uacpi_u8 *out_triggering, uacpi_bool *out_did_claim)
Definition: event.c:770
uacpi_status uacpi_install_fixed_event_handler(uacpi_fixed_event event, uacpi_interrupt_handler handler, uacpi_handle user)
Definition: event.c:3193
static uacpi_bool g_gpes_finalized
Definition: event.c:43
static void for_each_gpe_block(gpe_block_iteration_callback cb, uacpi_handle handle)
Definition: event.c:1736
static uacpi_handle g_fixed_event_slock
Definition: event.c:138
uacpi_status uacpi_finish_handling_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2526
void uacpi_deinitialize_events(void)
Definition: event.c:3120
static uacpi_status do_install_gpe_handler(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_gpe_triggering triggering, enum gpe_handler_type type, uacpi_gpe_handler handler, uacpi_handle ctx)
Definition: event.c:2207
#define UACPI_EVENT_DISABLED
Definition: event.c:15
uacpi_status uacpi_setup_gpe_for_wake(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_namespace_node *wake_device)
Definition: event.c:2592
static uacpi_iteration_decision do_for_all_gpes(struct gpe_block *block, uacpi_handle opaque)
Definition: event.c:2804
gpe_state
Definition: event.c:511
@ GPE_STATE_ENABLED
Definition: event.c:512
@ GPE_STATE_ENABLED_CONDITIONALLY
Definition: event.c:513
@ GPE_STATE_DISABLED
Definition: event.c:514
static uacpi_status gpe_mask_and_flush(struct gp_event *event)
Definition: event.c:1923
static uacpi_status gpe_ensure_work_item(struct gp_event *event)
Definition: event.c:1125
void uacpi_events_restore_buttons_post_wake(void)
Definition: event.c:243
uacpi_status uacpi_enable_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2392
uacpi_status uacpi_clear_fixed_event(uacpi_fixed_event event)
Definition: event.c:229
static uacpi_interrupt_ret handle_fixed_events(void)
Definition: event.c:323
static uacpi_bool gpe_is_armed(struct gp_event *event)
Definition: event.c:576
#define UACPI_EVENT_ENABLED
Definition: event.c:16
static uacpi_status gpe_block_apply_action(struct gpe_block *block, enum gpe_block_action action)
Definition: event.c:1159
static uacpi_status gpe_remove_user_unlocked(struct gp_event *event)
Definition: event.c:1814
static void gp_event_toggle_masks(struct gp_event *event, uacpi_bool set_on)
Definition: event.c:1796
gpe_block_action
Definition: event.c:1152
@ GPE_BLOCK_ACTION_ENABLE_ALL_FOR_WAKE
Definition: event.c:1155
@ GPE_BLOCK_ACTION_ENABLE_ALL_FOR_RUNTIME
Definition: event.c:1154
@ GPE_BLOCK_ACTION_DISABLE_ALL
Definition: event.c:1153
@ GPE_BLOCK_ACTION_CLEAR_ALL
Definition: event.c:1156
uacpi_status uacpi_disable_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2436
static uacpi_status initialize_fixed_events(void)
Definition: event.c:140
static uacpi_status for_all_gpes_locked(struct do_for_all_gpes_ctx *ctx)
Definition: event.c:2817
uacpi_status uacpi_clear_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2461
static uacpi_status initialize_gpes(void)
Definition: event.c:2860
static uacpi_bool gpe_needs_polling(struct gp_event *event, uacpi_bool is_first_user)
Definition: event.c:1909
static uacpi_status event_config_lock(void)
Definition: event.c:45
static void async_restore_gpe(uacpi_handle opaque)
Definition: event.c:642
static uacpi_interrupt_ret dispatch_gpe(uacpi_namespace_node *device_node, struct gp_event *event, enum gpe_dispatcher dispatcher)
Definition: event.c:827
static void unlink_gpe_interrupt_ctx(struct gpe_interrupt_ctx *ctx)
Definition: event.c:1090
uacpi_status uacpi_install_gpe_handler(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_gpe_triggering triggering, uacpi_gpe_handler handler, uacpi_handle ctx)
Definition: event.c:2290
static uacpi_status gpe_remove_user(struct gp_event *event)
Definition: event.c:1834
static struct uacpi_recursive_lock g_event_config_lock
Definition: event.c:42
uacpi_status uacpi_unmask_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:2585
static uacpi_status clear_gpe(struct gp_event *event)
Definition: event.c:569
static uacpi_status gpe_get_mask_unmask(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_bool should_mask)
Definition: event.c:2551
void uacpi_events_match_post_dynamic_table_load(void)
Definition: event.c:1567
static struct gp_event * gpe_from_block(struct gpe_block *block, uacpi_u16 idx)
Definition: event.c:1388
static uacpi_interrupt_ret detect_gpes(struct gpe_interrupt_ctx *ctx, enum gpe_dispatcher dispatcher)
Definition: event.c:953
static void wait_for_work_completion_unlocked(void)
Definition: event.c:76
uacpi_status uacpi_clear_all_events(void)
Definition: event.c:3391
return ret
Definition: mutex.c:147
action
Definition: namespace.c:714
unsigned char irq
Definition: dsp.h:13
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLuint address
Definition: glext.h:9393
GLintptr offset
Definition: glext.h:5920
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLboolean enable
Definition: glext.h:11120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static int reg
Definition: i386-dis.c:1290
uacpi_status uacpi_notify_all(uacpi_namespace_node *node, uacpi_u64 value)
Definition: notify.c:96
uacpi_status uacpi_string_to_integer(const uacpi_char *str, uacpi_size max_chars, enum uacpi_base base, uacpi_u64 *out_value)
Definition: utilities.c:233
@ UACPI_BASE_HEX
Definition: utilities.h:34
uacpi_status uacpi_execute_control_method(uacpi_namespace_node *scope, uacpi_control_method *method, const uacpi_object_array *args, uacpi_object **ret)
Definition: interpreter.c:6479
uint32_t entry
Definition: isohybrid.c:63
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
uacpi_status uacpi_kernel_wait_for_work_completion(void)
Definition: uacpiosl.c:235
uacpi_status uacpi_kernel_uninstall_interrupt_handler(uacpi_interrupt_handler, uacpi_handle irq_handle)
Definition: uacpiosl.c:221
uacpi_status uacpi_kernel_install_interrupt_handler(uacpi_u32 irq, uacpi_interrupt_handler, uacpi_handle ctx, uacpi_handle *out_irq_handle)
Definition: uacpiosl.c:212
void uacpi_kernel_schedule_work(uacpi_work_type, uacpi_handle work_item, uacpi_work_handler handler, uacpi_handle ctx)
@ UACPI_WORK_GPE_EXECUTION
Definition: kernel_api.h:361
@ UACPI_WORK_NOTIFICATION
Definition: kernel_api.h:367
uacpi_handle uacpi_kernel_create_spinlock(void)
Definition: uacpiosl.c:85
uacpi_handle uacpi_kernel_create_work_item(void)
void uacpi_kernel_free_spinlock(uacpi_handle)
Definition: uacpiosl.c:92
void uacpi_kernel_free_work_item(uacpi_handle)
uacpi_cpu_flags uacpi_kernel_lock_spinlock(uacpi_handle)
Definition: uacpiosl.c:98
void uacpi_kernel_unlock_spinlock(uacpi_handle, uacpi_cpu_flags)
Definition: uacpiosl.c:105
HWND buttons[5]
Definition: sndrec32.cpp:40
enum gpe_block_action action
Definition: event.c:2800
uacpi_status ret
Definition: event.c:2801
Definition: filter.c:185
uacpi_handle ctx
Definition: event.c:92
uacpi_interrupt_handler handler
Definition: event.c:91
uacpi_u16 status_mask
Definition: event.c:87
uacpi_u8 enable_field
Definition: event.c:84
uacpi_u8 status_field
Definition: event.c:85
uacpi_u16 enable_mask
Definition: event.c:86
uacpi_u8 has_auto_user
Definition: event.c:416
uacpi_u8 num_users
Definition: event.c:427
uacpi_handle work_item
Definition: event.c:403
uacpi_u8 handler_type
Definition: event.c:407
struct gpe_implicit_notify_handler * implicit_handler
Definition: event.c:391
uacpi_bool work_item_in_use
Definition: event.c:439
uacpi_u8 triggering
Definition: event.c:408
uacpi_bool clear_on_restore
Definition: event.c:447
struct gpe_register * reg
Definition: event.c:396
uacpi_bool block_interrupts
Definition: event.c:433
uacpi_u16 idx
Definition: event.c:405
uacpi_namespace_node * aml_handler
Definition: event.c:392
uacpi_u8 wake
Definition: event.c:409
struct gpe_native_handler * native_handler
Definition: event.c:390
uacpi_handle * any_handler
Definition: event.c:393
uacpi_u16 base_idx
Definition: event.c:491
struct gpe_block * next
Definition: event.c:475
uacpi_namespace_node * device_node
Definition: event.c:483
uacpi_bool finalized
Definition: event.c:494
uacpi_u16 num_events
Definition: event.c:490
struct gp_event * events
Definition: event.c:486
struct gpe_register * registers
Definition: event.c:485
uacpi_u16 num_registers
Definition: event.c:489
struct gpe_interrupt_ctx * irq_ctx
Definition: event.c:487
uacpi_namespace_node * device
Definition: event.c:368
struct gpe_implicit_notify_handler * next
Definition: event.c:367
uacpi_handle irq_handle
Definition: event.c:501
struct gpe_interrupt_ctx * prev
Definition: event.c:498
uacpi_u32 irq
Definition: event.c:502
struct gpe_interrupt_ctx * next
Definition: event.c:498
struct gpe_block * gpe_head
Definition: event.c:500
uacpi_u32 matched_count
Definition: event.c:1404
struct gpe_block * block
Definition: event.c:1403
uacpi_bool post_dynamic_table_load
Definition: event.c:1405
uacpi_gpe_handler cb
Definition: event.c:353
uacpi_u8 previously_enabled
Definition: event.c:363
uacpi_u8 previous_triggering
Definition: event.c:361
uacpi_handle ctx
Definition: event.c:354
uacpi_handle previous_handler
Definition: event.c:360
uacpi_u8 previous_handler_type
Definition: event.c:362
uacpi_u16 base_idx
Definition: event.c:471
uacpi_u8 masked_mask
Definition: event.c:460
uacpi_u8 armed_mask
Definition: event.c:469
uacpi_mapped_gas enable
Definition: event.c:452
uacpi_u8 runtime_mask
Definition: event.c:458
uacpi_u8 current_mask
Definition: event.c:461
uacpi_mapped_gas status
Definition: event.c:451
uacpi_u8 wake_mask
Definition: event.c:459
uacpi_u16 idx
Definition: event.c:1761
uacpi_namespace_node * gpe_device
Definition: event.c:1760
struct gp_event * out_event
Definition: event.c:1763
struct gpe_block * out_block
Definition: event.c:1762
Definition: name.c:39
Definition: ps.c:97
uacpi_object_name name
Definition: namespace.h:29
uacpi_control_method * method
Definition: types.h:267
Definition: dlist.c:348
uacpi_char text[4]
Definition: types.h:24
Definition: pdh_main.c:64
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
static unsigned int block
Definition: xmlmemory.c:101