^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: hwgpe - Low level GPE enable/disable/clear functions
^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_HARDWARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) ACPI_MODULE_NAME("hwgpe")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct acpi_gpe_block_info *gpe_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) void *context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) acpi_hw_gpe_enable_write(u8 enable_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct acpi_gpe_register_info *gpe_register_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * FUNCTION: acpi_hw_gpe_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * PARAMETERS: value - Where the value is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * reg - GPE register structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * DESCRIPTION: Read from a GPE register in either memory or IO space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * LIMITATIONS: <These limitations also apply to acpi_hw_gpe_write>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * space_ID must be system_memory or system_IO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u32 value32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *value = (u64)ACPI_GET8((unsigned long)reg->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return acpi_os_read_memory((acpi_physical_address)reg->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) value, ACPI_GPE_REGISTER_WIDTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) status = acpi_os_read_port((acpi_io_address)reg->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) &value32, ACPI_GPE_REGISTER_WIDTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) *value = (u64)value32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^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) * FUNCTION: acpi_hw_gpe_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * PARAMETERS: value - Value to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * reg - GPE register structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * DESCRIPTION: Write to a GPE register in either memory or IO space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ACPI_SET8((unsigned long)reg->address, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return acpi_os_write_memory((acpi_physical_address)reg->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) value, ACPI_GPE_REGISTER_WIDTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return acpi_os_write_port((acpi_io_address)reg->address, (u32)value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ACPI_GPE_REGISTER_WIDTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * FUNCTION: acpi_hw_get_gpe_register_bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * PARAMETERS: gpe_event_info - Info block for the GPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * RETURN: Register mask with a one in the GPE bit position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * correct position for the input GPE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ((u32)1 <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (gpe_event_info->gpe_number -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) gpe_event_info->register_info->base_gpe_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * FUNCTION: acpi_hw_low_set_gpe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * action - Enable or disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * The enable_mask field of the involved GPE register must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * updated by the caller if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct acpi_gpe_register_info *gpe_register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u64 enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 register_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Get the info block for the entire GPE register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) gpe_register_info = gpe_event_info->register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!gpe_register_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return (AE_NOT_EXIST);
^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) /* Get current value of the enable register that contains this GPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) status = acpi_hw_gpe_read(&enable_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) &gpe_register_info->enable_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Set or clear just the bit that corresponds to this GPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case ACPI_GPE_CONDITIONAL_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* Only enable if the corresponding enable_mask bit is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!(register_bit & gpe_register_info->enable_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /*lint -fallthrough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case ACPI_GPE_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ACPI_SET_BIT(enable_mask, register_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case ACPI_GPE_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ACPI_CLEAR_BIT(enable_mask, register_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return (AE_BAD_PARAMETER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (!(register_bit & gpe_register_info->mask_for_run)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Write the updated enable mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) status = acpi_hw_gpe_write(enable_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) &gpe_register_info->enable_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return (status);
^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) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * FUNCTION: acpi_hw_clear_gpe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * DESCRIPTION: Clear the status bit for a single GPE.
^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_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct acpi_gpe_register_info *gpe_register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u32 register_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Get the info block for the entire GPE register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) gpe_register_info = gpe_event_info->register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!gpe_register_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return (AE_NOT_EXIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Write a one to the appropriate bit in the status register to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * clear this GPE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) status = acpi_hw_gpe_write(register_bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) &gpe_register_info->status_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * FUNCTION: acpi_hw_get_gpe_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * PARAMETERS: gpe_event_info - Info block for the GPE to queried
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * event_status - Where the GPE status is returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * DESCRIPTION: Return the status of a single GPE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) acpi_event_status *event_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) u64 in_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u32 register_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct acpi_gpe_register_info *gpe_register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) acpi_event_status local_event_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ACPI_FUNCTION_ENTRY();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!event_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return (AE_BAD_PARAMETER);
^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) /* GPE currently handled? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ACPI_GPE_DISPATCH_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* Get the info block for the entire GPE register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) gpe_register_info = gpe_event_info->register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Get the register bitmask for this GPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* GPE currently enabled? (enabled for runtime?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (register_bit & gpe_register_info->enable_for_run) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) local_event_status |= ACPI_EVENT_FLAG_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* GPE currently masked? (masked for runtime?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (register_bit & gpe_register_info->mask_for_run) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) local_event_status |= ACPI_EVENT_FLAG_MASKED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* GPE enabled for wake? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (register_bit & gpe_register_info->enable_for_wake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* GPE currently enabled (enable bit == 1)? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->enable_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (register_bit & in_byte) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) local_event_status |= ACPI_EVENT_FLAG_ENABLE_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* GPE currently active (status bit == 1)? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->status_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return (status);
^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) if (register_bit & in_byte) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) local_event_status |= ACPI_EVENT_FLAG_STATUS_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Set return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) (*event_status) = local_event_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return (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) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * FUNCTION: acpi_hw_gpe_enable_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * PARAMETERS: enable_mask - Bit mask to write to the GPE register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * gpe_register_info - Gpe Register info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * DESCRIPTION: Write the enable mask byte to the given GPE register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) acpi_hw_gpe_enable_write(u8 enable_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct acpi_gpe_register_info *gpe_register_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) gpe_register_info->enable_mask = enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) status = acpi_hw_gpe_write(enable_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) &gpe_register_info->enable_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^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) * FUNCTION: acpi_hw_disable_gpe_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * gpe_block - Gpe Block info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * DESCRIPTION: Disable all GPEs within a single GPE block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct acpi_gpe_block_info *gpe_block, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Examine each GPE Register within the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) for (i = 0; i < gpe_block->register_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Disable all GPEs in this register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) acpi_hw_gpe_enable_write(0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) &gpe_block->register_info[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^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) * FUNCTION: acpi_hw_clear_gpe_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * gpe_block - Gpe Block info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct acpi_gpe_block_info *gpe_block, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* Examine each GPE Register within the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) for (i = 0; i < gpe_block->register_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* Clear status on all GPEs in this register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) status = acpi_hw_gpe_write(0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) &gpe_block->register_info[i].status_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * FUNCTION: acpi_hw_enable_runtime_gpe_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * gpe_block - Gpe Block info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * combination wake/run GPEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct acpi_gpe_block_info *gpe_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct acpi_gpe_register_info *gpe_register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) u8 enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* NOTE: assumes that all GPEs are currently disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* Examine each GPE Register within the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) for (i = 0; i < gpe_block->register_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) gpe_register_info = &gpe_block->register_info[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (!gpe_register_info->enable_for_run) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Enable all "runtime" GPEs in this register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) enable_mask = gpe_register_info->enable_for_run &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ~gpe_register_info->mask_for_run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) acpi_hw_gpe_enable_write(enable_mask, gpe_register_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * FUNCTION: acpi_hw_enable_wakeup_gpe_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * gpe_block - Gpe Block info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * combination wake/run GPEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct acpi_gpe_block_info *gpe_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct acpi_gpe_register_info *gpe_register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* Examine each GPE Register within the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) for (i = 0; i < gpe_block->register_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) gpe_register_info = &gpe_block->register_info[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * Enable all "wake" GPEs in this register and disable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * remaining ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) acpi_hw_gpe_enable_write(gpe_register_info->enable_for_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) gpe_register_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return (status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct acpi_gpe_block_status_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct acpi_gpe_register_info *gpe_skip_register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u8 gpe_skip_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u8 retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * FUNCTION: acpi_hw_get_gpe_block_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * PARAMETERS: gpe_xrupt_info - GPE Interrupt info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * gpe_block - Gpe Block info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * context - GPE list walk context data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * RETURN: Success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * DESCRIPTION: Produce a combined GPE status bits mask for the given block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct acpi_gpe_block_info *gpe_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct acpi_gpe_block_status_context *c = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct acpi_gpe_register_info *gpe_register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) u64 in_enable, in_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) u8 ret_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* Examine each GPE Register within the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) for (i = 0; i < gpe_block->register_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) gpe_register_info = &gpe_block->register_info[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) status = acpi_hw_gpe_read(&in_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) &gpe_register_info->enable_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) status = acpi_hw_gpe_read(&in_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) &gpe_register_info->status_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ret_mask = in_enable & in_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (ret_mask && c->gpe_skip_register_info == gpe_register_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ret_mask &= ~c->gpe_skip_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) c->retval |= ret_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return (AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * FUNCTION: acpi_hw_disable_all_gpes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) acpi_status acpi_hw_disable_all_gpes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ACPI_FUNCTION_TRACE(hw_disable_all_gpes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * FUNCTION: acpi_hw_enable_all_runtime_gpes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) acpi_status acpi_hw_enable_all_runtime_gpes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * FUNCTION: acpi_hw_enable_all_wakeup_gpes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) acpi_status acpi_hw_enable_all_wakeup_gpes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * FUNCTION: acpi_hw_check_all_gpes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * PARAMETERS: gpe_skip_device - GPE devoce of the GPE to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * gpe_skip_number - Number of the GPE to skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * RETURN: Combined status of all GPEs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * DESCRIPTION: Check all enabled GPEs in all GPE blocks, except for the one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * represented by the "skip" arguments, and return TRUE if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * status bit is set for at least one of them of FALSE otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct acpi_gpe_block_status_context context = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) .gpe_skip_register_info = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .retval = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct acpi_gpe_event_info *gpe_event_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) acpi_cpu_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ACPI_FUNCTION_TRACE(acpi_hw_check_all_gpes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) gpe_event_info = acpi_ev_get_gpe_event_info(gpe_skip_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) gpe_skip_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (gpe_event_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) context.gpe_skip_register_info = gpe_event_info->register_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) context.gpe_skip_mask = acpi_hw_get_gpe_register_bit(gpe_event_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) (void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return (context.retval != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #endif /* !ACPI_REDUCED_HARDWARE */