ReactOS 0.4.17-dev-1190-g4c812f4
event.c File Reference
Include dependency graph for event.c:

Go to the source code of this file.

Classes

struct  fixed_event
 
struct  fixed_event_handler
 
struct  gpe_native_handler
 
struct  gpe_implicit_notify_handler
 
struct  gp_event
 
struct  gpe_register
 
struct  gpe_block
 
struct  gpe_interrupt_ctx
 
struct  gpe_match_ctx
 
struct  gpe_search_ctx
 
struct  do_for_all_gpes_ctx
 

Macros

#define UACPI_EVENT_DISABLED   0
 
#define UACPI_EVENT_ENABLED   1
 
#define EVENTS_PER_GPE_REGISTER   8
 
#define PM1_STATUS_BITS
 

Typedefs

typedef uacpi_iteration_decision(* gpe_block_iteration_callback) (struct gpe_block *, uacpi_handle)
 

Enumerations

enum  gpe_handler_type {
  GPE_HANDLER_TYPE_NONE = 0 , GPE_HANDLER_TYPE_AML_HANDLER = 1 , GPE_HANDLER_TYPE_NATIVE_HANDLER = 2 , GPE_HANDLER_TYPE_NATIVE_HANDLER_RAW = 3 ,
  GPE_HANDLER_TYPE_IMPLICIT_NOTIFY = 4
}
 
enum  gpe_state { GPE_STATE_ENABLED , GPE_STATE_ENABLED_CONDITIONALLY , GPE_STATE_DISABLED }
 
enum  gpe_dispatcher { GPE_DISPATCHER_INTERRUPT , GPE_DISPATCHER_POLL }
 
enum  gpe_block_action { GPE_BLOCK_ACTION_DISABLE_ALL , GPE_BLOCK_ACTION_ENABLE_ALL_FOR_RUNTIME , GPE_BLOCK_ACTION_ENABLE_ALL_FOR_WAKE , GPE_BLOCK_ACTION_CLEAR_ALL }
 
enum  event_clear_if_first { EVENT_CLEAR_IF_FIRST_YES , EVENT_CLEAR_IF_FIRST_NO }
 

Functions

static uacpi_status event_config_lock (void)
 
static void event_config_unlock (void)
 
static void wait_for_work_completion_unlocked (void)
 
static uacpi_status initialize_fixed_events (void)
 
static uacpi_status set_event (uacpi_u8 event, uacpi_u8 value)
 
uacpi_status uacpi_enable_fixed_event (uacpi_fixed_event event)
 
uacpi_status uacpi_disable_fixed_event (uacpi_fixed_event event)
 
uacpi_status uacpi_clear_fixed_event (uacpi_fixed_event event)
 
void uacpi_events_restore_buttons_post_wake (void)
 
static uacpi_interrupt_ret dispatch_fixed_event (const struct fixed_event *ev, uacpi_fixed_event event)
 
static uacpi_interrupt_ret handle_fixed_events (void)
 
static uacpi_u8 gpe_get_mask (struct gp_event *event)
 
static uacpi_status set_gpe_state_unlocked (struct gp_event *event, enum gpe_state state)
 
static uacpi_status set_gpe_state (struct gp_event *event, enum gpe_state state)
 
static uacpi_status clear_gpe (struct gp_event *event)
 
static uacpi_bool gpe_is_armed (struct gp_event *event)
 
static void gpe_disarm (struct gp_event *event)
 
static uacpi_status restore_gpe_unlocked (struct gp_event *event)
 
static uacpi_status restore_gpe (struct gp_event *event)
 
static void gpe_work_done (struct gp_event *event)
 
static void async_restore_gpe (uacpi_handle opaque)
 
static void async_run_gpe_handler (uacpi_handle opaque)
 
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)
 
static uacpi_interrupt_ret dispatch_gpe (uacpi_namespace_node *device_node, struct gp_event *event, enum gpe_dispatcher dispatcher)
 
static struct gpe_block * load_gpe_block (struct gpe_block **block)
 
static uacpi_interrupt_ret detect_gpes (struct gpe_interrupt_ctx *ctx, enum gpe_dispatcher dispatcher)
 
static uacpi_status maybe_dispatch_gpe (uacpi_namespace_node *gpe_device, struct gp_event *event)
 
static uacpi_interrupt_ret handle_gpes (uacpi_handle opaque)
 
static uacpi_status find_or_create_gpe_interrupt_ctx (uacpi_u32 irq, struct gpe_interrupt_ctx **out_ctx)
 
static void unlink_gpe_interrupt_ctx (struct gpe_interrupt_ctx *ctx)
 
static uacpi_status gpe_ensure_work_item (struct gp_event *event)
 
static void gpe_release_implicit_notify_handlers (struct gp_event *event)
 
static uacpi_status gpe_block_apply_action (struct gpe_block *block, enum gpe_block_action action)
 
static void free_gpe_block (struct gpe_block *block)
 
static void uninstall_gpe_block (struct gpe_block *block)
 
static struct gp_event * gpe_from_block (struct gpe_block *block, uacpi_u16 idx)
 
static void gpe_set_handler (struct gp_event *event, uacpi_handle handler, enum gpe_handler_type type, uacpi_u8 triggering)
 
static void gpe_drop_claim (struct gp_event *event)
 
static uacpi_status gpe_set_aml_handler (struct gp_event *event, uacpi_namespace_node *node, uacpi_u8 triggering)
 
static uacpi_iteration_decision do_match_gpe_methods (uacpi_handle opaque, uacpi_namespace_node *node, uacpi_u32 depth)
 
void uacpi_events_match_post_dynamic_table_load (void)
 
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)
 
static void for_each_gpe_block (gpe_block_iteration_callback cb, uacpi_handle handle)
 
static uacpi_iteration_decision do_find_gpe (struct gpe_block *block, uacpi_handle opaque)
 
static struct gp_event * get_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
static void gp_event_toggle_masks (struct gp_event *event, uacpi_bool set_on)
 
static uacpi_status gpe_remove_user_unlocked (struct gp_event *event)
 
static uacpi_status gpe_remove_user (struct gp_event *event)
 
static uacpi_status gpe_add_user (struct gp_event *event, enum event_clear_if_first clear_if_first, uacpi_bool *out_is_first)
 
const uacpi_char * uacpi_gpe_triggering_to_string (uacpi_gpe_triggering triggering)
 
static uacpi_bool gpe_needs_polling (struct gp_event *event, uacpi_bool is_first_user)
 
static uacpi_status gpe_mask_and_flush (struct gp_event *event)
 
static uacpi_status gpe_mask_unmask (struct gp_event *event, uacpi_bool should_mask)
 
static uacpi_status gpe_mask_safe (struct gp_event *event, uacpi_bool *out_did_mask)
 
static uacpi_iteration_decision do_initialize_gpe_block (struct gpe_block *block, uacpi_handle opaque)
 
uacpi_status uacpi_finalize_gpe_initialization (void)
 
static uacpi_status sanitize_device_and_find_gpe (uacpi_namespace_node **gpe_device, uacpi_u16 idx, struct gp_event **out_event)
 
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)
 
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)
 
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)
 
uacpi_status uacpi_uninstall_gpe_handler (uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_gpe_handler handler)
 
uacpi_status uacpi_enable_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
uacpi_status uacpi_disable_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
uacpi_status uacpi_clear_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
static uacpi_status gpe_suspend_resume (uacpi_namespace_node *gpe_device, uacpi_u16 idx, enum gpe_state state)
 
uacpi_status uacpi_suspend_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
uacpi_status uacpi_resume_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
uacpi_status uacpi_finish_handling_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
static uacpi_status gpe_get_mask_unmask (uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_bool should_mask)
 
uacpi_status uacpi_mask_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
uacpi_status uacpi_unmask_gpe (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
uacpi_status uacpi_setup_gpe_for_wake (uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_namespace_node *wake_device)
 
static uacpi_status gpe_enable_disable_for_wake (uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_bool enabled)
 
uacpi_status uacpi_enable_gpe_for_wake (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
uacpi_status uacpi_disable_gpe_for_wake (uacpi_namespace_node *gpe_device, uacpi_u16 idx)
 
static uacpi_iteration_decision do_for_all_gpes (struct gpe_block *block, uacpi_handle opaque)
 
static uacpi_status for_all_gpes_locked (struct do_for_all_gpes_ctx *ctx)
 
uacpi_status uacpi_disable_all_gpes (void)
 
uacpi_status uacpi_enable_all_runtime_gpes (void)
 
uacpi_status uacpi_enable_all_wake_gpes (void)
 
static uacpi_status initialize_gpes (void)
 
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)
 
uacpi_status uacpi_uninstall_gpe_block (uacpi_namespace_node *gpe_device)
 
static uacpi_interrupt_ret handle_global_lock (uacpi_handle ctx)
 
static uacpi_interrupt_ret handle_sci (uacpi_handle ctx)
 
uacpi_status uacpi_initialize_events_early (void)
 
uacpi_status uacpi_initialize_events (void)
 
void uacpi_deinitialize_events (void)
 
uacpi_status uacpi_install_fixed_event_handler (uacpi_fixed_event event, uacpi_interrupt_handler handler, uacpi_handle user)
 
uacpi_status uacpi_uninstall_fixed_event_handler (uacpi_fixed_event event)
 
uacpi_status uacpi_fixed_event_info (uacpi_fixed_event event, uacpi_event_info *out_info)
 
uacpi_status uacpi_gpe_info (uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_event_info *out_info)
 
uacpi_status uacpi_clear_all_events (void)
 

Variables

static uacpi_handle g_gpe_state_slock
 
static struct uacpi_recursive_lock g_event_lock
 
static struct uacpi_recursive_lock g_event_config_lock
 
static uacpi_bool g_gpes_finalized
 
static const struct fixed_event fixed_events [UACPI_FIXED_EVENT_MAX+1]
 
static struct fixed_event_handler fixed_event_handlers [UACPI_FIXED_EVENT_MAX+1]
 
static uacpi_handle g_fixed_event_slock
 
static struct gpe_interrupt_ctx * g_gpe_interrupt_head
 

Macro Definition Documentation

◆ EVENTS_PER_GPE_REGISTER

#define EVENTS_PER_GPE_REGISTER   8

Definition at line 371 of file event.c.

◆ PM1_STATUS_BITS

#define PM1_STATUS_BITS
Value:
( \
)
#define ACPI_PM1_STS_WAKE_STS_MASK
Definition: acpi.h:877
#define ACPI_PM1_STS_PCIEXP_WAKE_STS_MASK
Definition: acpi.h:876
#define ACPI_PM1_STS_SLPBTN_STS_MASK
Definition: acpi.h:873
#define ACPI_PM1_STS_RTC_STS_MASK
Definition: acpi.h:874
#define ACPI_PM1_STS_BM_STS_MASK
Definition: acpi.h:870
#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_STS_GBL_STS_MASK
Definition: acpi.h:871

Definition at line 3380 of file event.c.

◆ UACPI_EVENT_DISABLED

#define UACPI_EVENT_DISABLED   0

Definition at line 15 of file event.c.

◆ UACPI_EVENT_ENABLED

#define UACPI_EVENT_ENABLED   1

Definition at line 16 of file event.c.

Typedef Documentation

◆ gpe_block_iteration_callback

typedef uacpi_iteration_decision(* gpe_block_iteration_callback) (struct gpe_block *, uacpi_handle)

Definition at line 1733 of file event.c.

Enumeration Type Documentation

◆ event_clear_if_first

Enumerator
EVENT_CLEAR_IF_FIRST_YES 
EVENT_CLEAR_IF_FIRST_NO 

Definition at line 1846 of file event.c.

1846 {
1849};
@ EVENT_CLEAR_IF_FIRST_YES
Definition: event.c:1847
@ EVENT_CLEAR_IF_FIRST_NO
Definition: event.c:1848

◆ gpe_block_action

Enumerator
GPE_BLOCK_ACTION_DISABLE_ALL 
GPE_BLOCK_ACTION_ENABLE_ALL_FOR_RUNTIME 
GPE_BLOCK_ACTION_ENABLE_ALL_FOR_WAKE 
GPE_BLOCK_ACTION_CLEAR_ALL 

Definition at line 1151 of file event.c.

1152{
1157};
@ 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

◆ gpe_dispatcher

Enumerator
GPE_DISPATCHER_INTERRUPT 
GPE_DISPATCHER_POLL 

Definition at line 747 of file event.c.

747 {
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};
@ GPE_DISPATCHER_INTERRUPT
Definition: event.c:749
@ GPE_DISPATCHER_POLL
Definition: event.c:752

◆ gpe_handler_type

Enumerator
GPE_HANDLER_TYPE_NONE 
GPE_HANDLER_TYPE_AML_HANDLER 
GPE_HANDLER_TYPE_NATIVE_HANDLER 
GPE_HANDLER_TYPE_NATIVE_HANDLER_RAW 
GPE_HANDLER_TYPE_IMPLICIT_NOTIFY 

Definition at line 380 of file event.c.

380 {
386};
@ 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

◆ gpe_state

Enumerator
GPE_STATE_ENABLED 
GPE_STATE_ENABLED_CONDITIONALLY 
GPE_STATE_DISABLED 

Definition at line 511 of file event.c.

511 {
515};
@ GPE_STATE_ENABLED
Definition: event.c:512
@ GPE_STATE_ENABLED_CONDITIONALLY
Definition: event.c:513
@ GPE_STATE_DISABLED
Definition: event.c:514

Function Documentation

◆ async_restore_gpe()

static void async_restore_gpe ( uacpi_handle  opaque)
static

Definition at line 642 of file event.c.

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}
#define uacpi_error(...)
Definition: log.h:36
#define uacpi_unlikely_error(expr)
Definition: status.h:50
uacpi_status
Definition: status.h:10
const uacpi_char * uacpi_status_to_string(uacpi_status)
Definition: uacpi.c:61
static void gpe_work_done(struct gp_event *event)
Definition: event.c:633
static uacpi_status restore_gpe(struct gp_event *event)
Definition: event.c:621
return ret
Definition: mutex.c:147
Definition: filter.c:185

Referenced by async_run_gpe_handler().

◆ async_run_gpe_handler()

static void async_run_gpe_handler ( uacpi_handle  opaque)
static

Definition at line 660 of file event.c.

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}
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7708
#define uacpi_trace(...)
Definition: log.h:33
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_status uacpi_namespace_write_lock(void)
Definition: namespace.c:46
uacpi_object_name uacpi_namespace_node_name(const uacpi_namespace_node *node)
Definition: namespace.c:759
#define uacpi_unlikely(expr)
Definition: compiler.h:88
#define UACPI_NULL
Definition: types.h:33
@ UACPI_OBJECT_METHOD_BIT
Definition: types.h:142
static void async_restore_gpe(uacpi_handle opaque)
Definition: event.c:642
uacpi_status uacpi_notify_all(uacpi_namespace_node *node, uacpi_u64 value)
Definition: notify.c:96
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
void uacpi_kernel_schedule_work(uacpi_work_type, uacpi_handle work_item, uacpi_work_handler handler, uacpi_handle ctx)
@ UACPI_WORK_NOTIFICATION
Definition: kernel_api.h:367
Definition: name.c:39
uacpi_control_method * method
Definition: types.h:267

Referenced by dispatch_gpe().

◆ clear_gpe()

static uacpi_status clear_gpe ( struct gp_event *  event)
static

Definition at line 569 of file event.c.

570{
571 struct gpe_register *reg = event->reg;
572
573 return uacpi_gas_write_mapped(&reg->status, gpe_get_mask(event));
574}
uacpi_status uacpi_gas_write_mapped(const uacpi_mapped_gas *gas, uacpi_u64 value)
Definition: io.c:950
static uacpi_u8 gpe_get_mask(struct gp_event *event)
Definition: event.c:506
static int reg
Definition: i386-dis.c:1290

Referenced by dispatch_gpe(), gpe_add_user(), restore_gpe_unlocked(), and uacpi_clear_gpe().

◆ create_gpe_block()

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 
)
static

Definition at line 1610 of file event.c.

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}
unsigned long uacpi_cpu_flags
Definition: arch_helpers.h:13
#define uacpi_atomic_store_ptr(ptr_to_ptr, value)
Definition: atomic.h:344
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_status uacpi_map_gas_noalloc(const struct acpi_gas *gas, uacpi_mapped_gas *out_mapped)
Definition: io.c:992
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_PERMANENT_ONLY_YES
Definition: namespace.h:94
@ UACPI_SHOULD_LOCK_YES
Definition: namespace.h:99
#define uacpi_kernel_alloc_zeroed
Definition: stdlib.h:127
#define UACPI_MAX_DEPTH_ANY
Definition: namespace.h:102
size_t uacpi_size
Definition: types.h:37
uint32_t uacpi_u32
Definition: types.h:21
#define UACPI_FALSE
Definition: types.h:30
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
@ UACPI_STATUS_OK
Definition: status.h:11
static uacpi_handle g_gpe_state_slock
Definition: event.c:29
static void free_gpe_block(struct gpe_block *block)
Definition: event.c:1223
static uacpi_status find_or_create_gpe_interrupt_ctx(uacpi_u32 irq, struct gpe_interrupt_ctx **out_ctx)
Definition: event.c:1037
static uacpi_iteration_decision do_match_gpe_methods(uacpi_handle opaque, uacpi_namespace_node *node, uacpi_u32 depth)
Definition: event.c:1477
#define EVENTS_PER_GPE_REGISTER
Definition: event.c:371
static uacpi_bool g_gpes_finalized
Definition: event.c:43
unsigned char irq
Definition: dsp.h:13
GLuint address
Definition: glext.h:9393
GLbitfield flags
Definition: glext.h:7161
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
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
uacpi_u32 matched_count
Definition: event.c:1404
struct gpe_block * block
Definition: event.c:1403
uacpi_object_name name
Definition: namespace.h:29
uacpi_char text[4]
Definition: types.h:24
static unsigned int block
Definition: xmlmemory.c:101

Referenced by initialize_gpes(), and uacpi_install_gpe_block().

◆ detect_gpes()

static uacpi_interrupt_ret detect_gpes ( struct gpe_interrupt_ctx *  ctx,
enum gpe_dispatcher  dispatcher 
)
static

Definition at line 953 of file event.c.

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}
uacpi_status uacpi_gas_read_mapped(const uacpi_mapped_gas *gas, uacpi_u64 *value)
Definition: io.c:911
bool uacpi_bool
Definition: types.h:31
uint64_t uacpi_u64
Definition: types.h:22
uacpi_u32 uacpi_interrupt_ret
Definition: types.h:552
#define UACPI_INTERRUPT_NOT_HANDLED
Definition: types.h:550
static struct gpe_block * load_gpe_block(struct gpe_block **block)
Definition: event.c:948
static uacpi_interrupt_ret dispatch_gpe(uacpi_namespace_node *device_node, struct gp_event *event, enum gpe_dispatcher dispatcher)
Definition: event.c:827
GLboolean enable
Definition: glext.h:11120
Definition: ps.c:97

Referenced by handle_gpes(), and uacpi_finalize_gpe_initialization().

◆ dispatch_fixed_event()

static uacpi_interrupt_ret dispatch_fixed_event ( const struct fixed_event *  ev,
uacpi_fixed_event  event 
)
static

Definition at line 283 of file event.c.

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}
#define ACPI_PM1_STS_CLEAR
Definition: acpi.h:879
#define uacpi_warn(...)
Definition: log.h:35
uacpi_status uacpi_read_register_field(uacpi_register_field, uacpi_u64 *)
Definition: registers.c:487
uacpi_status uacpi_write_register_field(uacpi_register_field, uacpi_u64)
Definition: registers.c:518
static struct fixed_event_handler fixed_event_handlers[UACPI_FIXED_EVENT_MAX+1]
Definition: event.c:128
static uacpi_handle g_fixed_event_slock
Definition: event.c:138
#define UACPI_EVENT_DISABLED
Definition: event.c:15
uacpi_u8 enable_field
Definition: event.c:84
uacpi_u8 status_field
Definition: event.c:85

Referenced by handle_fixed_events().

◆ dispatch_gpe()

static uacpi_interrupt_ret dispatch_gpe ( uacpi_namespace_node *  device_node,
struct gp_event *  event,
enum gpe_dispatcher  dispatcher 
)
static

Definition at line 827 of file event.c.

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}
#define UACPI_GPE_REENABLE
Definition: event.h:110
@ UACPI_GPE_TRIGGERING_EDGE
Definition: event.h:118
uacpi_u16 uacpi_gpe_triggering triggering
Definition: event.h:170
uint8_t uacpi_u8
Definition: types.h:19
#define UACPI_TRUE
Definition: types.h:29
#define UACPI_INTERRUPT_HANDLED
Definition: types.h:551
static uacpi_status set_gpe_state_unlocked(struct gp_event *event, enum gpe_state state)
Definition: event.c:518
static void async_run_gpe_handler(uacpi_handle opaque)
Definition: event.c:660
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
static uacpi_status clear_gpe(struct gp_event *event)
Definition: event.c:569
@ UACPI_WORK_GPE_EXECUTION
Definition: kernel_api.h:361

Referenced by detect_gpes(), and maybe_dispatch_gpe().

◆ do_find_gpe()

static uacpi_iteration_decision do_find_gpe ( struct gpe_block *  block,
uacpi_handle  opaque 
)
static

Definition at line 1766 of file event.c.

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}
@ UACPI_ITERATION_DECISION_BREAK
Definition: types.h:30
@ UACPI_ITERATION_DECISION_CONTINUE
Definition: types.h:29
static struct gp_event * gpe_from_block(struct gpe_block *block, uacpi_u16 idx)
Definition: event.c:1388

Referenced by get_gpe(), and uacpi_uninstall_gpe_block().

◆ do_for_all_gpes()

static uacpi_iteration_decision do_for_all_gpes ( struct gpe_block *  block,
uacpi_handle  opaque 
)
static

Definition at line 2804 of file event.c.

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}
static uacpi_status gpe_block_apply_action(struct gpe_block *block, enum gpe_block_action action)
Definition: event.c:1159

Referenced by for_all_gpes_locked(), and uacpi_clear_all_events().

◆ do_initialize_gpe_block()

static uacpi_iteration_decision do_initialize_gpe_block ( struct gpe_block *  block,
uacpi_handle  opaque 
)
static

Definition at line 2100 of file event.c.

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}
#define uacpi_info(...)
Definition: log.h:34
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_bool gpe_needs_polling(struct gp_event *event, uacpi_bool is_first_user)
Definition: event.c:1909

Referenced by uacpi_finalize_gpe_initialization().

◆ do_install_gpe_handler()

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 
)
static

Definition at line 2207 of file event.c.

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}
unsigned int idx
Definition: utils.c:40
@ UACPI_GPE_TRIGGERING_MAX
Definition: event.h:119
#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl)
Definition: context.h:127
static uacpi_bool uacpi_is_hardware_reduced(void)
Definition: context.h:100
#define uacpi_free(mem, _)
Definition: stdlib.h:96
#define uacpi_likely_success(expr)
Definition: status.h:54
@ UACPI_STATUS_NOT_FOUND
Definition: status.h:17
@ UACPI_STATUS_ALREADY_EXISTS
Definition: status.h:20
@ UACPI_INIT_LEVEL_NAMESPACE_LOADED
Definition: types.h:78
const uacpi_char * uacpi_gpe_triggering_to_string(uacpi_gpe_triggering triggering)
Definition: event.c:1889
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 gpe_mask_unmask(struct gp_event *event, uacpi_bool should_mask)
Definition: event.c:1984
static void gpe_set_handler(struct gp_event *event, uacpi_handle handler, enum gpe_handler_type type, uacpi_u8 triggering)
Definition: event.c:1413
static uacpi_status gpe_mask_safe(struct gp_event *event, uacpi_bool *out_did_mask)
Definition: event.c:2048
static void gpe_drop_claim(struct gp_event *event)
Definition: event.c:1436
static void event_config_unlock(void)
Definition: event.c:60
static uacpi_status event_config_lock(void)
Definition: event.c:45
static uacpi_status gpe_remove_user(struct gp_event *event)
Definition: event.c:1834
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
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
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by uacpi_install_gpe_handler(), and uacpi_install_gpe_handler_raw().

◆ do_match_gpe_methods()

static uacpi_iteration_decision do_match_gpe_methods ( uacpi_handle  opaque,
uacpi_namespace_node *  node,
uacpi_u32  depth 
)
static

Definition at line 1477 of file event.c.

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}
@ UACPI_GPE_TRIGGERING_LEVEL
Definition: event.h:117
#define UACPI_UNUSED(x)
Definition: helpers.h:7
#define UACPI_FALLTHROUGH
Definition: compiler.h:100
static uacpi_status gpe_set_aml_handler(struct gp_event *event, uacpi_namespace_node *node, uacpi_u8 triggering)
Definition: event.c:1453
static uacpi_status gpe_ensure_work_item(struct gp_event *event)
Definition: event.c:1125
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
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
Definition: dlist.c:348

Referenced by create_gpe_block(), and uacpi_events_match_post_dynamic_table_load().

◆ event_config_lock()

static uacpi_status event_config_lock ( void  )
static

Definition at line 45 of file event.c.

46{
48
51 return ret;
52
56
57 return ret;
58}
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
static struct uacpi_recursive_lock g_event_lock
Definition: event.c:30
static struct uacpi_recursive_lock g_event_config_lock
Definition: event.c:42

Referenced by do_install_gpe_handler(), gpe_get_mask_unmask(), uacpi_deinitialize_events(), uacpi_install_fixed_event_handler(), uacpi_install_gpe_block(), uacpi_setup_gpe_for_wake(), uacpi_uninstall_fixed_event_handler(), uacpi_uninstall_gpe_block(), and uacpi_uninstall_gpe_handler().

◆ event_config_unlock()

◆ find_or_create_gpe_interrupt_ctx()

static uacpi_status find_or_create_gpe_interrupt_ctx ( uacpi_u32  irq,
struct gpe_interrupt_ctx **  out_ctx 
)
static

Definition at line 1037 of file event.c.

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}
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:18
static struct gpe_interrupt_ctx * g_gpe_interrupt_head
Definition: event.c:504
static uacpi_interrupt_ret handle_gpes(uacpi_handle opaque)
Definition: event.c:1027
uint32_t entry
Definition: isohybrid.c:63
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

Referenced by create_gpe_block(), and uacpi_initialize_events().

◆ for_all_gpes_locked()

static uacpi_status for_all_gpes_locked ( struct do_for_all_gpes_ctx *  ctx)
static

Definition at line 2817 of file event.c.

2818{
2820
2822
2825
2828 return ret;
2829
2831
2833 return ctx->ret;
2834}
static void for_each_gpe_block(gpe_block_iteration_callback cb, uacpi_handle handle)
Definition: event.c:1736
static uacpi_iteration_decision do_for_all_gpes(struct gpe_block *block, uacpi_handle opaque)
Definition: event.c:2804

Referenced by uacpi_disable_all_gpes(), uacpi_enable_all_runtime_gpes(), and uacpi_enable_all_wake_gpes().

◆ for_each_gpe_block()

static void for_each_gpe_block ( gpe_block_iteration_callback  cb,
uacpi_handle  handle 
)
static

Definition at line 1736 of file event.c.

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}
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
uacpi_iteration_decision
Definition: types.h:28
struct gpe_interrupt_ctx * irq_ctx
Definition: event.c:487

Referenced by for_all_gpes_locked(), get_gpe(), uacpi_clear_all_events(), uacpi_finalize_gpe_initialization(), and uacpi_uninstall_gpe_block().

◆ free_gpe_block()

static void free_gpe_block ( struct gpe_block *  block)
static

Definition at line 1223 of file event.c.

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}
void uacpi_unmap_gas_nofree(uacpi_mapped_gas *gas)
Definition: io.c:1049
static void gpe_release_implicit_notify_handlers(struct gp_event *event)
Definition: event.c:1137
void uacpi_kernel_free_work_item(uacpi_handle)

Referenced by create_gpe_block(), and uninstall_gpe_block().

◆ get_gpe()

static struct gp_event * get_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)
static

Definition at line 1783 of file event.c.

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}
static uacpi_iteration_decision do_find_gpe(struct gpe_block *block, uacpi_handle opaque)
Definition: event.c:1766
uacpi_namespace_node * gpe_device
Definition: event.c:1760

Referenced by sanitize_device_and_find_gpe(), and uacpi_install_gpe_block().

◆ gp_event_toggle_masks()

static void gp_event_toggle_masks ( struct gp_event *  event,
uacpi_bool  set_on 
)
static

Definition at line 1796 of file event.c.

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}

Referenced by gpe_add_user(), and gpe_remove_user_unlocked().

◆ gpe_add_user()

static uacpi_status gpe_add_user ( struct gp_event *  event,
enum event_clear_if_first  clear_if_first,
uacpi_bool *  out_is_first 
)
static

Definition at line 1851 of file event.c.

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}
static void gp_event_toggle_masks(struct gp_event *event, uacpi_bool set_on)
Definition: event.c:1796

Referenced by do_initialize_gpe_block(), uacpi_enable_gpe(), and uacpi_uninstall_gpe_handler().

◆ gpe_block_apply_action()

static uacpi_status gpe_block_apply_action ( struct gpe_block *  block,
enum gpe_block_action  action 
)
static

Definition at line 1159 of file event.c.

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}
action
Definition: namespace.c:714
Definition: pdh_main.c:64

Referenced by do_for_all_gpes().

◆ gpe_disarm()

static void gpe_disarm ( struct gp_event *  event)
static

Definition at line 588 of file event.c.

589{
591
593 event->reg->armed_mask &= ~gpe_get_mask(event);
595}

Referenced by gpe_mask_and_flush().

◆ gpe_drop_claim()

static void gpe_drop_claim ( struct gp_event *  event)
static

Definition at line 1436 of file event.c.

1437{
1439
1441 event->block_interrupts = UACPI_FALSE;
1442 event->clear_on_restore = UACPI_FALSE;
1444}

Referenced by do_install_gpe_handler(), and uacpi_uninstall_gpe_handler().

◆ gpe_enable_disable_for_wake()

static uacpi_status gpe_enable_disable_for_wake ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx,
uacpi_bool  enabled 
)
static

Definition at line 2746 of file event.c.

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}
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLenum GLint GLuint mask
Definition: glext.h:6028

Referenced by uacpi_disable_gpe_for_wake(), and uacpi_enable_gpe_for_wake().

◆ gpe_ensure_work_item()

static uacpi_status gpe_ensure_work_item ( struct gp_event *  event)
static

Definition at line 1125 of file event.c.

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}
uacpi_handle uacpi_kernel_create_work_item(void)

Referenced by do_match_gpe_methods(), and uacpi_setup_gpe_for_wake().

◆ gpe_from_block()

static struct gp_event * gpe_from_block ( struct gpe_block *  block,
uacpi_u16  idx 
)
static

Definition at line 1388 of file event.c.

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}
uint16_t uacpi_u16
Definition: types.h:20
GLintptr offset
Definition: glext.h:5920

Referenced by do_find_gpe(), and do_match_gpe_methods().

◆ gpe_get_mask()

static uacpi_u8 gpe_get_mask ( struct gp_event *  event)
static

◆ gpe_get_mask_unmask()

static uacpi_status gpe_get_mask_unmask ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx,
uacpi_bool  should_mask 
)
static

Definition at line 2551 of file event.c.

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}

Referenced by uacpi_mask_gpe(), and uacpi_unmask_gpe().

◆ gpe_is_armed()

static uacpi_bool gpe_is_armed ( struct gp_event *  event)
static

Definition at line 576 of file event.c.

577{
580
582 ret = (event->reg->armed_mask & gpe_get_mask(event)) != 0;
584
585 return ret;
586}

Referenced by gpe_mask_and_flush().

◆ gpe_mask_and_flush()

static uacpi_status gpe_mask_and_flush ( struct gp_event *  event)
static

Definition at line 1923 of file event.c.

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}
static uacpi_status set_gpe_state(struct gp_event *event, enum gpe_state state)
Definition: event.c:557
static void gpe_disarm(struct gp_event *event)
Definition: event.c:588
static uacpi_bool gpe_is_armed(struct gp_event *event)
Definition: event.c:576
static void wait_for_work_completion_unlocked(void)
Definition: event.c:76

Referenced by gpe_mask_safe(), and gpe_mask_unmask().

◆ gpe_mask_safe()

static uacpi_status gpe_mask_safe ( struct gp_event *  event,
uacpi_bool *  out_did_mask 
)
static

Definition at line 2048 of file event.c.

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}
static uacpi_status gpe_mask_and_flush(struct gp_event *event)
Definition: event.c:1923

Referenced by do_install_gpe_handler(), uacpi_setup_gpe_for_wake(), and uacpi_uninstall_gpe_handler().

◆ gpe_mask_unmask()

static uacpi_status gpe_mask_unmask ( struct gp_event *  event,
uacpi_bool  should_mask 
)
static

Definition at line 1984 of file event.c.

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}

Referenced by do_install_gpe_handler(), gpe_get_mask_unmask(), gpe_mask_safe(), gpe_mask_unmask(), uacpi_setup_gpe_for_wake(), and uacpi_uninstall_gpe_handler().

◆ gpe_needs_polling()

static uacpi_bool gpe_needs_polling ( struct gp_event *  event,
uacpi_bool  is_first_user 
)
static

Definition at line 1909 of file event.c.

1912{
1913 return is_first_user && event->triggering == UACPI_GPE_TRIGGERING_EDGE;
1914}

Referenced by do_initialize_gpe_block(), uacpi_enable_gpe(), and uacpi_uninstall_gpe_handler().

◆ gpe_release_implicit_notify_handlers()

static void gpe_release_implicit_notify_handlers ( struct gp_event *  event)
static

Definition at line 1137 of file event.c.

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}

Referenced by free_gpe_block(), and gpe_set_aml_handler().

◆ gpe_remove_user()

static uacpi_status gpe_remove_user ( struct gp_event *  event)
static

Definition at line 1834 of file event.c.

1835{
1838
1842
1843 return ret;
1844}
static uacpi_status gpe_remove_user_unlocked(struct gp_event *event)
Definition: event.c:1814

Referenced by do_install_gpe_handler().

◆ gpe_remove_user_unlocked()

static uacpi_status gpe_remove_user_unlocked ( struct gp_event *  event)
static

Definition at line 1814 of file event.c.

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}

Referenced by gpe_remove_user(), uacpi_disable_gpe(), and uacpi_setup_gpe_for_wake().

◆ gpe_set_aml_handler()

static uacpi_status gpe_set_aml_handler ( struct gp_event *  event,
uacpi_namespace_node *  node,
uacpi_u8  triggering 
)
static

Definition at line 1453 of file event.c.

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}

Referenced by do_match_gpe_methods().

◆ gpe_set_handler()

static void gpe_set_handler ( struct gp_event *  event,
uacpi_handle  handler,
enum gpe_handler_type  type,
uacpi_u8  triggering 
)
static

Definition at line 1413 of file event.c.

1417{
1419
1421 event->any_handler = handler;
1422 event->handler_type = type;
1423 event->triggering = triggering;
1425}

Referenced by do_install_gpe_handler(), gpe_set_aml_handler(), uacpi_setup_gpe_for_wake(), and uacpi_uninstall_gpe_handler().

◆ gpe_suspend_resume()

static uacpi_status gpe_suspend_resume ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx,
enum gpe_state  state 
)
static

Definition at line 2486 of file event.c.

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}
static int state
Definition: maze.c:121

Referenced by uacpi_resume_gpe(), and uacpi_suspend_gpe().

◆ gpe_try_claim()

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 
)
static

Definition at line 770 of file event.c.

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}
uacpi_mapped_gas status
Definition: event.c:451

Referenced by dispatch_gpe().

◆ gpe_work_done()

static void gpe_work_done ( struct gp_event *  event)
static

Definition at line 633 of file event.c.

Referenced by async_restore_gpe(), and dispatch_gpe().

◆ handle_fixed_events()

static uacpi_interrupt_ret handle_fixed_events ( void  )
static

Definition at line 323 of file event.c.

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}
@ UACPI_FIXED_EVENT_MAX
Definition: event.h:17
uacpi_status uacpi_read_register(uacpi_register, uacpi_u64 *)
Definition: registers.c:227
@ UACPI_REGISTER_PM1_EN
Definition: registers.h:18
@ UACPI_REGISTER_PM1_STS
Definition: registers.h:17
static const struct fixed_event fixed_events[UACPI_FIXED_EVENT_MAX+1]
Definition: event.c:95
static uacpi_interrupt_ret dispatch_fixed_event(const struct fixed_event *ev, uacpi_fixed_event event)
Definition: event.c:283
uacpi_u16 status_mask
Definition: event.c:87
uacpi_u16 enable_mask
Definition: event.c:86

Referenced by handle_sci().

◆ handle_global_lock()

static uacpi_interrupt_ret handle_global_lock ( uacpi_handle  ctx)
static

Definition at line 2990 of file event.c.

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}
static void uacpi_signal_native_event(uacpi_handle evt)
Definition: mutex.h:95

Referenced by uacpi_initialize_events().

◆ handle_gpes()

static uacpi_interrupt_ret handle_gpes ( uacpi_handle  opaque)
static

Definition at line 1027 of file event.c.

1028{
1029 struct gpe_interrupt_ctx *ctx = opaque;
1030
1033
1035}
static uacpi_interrupt_ret detect_gpes(struct gpe_interrupt_ctx *ctx, enum gpe_dispatcher dispatcher)
Definition: event.c:953

Referenced by find_or_create_gpe_interrupt_ctx(), handle_sci(), and unlink_gpe_interrupt_ctx().

◆ handle_sci()

static uacpi_interrupt_ret handle_sci ( uacpi_handle  ctx)
static

Definition at line 3017 of file event.c.

3018{
3020
3021 int_ret |= handle_fixed_events();
3022 int_ret |= handle_gpes(ctx);
3023
3024 return int_ret;
3025}
static uacpi_interrupt_ret handle_fixed_events(void)
Definition: event.c:323

Referenced by uacpi_deinitialize_events(), and uacpi_initialize_events().

◆ initialize_fixed_events()

static uacpi_status initialize_fixed_events ( void  )
static

Definition at line 140 of file event.c.

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}

Referenced by uacpi_initialize_events_early().

◆ initialize_gpes()

static uacpi_status initialize_gpes ( void  )
static

Definition at line 2860 of file event.c.

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}
uacpi_namespace_node * uacpi_namespace_get_predefined(uacpi_predefined_namespace)
Definition: namespace.c:269
@ UACPI_PREDEFINED_NAMESPACE_GPE
Definition: namespace.h:18
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

Referenced by uacpi_initialize_events().

◆ load_gpe_block()

static struct gpe_block * load_gpe_block ( struct gpe_block **  block)
static

Definition at line 948 of file event.c.

949{
950 return (struct gpe_block*)uacpi_atomic_load_ptr(block);
951}
#define uacpi_atomic_load_ptr(ptr_to_ptr)
Definition: atomic.h:343

Referenced by detect_gpes().

◆ maybe_dispatch_gpe()

static uacpi_status maybe_dispatch_gpe ( uacpi_namespace_node *  gpe_device,
struct gp_event *  event 
)
static

Definition at line 1008 of file event.c.

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}

Referenced by uacpi_enable_gpe(), and uacpi_uninstall_gpe_handler().

◆ restore_gpe()

static uacpi_status restore_gpe ( struct gp_event *  event)
static

Definition at line 621 of file event.c.

622{
625
629
630 return ret;
631}
static uacpi_status restore_gpe_unlocked(struct gp_event *event)
Definition: event.c:598

Referenced by async_restore_gpe(), and dispatch_gpe().

◆ restore_gpe_unlocked()

static uacpi_status restore_gpe_unlocked ( struct gp_event *  event)
static

Definition at line 598 of file event.c.

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}

Referenced by restore_gpe(), and uacpi_finish_handling_gpe().

◆ sanitize_device_and_find_gpe()

static uacpi_status sanitize_device_and_find_gpe ( uacpi_namespace_node **  gpe_device,
uacpi_u16  idx,
struct gp_event **  out_event 
)
static

Definition at line 2189 of file event.c.

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}
static struct gp_event * get_gpe(uacpi_namespace_node *gpe_device, uacpi_u16 idx)
Definition: event.c:1783

Referenced by do_install_gpe_handler(), gpe_enable_disable_for_wake(), gpe_get_mask_unmask(), gpe_suspend_resume(), uacpi_clear_gpe(), uacpi_disable_gpe(), uacpi_enable_gpe(), uacpi_finish_handling_gpe(), uacpi_gpe_info(), uacpi_setup_gpe_for_wake(), and uacpi_uninstall_gpe_handler().

◆ set_event()

static uacpi_status set_event ( uacpi_u8  event,
uacpi_u8  value 
)
static

Definition at line 153 of file event.c.

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}
@ UACPI_STATUS_HARDWARE_TIMEOUT
Definition: status.h:28

Referenced by fire_event(), queue_add_timer(), queue_move_timer(), uacpi_disable_fixed_event(), uacpi_enable_fixed_event(), uacpi_events_restore_buttons_post_wake(), uacpi_install_fixed_event_handler(), and uacpi_uninstall_fixed_event_handler().

◆ set_gpe_state()

static uacpi_status set_gpe_state ( struct gp_event *  event,
enum gpe_state  state 
)
static

◆ set_gpe_state_unlocked()

static uacpi_status set_gpe_state_unlocked ( struct gp_event *  event,
enum gpe_state  state 
)
static

Definition at line 518 of file event.c.

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}

Referenced by dispatch_gpe(), gpe_add_user(), gpe_mask_unmask(), gpe_remove_user_unlocked(), gpe_suspend_resume(), restore_gpe_unlocked(), and set_gpe_state().

◆ uacpi_clear_all_events()

uacpi_status uacpi_clear_all_events ( void  )

Definition at line 3391 of file event.c.

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}
uacpi_status uacpi_write_register(uacpi_register, uacpi_u64)
Definition: registers.c:286
#define PM1_STATUS_BITS
Definition: event.c:3380

Referenced by enter_sleep_state_hw_full().

◆ uacpi_clear_fixed_event()

uacpi_status uacpi_clear_fixed_event ( uacpi_fixed_event  event)

Definition at line 229 of file event.c.

230{
232
233 if (uacpi_unlikely(event < 0 || event > UACPI_FIXED_EVENT_MAX))
236 return UACPI_STATUS_OK;
237
240 );
241}
@ UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED
Definition: types.h:72

◆ uacpi_clear_gpe()

uacpi_status uacpi_clear_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

◆ uacpi_deinitialize_events()

void uacpi_deinitialize_events ( void  )

Definition at line 3120 of file event.c.

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}
uacpi_status uacpi_recursive_lock_deinit(struct uacpi_recursive_lock *lock)
Definition: mutex.c:265
static uacpi_interrupt_ret handle_sci(uacpi_handle ctx)
Definition: event.c:3017
static void uninstall_gpe_block(struct gpe_block *block)
Definition: event.c:1296
uacpi_status uacpi_uninstall_fixed_event_handler(uacpi_fixed_event event)
Definition: event.c:3237
static void unlink_gpe_interrupt_ctx(struct gpe_interrupt_ctx *ctx)
Definition: event.c:1090
uacpi_status uacpi_kernel_uninstall_interrupt_handler(uacpi_interrupt_handler, uacpi_handle irq_handle)
Definition: uacpiosl.c:221
void uacpi_kernel_free_spinlock(uacpi_handle)
Definition: uacpiosl.c:92

Referenced by uacpi_state_reset().

◆ uacpi_disable_all_gpes()

uacpi_status uacpi_disable_all_gpes ( void  )

Definition at line 2836 of file event.c.

2837{
2838 struct do_for_all_gpes_ctx ctx = {
2840 };
2841 return for_all_gpes_locked(&ctx);
2842}
static uacpi_status for_all_gpes_locked(struct do_for_all_gpes_ctx *ctx)
Definition: event.c:2817

Referenced by enter_sleep_state_hw_full(), and wake_from_sleep_state_hw_full().

◆ uacpi_disable_fixed_event()

uacpi_status uacpi_disable_fixed_event ( uacpi_fixed_event  event)

Definition at line 210 of file event.c.

◆ uacpi_disable_gpe()

uacpi_status uacpi_disable_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

◆ uacpi_disable_gpe_for_wake()

uacpi_status uacpi_disable_gpe_for_wake ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

Definition at line 2792 of file event.c.

2795{
2796 return gpe_enable_disable_for_wake(gpe_device, idx, UACPI_FALSE);
2797}
static uacpi_status gpe_enable_disable_for_wake(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_bool enabled)
Definition: event.c:2746

◆ uacpi_enable_all_runtime_gpes()

uacpi_status uacpi_enable_all_runtime_gpes ( void  )

Definition at line 2844 of file event.c.

2845{
2846 struct do_for_all_gpes_ctx ctx = {
2848 };
2849 return for_all_gpes_locked(&ctx);
2850}

Referenced by wake_from_sleep_state_hw_full().

◆ uacpi_enable_all_wake_gpes()

uacpi_status uacpi_enable_all_wake_gpes ( void  )

Definition at line 2852 of file event.c.

2853{
2854 struct do_for_all_gpes_ctx ctx = {
2856 };
2857 return for_all_gpes_locked(&ctx);
2858}

Referenced by enter_sleep_state_hw_full().

◆ uacpi_enable_fixed_event()

uacpi_status uacpi_enable_fixed_event ( uacpi_fixed_event  event)

Definition at line 178 of file event.c.

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}
@ UACPI_STATUS_NO_HANDLER
Definition: status.h:25
#define UACPI_EVENT_ENABLED
Definition: event.c:16

◆ uacpi_enable_gpe()

uacpi_status uacpi_enable_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

Definition at line 2392 of file event.c.

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}
static uacpi_status maybe_dispatch_gpe(uacpi_namespace_node *gpe_device, struct gp_event *event)
Definition: event.c:1008

◆ uacpi_enable_gpe_for_wake()

uacpi_status uacpi_enable_gpe_for_wake ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

Definition at line 2785 of file event.c.

2788{
2789 return gpe_enable_disable_for_wake(gpe_device, idx, UACPI_TRUE);
2790}

◆ uacpi_events_match_post_dynamic_table_load()

void uacpi_events_match_post_dynamic_table_load ( void  )

Definition at line 1567 of file event.c.

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}
struct gpe_interrupt_ctx * next
Definition: event.c:498
struct gpe_block * gpe_head
Definition: event.c:500
uacpi_bool post_dynamic_table_load
Definition: event.c:1405

Referenced by do_load_table(), handle_load(), and handle_load_table().

◆ uacpi_events_restore_buttons_post_wake()

void uacpi_events_restore_buttons_post_wake ( void  )

Definition at line 243 of file event.c.

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}
@ UACPI_FIXED_EVENT_SLEEP_BUTTON
Definition: event.h:15
@ UACPI_FIXED_EVENT_POWER_BUTTON
Definition: event.h:14
#define UACPI_ARRAY_SIZE(arr)
Definition: helpers.h:5
HWND buttons[5]
Definition: sndrec32.cpp:40

Referenced by wake_from_sleep_state_hw_full().

◆ uacpi_finalize_gpe_initialization()

uacpi_status uacpi_finalize_gpe_initialization ( void  )

Definition at line 2154 of file event.c.

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}
static uacpi_iteration_decision do_initialize_gpe_block(struct gpe_block *block, uacpi_handle opaque)
Definition: event.c:2100

◆ uacpi_finish_handling_gpe()

uacpi_status uacpi_finish_handling_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

◆ uacpi_fixed_event_info()

uacpi_status uacpi_fixed_event_info ( uacpi_fixed_event  event,
uacpi_event_info *  out_info 
)

Definition at line 3284 of file event.c.

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}
uacpi_event_info
Definition: event.h:82

◆ uacpi_gpe_info()

uacpi_status uacpi_gpe_info ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx,
uacpi_event_info *  out_info 
)

Definition at line 3326 of file event.c.

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}

◆ uacpi_gpe_triggering_to_string()

const uacpi_char * uacpi_gpe_triggering_to_string ( uacpi_gpe_triggering  triggering)

Definition at line 1889 of file event.c.

1892{
1893 switch (triggering) {
1895 return "edge";
1897 return "level";
1898 default:
1899 return "invalid";
1900 }
1901}

Referenced by do_install_gpe_handler().

◆ uacpi_initialize_events()

uacpi_status uacpi_initialize_events ( void  )

Definition at line 3057 of file event.c.

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}
static uacpi_handle uacpi_create_native_event(void)
Definition: mutex.h:78
#define UACPI_FIXED_EVENT_GLOBAL_LOCK
Definition: event.h:6
static uacpi_interrupt_ret handle_global_lock(uacpi_handle ctx)
Definition: event.c:2990
uacpi_status uacpi_install_fixed_event_handler(uacpi_fixed_event event, uacpi_interrupt_handler handler, uacpi_handle user)
Definition: event.c:3193
static uacpi_status initialize_gpes(void)
Definition: event.c:2860
uacpi_handle uacpi_kernel_create_spinlock(void)
Definition: uacpiosl.c:85

Referenced by uacpi_namespace_load().

◆ uacpi_initialize_events_early()

uacpi_status uacpi_initialize_events_early ( void  )

Definition at line 3027 of file event.c.

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}
uacpi_status uacpi_recursive_lock_init(struct uacpi_recursive_lock *lock)
Definition: mutex.c:253
static uacpi_status initialize_fixed_events(void)
Definition: event.c:140

Referenced by uacpi_initialize().

◆ uacpi_install_fixed_event_handler()

uacpi_status uacpi_install_fixed_event_handler ( uacpi_fixed_event  event,
uacpi_interrupt_handler  handler,
uacpi_handle  user 
)

Definition at line 3193 of file event.c.

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}
void user(int argc, const char *argv[])
Definition: cmds.c:1350
uacpi_handle ctx
Definition: event.c:92
uacpi_interrupt_handler handler
Definition: event.c:91

Referenced by uacpi_initialize_events().

◆ uacpi_install_gpe_block()

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 at line 2914 of file event.c.

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}
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
uacpi_status uacpi_namespace_node_is(const uacpi_namespace_node *node, uacpi_object_type type, uacpi_bool *out)
Definition: namespace.c:832
@ UACPI_OBJECT_DEVICE
Definition: types.h:117

◆ uacpi_install_gpe_handler()

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 at line 2290 of file event.c.

2295{
2298 handler, ctx
2299 );
2300}
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

◆ uacpi_install_gpe_handler_raw()

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 at line 2302 of file event.c.

2307{
2310 handler, ctx
2311 );
2312}

◆ uacpi_mask_gpe()

uacpi_status uacpi_mask_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

Definition at line 2578 of file event.c.

2581{
2582 return gpe_get_mask_unmask(gpe_device, idx, UACPI_TRUE);
2583}
static uacpi_status gpe_get_mask_unmask(uacpi_namespace_node *gpe_device, uacpi_u16 idx, uacpi_bool should_mask)
Definition: event.c:2551

◆ uacpi_resume_gpe()

uacpi_status uacpi_resume_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

Definition at line 2519 of file event.c.

2522{
2523 return gpe_suspend_resume(gpe_device, idx, GPE_STATE_ENABLED);
2524}
static uacpi_status gpe_suspend_resume(uacpi_namespace_node *gpe_device, uacpi_u16 idx, enum gpe_state state)
Definition: event.c:2486

◆ uacpi_setup_gpe_for_wake()

uacpi_status uacpi_setup_gpe_for_wake ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx,
uacpi_namespace_node *  wake_device 
)

Definition at line 2592 of file event.c.

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}
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:264
#define uacpi_likely(expr)
Definition: compiler.h:89
@ UACPI_STATUS_INTERNAL_ERROR
Definition: status.h:21
uacpi_namespace_node * device
Definition: event.c:368
struct gpe_implicit_notify_handler * next
Definition: event.c:367

◆ uacpi_suspend_gpe()

uacpi_status uacpi_suspend_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

Definition at line 2512 of file event.c.

2515{
2516 return gpe_suspend_resume(gpe_device, idx, GPE_STATE_DISABLED);
2517}

◆ uacpi_uninstall_fixed_event_handler()

uacpi_status uacpi_uninstall_fixed_event_handler ( uacpi_fixed_event  event)

Definition at line 3237 of file event.c.

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}

Referenced by uacpi_deinitialize_events(), and uacpi_initialize_events().

◆ uacpi_uninstall_gpe_block()

uacpi_status uacpi_uninstall_gpe_block ( uacpi_namespace_node *  gpe_device)

Definition at line 2951 of file event.c.

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}
uacpi_u16 idx
Definition: event.c:1761
struct gpe_block * out_block
Definition: event.c:1762

◆ uacpi_uninstall_gpe_handler()

uacpi_status uacpi_uninstall_gpe_handler ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx,
uacpi_gpe_handler  handler 
)

Definition at line 2314 of file event.c.

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}

◆ uacpi_unmask_gpe()

uacpi_status uacpi_unmask_gpe ( uacpi_namespace_node *  gpe_device,
uacpi_u16  idx 
)

Definition at line 2585 of file event.c.

2588{
2589 return gpe_get_mask_unmask(gpe_device, idx, UACPI_FALSE);
2590}

◆ uninstall_gpe_block()

static void uninstall_gpe_block ( struct gpe_block *  block)
static

Definition at line 1296 of file event.c.

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}
struct gpe_block * next
Definition: event.c:475

Referenced by uacpi_deinitialize_events(), and uacpi_uninstall_gpe_block().

◆ unlink_gpe_interrupt_ctx()

static void unlink_gpe_interrupt_ctx ( struct gpe_interrupt_ctx *  ctx)
static

Definition at line 1090 of file event.c.

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}

Referenced by uacpi_deinitialize_events(), and uninstall_gpe_block().

◆ wait_for_work_completion_unlocked()

static void wait_for_work_completion_unlocked ( void  )
static

Variable Documentation

◆ fixed_event_handlers

◆ fixed_events

◆ g_event_config_lock

◆ g_event_lock

◆ g_fixed_event_slock

◆ g_gpe_interrupt_head

◆ g_gpe_state_slock

◆ g_gpes_finalized

uacpi_bool g_gpes_finalized
static