^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: evgpeinit - System GPE initialization and update
^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) #include "acnamesp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define _COMPONENT ACPI_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) ACPI_MODULE_NAME("evgpeinit")
^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) * Note: History of _PRW support in ACPICA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Originally (2000 - 2010), the GPE initialization code performed a walk of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * the entire namespace to execute the _PRW methods and detect all GPEs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * capable of waking the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * As of 10/2010, the _PRW method execution has been removed since it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * actually unnecessary. The host OS must in fact execute all _PRW methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * in order to identify the device/power-resource dependencies. We now put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * the onus on the host OS to identify the wake GPEs as part of this process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * and to inform ACPICA of these GPEs via the acpi_setup_gpe_for_wake interface. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * not only reduces the complexity of the ACPICA initialization code, but in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * some cases (on systems with very large namespaces) it should reduce the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * kernel boot time as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ACPI_FADT_GPE_BLOCK_ADDRESS(N) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) acpi_gbl_FADT.xgpe##N##_block.space_id == \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ACPI_ADR_SPACE_SYSTEM_MEMORY ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) (u64)acpi_gbl_xgpe##N##_block_logical_address : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) acpi_gbl_FADT.xgpe##N##_block.address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ACPI_FADT_GPE_BLOCK_ADDRESS(N) acpi_gbl_FADT.xgpe##N##_block.address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif /* ACPI_GPE_USE_LOGICAL_ADDRESSES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * FUNCTION: acpi_ev_gpe_initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * DESCRIPTION: Initialize the GPE data structures and the FADT GPE 0/1 blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) acpi_status acpi_ev_gpe_initialize(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 register_count0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u32 register_count1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u32 gpe_number_max = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u64 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ACPI_FUNCTION_TRACE(ev_gpe_initialize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "Initializing General Purpose Events (GPEs):\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^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) * Initialize the GPE Block(s) defined in the FADT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Why the GPE register block lengths are divided by 2: From the ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * Spec, section "General-Purpose Event Registers", we have:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * "Each register block contains two registers of equal length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * The length of the GPE1_STS and GPE1_EN registers is equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * half the GPE1_LEN. If a generic register block is not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * then its respective block pointer and block length values in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * to be the same size."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Determine the maximum GPE number for this machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Note: both GPE0 and GPE1 are optional, and either can exist without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * the other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * If EITHER the register length OR the block address are zero, then that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * particular block is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) address = ACPI_FADT_GPE_BLOCK_ADDRESS(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (acpi_gbl_FADT.gpe0_block_length && address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* GPE block 0 exists (has both length and address > 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) register_count0 = (u16)(acpi_gbl_FADT.gpe0_block_length / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) gpe_number_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) (register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Install GPE Block 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) acpi_gbl_FADT.xgpe0_block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) space_id, register_count0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) acpi_gbl_FADT.sci_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) &acpi_gbl_gpe_fadt_blocks[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ACPI_EXCEPTION((AE_INFO, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) "Could not create GPE Block 0"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) address = ACPI_FADT_GPE_BLOCK_ADDRESS(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (acpi_gbl_FADT.gpe1_block_length && address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* GPE block 1 exists (has both length and address > 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) register_count1 = (u16)(acpi_gbl_FADT.gpe1_block_length / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Check for GPE0/GPE1 overlap (if both banks exist) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if ((register_count0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "GPE0 block (GPE 0 to %u) overlaps the GPE1 block "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "(GPE %u to %u) - Ignoring GPE1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) gpe_number_max, acpi_gbl_FADT.gpe1_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) acpi_gbl_FADT.gpe1_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ((register_count1 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ACPI_GPE_REGISTER_WIDTH) - 1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Ignore GPE1 block by setting the register count to zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) register_count1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Install GPE Block 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) acpi_gbl_FADT.xgpe1_block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) space_id, register_count1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) acpi_gbl_FADT.gpe1_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) acpi_gbl_FADT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) sci_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) &acpi_gbl_gpe_fadt_blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) [1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ACPI_EXCEPTION((AE_INFO, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) "Could not create GPE Block 1"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * GPE0 and GPE1 do not have to be contiguous in the GPE number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * space. However, GPE0 always starts at GPE number zero.
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Exit if there are no GPE registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if ((register_count0 + register_count1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* GPEs are not required by ACPI, this is OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ACPI_DEBUG_PRINT((ACPI_DB_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "There are no GPE blocks defined in the FADT\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * FUNCTION: acpi_ev_update_gpes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * PARAMETERS: table_owner_id - ID of the newly-loaded ACPI table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * RETURN: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * result of a Load() or load_table() operation. If new GPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * methods have been installed, register the new methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct acpi_gpe_xrupt_info *gpe_xrupt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct acpi_gpe_block_info *gpe_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct acpi_gpe_walk_info walk_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * Find any _Lxx/_Exx GPE methods that have just been loaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Any GPEs that correspond to new _Lxx/_Exx methods are immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Examine the namespace underneath each gpe_device within the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * gpe_block lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return;
^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) walk_info.count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) walk_info.owner_id = table_owner_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) walk_info.execute_by_owner_id = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* Walk the interrupt level descriptor list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) while (gpe_xrupt_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Walk all Gpe Blocks attached to this interrupt level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) gpe_block = gpe_xrupt_info->gpe_block_list_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) while (gpe_block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) walk_info.gpe_block = gpe_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) walk_info.gpe_device = gpe_block->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) walk_info.gpe_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ACPI_UINT32_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ACPI_NS_WALK_NO_UNLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) acpi_ev_match_gpe_method,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) NULL, &walk_info, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ACPI_EXCEPTION((AE_INFO, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) "While decoding _Lxx/_Exx methods"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) gpe_block = gpe_block->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) gpe_xrupt_info = gpe_xrupt_info->next;
^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) if (walk_info.count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ACPI_INFO(("Enabled %u new GPEs", walk_info.count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * FUNCTION: acpi_ev_match_gpe_method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * PARAMETERS: Callback from walk_namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * control method under the _GPE portion of the namespace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * Extract the name and GPE type from the object, saving this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * information for quick lookup during GPE dispatch. Allows a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * per-owner_id evaluation if execute_by_owner_id is TRUE in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * walk_info parameter block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * The name of each GPE control method is of the form:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * "_Lxx" or "_Exx", where:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * L - means that the GPE is level triggered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * E - means that the GPE is edge triggered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * xx - is the GPE number [in HEX]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * with that owner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) acpi_ev_match_gpe_method(acpi_handle obj_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 level, void *context, void **return_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct acpi_namespace_node *method_node =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct acpi_gpe_walk_info *walk_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct acpi_gpe_event_info *gpe_event_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) u32 gpe_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) u8 temp_gpe_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) char name[ACPI_NAMESEG_SIZE + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ACPI_FUNCTION_TRACE(ev_match_gpe_method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Check if requested owner_id matches this owner_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if ((walk_info->execute_by_owner_id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) (method_node->owner_id != walk_info->owner_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^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) * Match and decode the _Lxx and _Exx GPE method names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * 1) Extract the method name and null terminate it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ACPI_MOVE_32_TO_32(name, &method_node->name.integer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) name[ACPI_NAMESEG_SIZE] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* 2) Name must begin with an underscore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (name[0] != '_') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return_ACPI_STATUS(AE_OK); /* Ignore this method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * 3) Edge/Level determination is based on the 2nd character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * of the method name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) switch (name[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case 'L':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) type = ACPI_GPE_LEVEL_TRIGGERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case 'E':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) type = ACPI_GPE_EDGE_TRIGGERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Unknown method type, just ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) "Ignoring unknown GPE method type: %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) "(name not of form _Lxx or _Exx)", name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* 4) The last two characters of the name are the hex GPE Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) status = acpi_ut_ascii_to_hex_byte(&name[2], &temp_gpe_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Conversion failed; invalid method, just ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) "Could not extract GPE number from name: %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) "(name is not of form _Lxx or _Exx)", name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Ensure that we have a valid GPE number for this GPE block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) gpe_number = (u32)temp_gpe_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) gpe_event_info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) acpi_ev_low_get_gpe_info(gpe_number, walk_info->gpe_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!gpe_event_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * This gpe_number is not valid for this GPE block, just ignore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * However, it may be valid for a different GPE block, since GPE0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * and GPE1 methods both appear under \_GPE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ACPI_GPE_DISPATCH_HANDLER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ACPI_GPE_DISPATCH_RAW_HANDLER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* If there is already a handler, ignore this GPE method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ACPI_GPE_DISPATCH_METHOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * If there is already a method, ignore this method. But check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * for a type mismatch (if both the _Lxx AND _Exx exist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (type != (gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) "For GPE 0x%.2X, found both _L%2.2X and _E%2.2X methods",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) gpe_number, gpe_number, gpe_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Disable the GPE in case it's been enabled already. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * Add the GPE information from above to the gpe_event_info block for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * use during dispatch of this GPE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) gpe_event_info->dispatch.method_node = method_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "Registered GPE method %s as GPE number 0x%.2X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) name, gpe_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) #endif /* !ACPI_REDUCED_HARDWARE */