--- zzzz-none-000/linux-3.10.107/drivers/acpi/acpica/hwgpe.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/acpi/acpica/hwgpe.c 2021-02-04 17:41:59.000000000 +0000 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,6 +54,10 @@ struct acpi_gpe_block_info *gpe_block, void *context); +static acpi_status +acpi_hw_gpe_enable_write(u8 enable_mask, + struct acpi_gpe_register_info *gpe_register_info); + /****************************************************************************** * * FUNCTION: acpi_hw_get_gpe_register_bit @@ -85,6 +89,8 @@ * RETURN: Status * * DESCRIPTION: Enable or disable a single GPE in the parent enable register. + * The enable_mask field of the involved GPE register must be + * updated by the caller if necessary. * ******************************************************************************/ @@ -118,23 +124,26 @@ switch (action) { case ACPI_GPE_CONDITIONAL_ENABLE: - /* Only enable if the enable_for_run bit is set */ + /* Only enable if the corresponding enable_mask bit is set */ - if (!(register_bit & gpe_register_info->enable_for_run)) { + if (!(register_bit & gpe_register_info->enable_mask)) { return (AE_BAD_PARAMETER); } /*lint -fallthrough */ case ACPI_GPE_ENABLE: + ACPI_SET_BIT(enable_mask, register_bit); break; case ACPI_GPE_DISABLE: + ACPI_CLEAR_BIT(enable_mask, register_bit); break; default: + ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action)); return (AE_BAD_PARAMETER); } @@ -199,7 +208,7 @@ acpi_status acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, - acpi_event_status * event_status) + acpi_event_status *event_status) { u32 in_byte; u32 register_bit; @@ -213,6 +222,13 @@ return (AE_BAD_PARAMETER); } + /* GPE currently handled? */ + + if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != + ACPI_GPE_DISPATCH_NONE) { + local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; + } + /* Get the info block for the entire GPE register */ gpe_register_info = gpe_event_info->register_info; @@ -233,6 +249,17 @@ local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED; } + /* GPE currently enabled (enable bit == 1)? */ + + status = acpi_hw_read(&in_byte, &gpe_register_info->enable_address); + if (ACPI_FAILURE(status)) { + return (status); + } + + if (register_bit & in_byte) { + local_event_status |= ACPI_EVENT_FLAG_ENABLE_SET; + } + /* GPE currently active (status bit == 1)? */ status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); @@ -241,7 +268,7 @@ } if (register_bit & in_byte) { - local_event_status |= ACPI_EVENT_FLAG_SET; + local_event_status |= ACPI_EVENT_FLAG_STATUS_SET; } /* Set return value */ @@ -252,6 +279,30 @@ /****************************************************************************** * + * FUNCTION: acpi_hw_gpe_enable_write + * + * PARAMETERS: enable_mask - Bit mask to write to the GPE register + * gpe_register_info - Gpe Register info + * + * RETURN: Status + * + * DESCRIPTION: Write the enable mask byte to the given GPE register. + * + ******************************************************************************/ + +static acpi_status +acpi_hw_gpe_enable_write(u8 enable_mask, + struct acpi_gpe_register_info *gpe_register_info) +{ + acpi_status status; + + gpe_register_info->enable_mask = enable_mask; + status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); + return (status); +} + +/****************************************************************************** + * * FUNCTION: acpi_hw_disable_gpe_block * * PARAMETERS: gpe_xrupt_info - GPE Interrupt info @@ -277,8 +328,8 @@ /* Disable all GPEs in this register */ status = - acpi_hw_write(0x00, - &gpe_block->register_info[i].enable_address); + acpi_hw_gpe_enable_write(0x00, + &gpe_block->register_info[i]); if (ACPI_FAILURE(status)) { return (status); } @@ -345,21 +396,23 @@ { u32 i; acpi_status status; + struct acpi_gpe_register_info *gpe_register_info; /* NOTE: assumes that all GPEs are currently disabled */ /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { - if (!gpe_block->register_info[i].enable_for_run) { + gpe_register_info = &gpe_block->register_info[i]; + if (!gpe_register_info->enable_for_run) { continue; } /* Enable all "runtime" GPEs in this register */ status = - acpi_hw_write(gpe_block->register_info[i].enable_for_run, - &gpe_block->register_info[i].enable_address); + acpi_hw_gpe_enable_write(gpe_register_info->enable_for_run, + gpe_register_info); if (ACPI_FAILURE(status)) { return (status); } @@ -389,19 +442,21 @@ { u32 i; acpi_status status; + struct acpi_gpe_register_info *gpe_register_info; /* Examine each GPE Register within the block */ for (i = 0; i < gpe_block->register_count; i++) { - if (!gpe_block->register_info[i].enable_for_wake) { - continue; - } + gpe_register_info = &gpe_block->register_info[i]; - /* Enable all "wake" GPEs in this register */ + /* + * Enable all "wake" GPEs in this register and disable the + * remaining ones. + */ status = - acpi_hw_write(gpe_block->register_info[i].enable_for_wake, - &gpe_block->register_info[i].enable_address); + acpi_hw_gpe_enable_write(gpe_register_info->enable_for_wake, + gpe_register_info); if (ACPI_FAILURE(status)) { return (status); }