^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: evgpeutil - GPE utilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "acevents.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define _COMPONENT ACPI_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ACPI_MODULE_NAME("evgpeutil")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * FUNCTION: acpi_ev_walk_gpe_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * PARAMETERS: gpe_walk_callback - Routine called for each GPE block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * context - Value passed to callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * DESCRIPTION: Walk the GPE lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct acpi_gpe_block_info *gpe_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct acpi_gpe_xrupt_info *gpe_xrupt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) acpi_cpu_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ACPI_FUNCTION_TRACE(ev_walk_gpe_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Walk the interrupt level descriptor list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) while (gpe_xrupt_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Walk all Gpe Blocks attached to this interrupt level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) gpe_block = gpe_xrupt_info->gpe_block_list_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) while (gpe_block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* One callback per GPE block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) gpe_walk_callback(gpe_xrupt_info, gpe_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (status == AE_CTRL_END) { /* Callback abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) goto unlock_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) gpe_block = gpe_block->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) gpe_xrupt_info = gpe_xrupt_info->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unlock_and_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * FUNCTION: acpi_ev_get_gpe_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * PARAMETERS: GPE_WALK_CALLBACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * block device. NULL if the GPE is one of the FADT-defined GPEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct acpi_gpe_block_info *gpe_block, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct acpi_gpe_device_info *info = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* Increment Index by the number of GPEs in this block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) info->next_block_base_index += gpe_block->gpe_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (info->index < info->next_block_base_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * The GPE index is within this block, get the node. Leave the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * NULL for the FADT-defined GPEs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) info->gpe_device = gpe_block->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) info->status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return (AE_CTRL_END);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * FUNCTION: acpi_ev_get_gpe_xrupt_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * PARAMETERS: interrupt_number - Interrupt for a GPE block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * gpe_xrupt_block - Where the block is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * block per unique interrupt level used for GPEs. Should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * called only when the GPE lists are semaphore locked and not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * subject to change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) acpi_ev_get_gpe_xrupt_block(u32 interrupt_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct acpi_gpe_xrupt_info **gpe_xrupt_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct acpi_gpe_xrupt_info *next_gpe_xrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct acpi_gpe_xrupt_info *gpe_xrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) acpi_cpu_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ACPI_FUNCTION_TRACE(ev_get_gpe_xrupt_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* No need for lock since we are not changing any list elements here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) while (next_gpe_xrupt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (next_gpe_xrupt->interrupt_number == interrupt_number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *gpe_xrupt_block = next_gpe_xrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) next_gpe_xrupt = next_gpe_xrupt->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Not found, must allocate a new xrupt descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) gpe_xrupt = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_xrupt_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!gpe_xrupt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return_ACPI_STATUS(AE_NO_MEMORY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) gpe_xrupt->interrupt_number = interrupt_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Install new interrupt descriptor with spin lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (acpi_gbl_gpe_xrupt_list_head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) while (next_gpe_xrupt->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) next_gpe_xrupt = next_gpe_xrupt->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) next_gpe_xrupt->next = gpe_xrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) gpe_xrupt->previous = next_gpe_xrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) acpi_gbl_gpe_xrupt_list_head = gpe_xrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* Install new interrupt handler if not SCI_INT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (interrupt_number != acpi_gbl_FADT.sci_interrupt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) status = acpi_os_install_interrupt_handler(interrupt_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) acpi_ev_gpe_xrupt_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) gpe_xrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ACPI_EXCEPTION((AE_INFO, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) "Could not install GPE interrupt handler at level 0x%X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) interrupt_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *gpe_xrupt_block = gpe_xrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * FUNCTION: acpi_ev_delete_gpe_xrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * PARAMETERS: gpe_xrupt - A GPE interrupt info block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * DESCRIPTION: Remove and free a gpe_xrupt block. Remove an associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * interrupt handler if not the SCI interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) acpi_cpu_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ACPI_FUNCTION_TRACE(ev_delete_gpe_xrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* We never want to remove the SCI interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) gpe_xrupt->gpe_block_list_head = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Disable this interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) acpi_os_remove_interrupt_handler(gpe_xrupt->interrupt_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) acpi_ev_gpe_xrupt_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Unlink the interrupt block with lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (gpe_xrupt->previous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) gpe_xrupt->previous->next = gpe_xrupt->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* No previous, update list head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (gpe_xrupt->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) gpe_xrupt->next->previous = gpe_xrupt->previous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Free the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ACPI_FREE(gpe_xrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * FUNCTION: acpi_ev_delete_gpe_handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * gpe_block - Gpe Block info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * Used only prior to termination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct acpi_gpe_block_info *gpe_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct acpi_gpe_event_info *gpe_event_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct acpi_gpe_notify_info *notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct acpi_gpe_notify_info *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u32 j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* Examine each GPE Register within the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) for (i = 0; i < gpe_block->register_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Now look at the individual GPEs in this byte register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) gpe_event_info = &gpe_block->event_info[((acpi_size)i *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ACPI_GPE_REGISTER_WIDTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) + j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ACPI_GPE_DISPATCH_HANDLER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ACPI_GPE_DISPATCH_RAW_HANDLER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Delete an installed handler block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ACPI_FREE(gpe_event_info->dispatch.handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) gpe_event_info->dispatch.handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) gpe_event_info->flags &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ~ACPI_GPE_DISPATCH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) } else if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) == ACPI_GPE_DISPATCH_NOTIFY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Delete the implicit notification device list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) notify = gpe_event_info->dispatch.notify_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) while (notify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) next = notify->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ACPI_FREE(notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) notify = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) gpe_event_info->dispatch.notify_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) gpe_event_info->flags &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ~ACPI_GPE_DISPATCH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) #endif /* !ACPI_REDUCED_HARDWARE */