| From 0ee0d34985ceffe4036319e1e46df8bff591b9e3 Mon Sep 17 00:00:00 2001 |
| From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
| Date: Wed, 15 Apr 2015 04:00:27 +0200 |
| Subject: ACPICA: Store GPE register enable masks upfront |
| |
| From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
| |
| commit 0ee0d34985ceffe4036319e1e46df8bff591b9e3 upstream. |
| |
| It is reported that ACPI interrupts do not work any more on |
| Dell Latitude D600 after commit c50f13c672df (ACPICA: Save |
| current masks of enabled GPEs after enable register writes). |
| The problem turns out to be related to the fact that the |
| enable_mask and enable_for_run GPE bit masks are not in |
| sync (in the absence of any system suspend/resume events) |
| for at least one GPE register on that machine. |
| |
| Address this problem by writing the enable_for_run mask into |
| enable_mask as soon as enable_for_run is updated instead of |
| doing that only after the subsequent register write has |
| succeeded. For consistency, update acpi_hw_gpe_enable_write() |
| to store the bit mask to be written into the GPE register |
| in enable_mask unconditionally before the write. |
| |
| Since the ACPI_GPE_SAVE_MASK flag is not necessary any more after |
| that, drop it along with the symbols depending on it. |
| |
| Reported-and-tested-by: Jim Bos <jim876@xs4all.nl> |
| Fixes: c50f13c672df (ACPICA: Save current masks of enabled GPEs after enable register writes) |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/acpi/acpica/evgpe.c | 5 +++-- |
| drivers/acpi/acpica/hwgpe.c | 11 ++++------- |
| include/acpi/actypes.h | 4 ---- |
| 3 files changed, 7 insertions(+), 13 deletions(-) |
| |
| --- a/drivers/acpi/acpica/evgpe.c |
| +++ b/drivers/acpi/acpica/evgpe.c |
| @@ -92,6 +92,7 @@ acpi_ev_update_gpe_enable_mask(struct ac |
| ACPI_SET_BIT(gpe_register_info->enable_for_run, |
| (u8)register_bit); |
| } |
| + gpe_register_info->enable_mask = gpe_register_info->enable_for_run; |
| |
| return_ACPI_STATUS(AE_OK); |
| } |
| @@ -123,7 +124,7 @@ acpi_status acpi_ev_enable_gpe(struct ac |
| |
| /* Enable the requested GPE */ |
| |
| - status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE_SAVE); |
| + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); |
| return_ACPI_STATUS(status); |
| } |
| |
| @@ -202,7 +203,7 @@ acpi_ev_remove_gpe_reference(struct acpi |
| if (ACPI_SUCCESS(status)) { |
| status = |
| acpi_hw_low_set_gpe(gpe_event_info, |
| - ACPI_GPE_DISABLE_SAVE); |
| + ACPI_GPE_DISABLE); |
| } |
| |
| if (ACPI_FAILURE(status)) { |
| --- a/drivers/acpi/acpica/hwgpe.c |
| +++ b/drivers/acpi/acpica/hwgpe.c |
| @@ -89,6 +89,8 @@ u32 acpi_hw_get_gpe_register_bit(struct |
| * 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. |
| * |
| ******************************************************************************/ |
| |
| @@ -119,7 +121,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_even |
| /* Set or clear just the bit that corresponds to this GPE */ |
| |
| register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
| - switch (action & ~ACPI_GPE_SAVE_MASK) { |
| + switch (action) { |
| case ACPI_GPE_CONDITIONAL_ENABLE: |
| |
| /* Only enable if the corresponding enable_mask bit is set */ |
| @@ -149,9 +151,6 @@ acpi_hw_low_set_gpe(struct acpi_gpe_even |
| /* Write the updated enable mask */ |
| |
| status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); |
| - if (ACPI_SUCCESS(status) && (action & ACPI_GPE_SAVE_MASK)) { |
| - gpe_register_info->enable_mask = (u8)enable_mask; |
| - } |
| return (status); |
| } |
| |
| @@ -286,10 +285,8 @@ acpi_hw_gpe_enable_write(u8 enable_mask, |
| { |
| acpi_status status; |
| |
| + gpe_register_info->enable_mask = enable_mask; |
| status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); |
| - if (ACPI_SUCCESS(status)) { |
| - gpe_register_info->enable_mask = enable_mask; |
| - } |
| return (status); |
| } |
| |
| --- a/include/acpi/actypes.h |
| +++ b/include/acpi/actypes.h |
| @@ -756,10 +756,6 @@ typedef u32 acpi_event_status; |
| #define ACPI_GPE_ENABLE 0 |
| #define ACPI_GPE_DISABLE 1 |
| #define ACPI_GPE_CONDITIONAL_ENABLE 2 |
| -#define ACPI_GPE_SAVE_MASK 4 |
| - |
| -#define ACPI_GPE_ENABLE_SAVE (ACPI_GPE_ENABLE | ACPI_GPE_SAVE_MASK) |
| -#define ACPI_GPE_DISABLE_SAVE (ACPI_GPE_DISABLE | ACPI_GPE_SAVE_MASK) |
| |
| /* |
| * GPE info flags - Per GPE |