Skip to content

Commit

Permalink
ACPICA: Store GPE register enable masks upfront
Browse files Browse the repository at this point in the history
It is reported that ACPI interrupts do not work any more on
Dell Latitude D600 after commit c50f13c (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: c50f13c (ACPICA: Save current masks of enabled GPEs after enable register writes)
Cc: 3.19+ <stable@vger.kernel.org> # 3.19+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Rafael J. Wysocki committed Apr 15, 2015
1 parent 2b5083e commit 0ee0d34
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 13 deletions.
5 changes: 3 additions & 2 deletions drivers/acpi/acpica/evgpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
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);
}
Expand Down Expand Up @@ -123,7 +124,7 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)

/* 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);
}

Expand Down Expand Up @@ -202,7 +203,7 @@ acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
if (ACPI_SUCCESS(status)) {
status =
acpi_hw_low_set_gpe(gpe_event_info,
ACPI_GPE_DISABLE_SAVE);
ACPI_GPE_DISABLE);
}

if (ACPI_FAILURE(status)) {
Expand Down
11 changes: 4 additions & 7 deletions drivers/acpi/acpica/hwgpe.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
* 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.
*
******************************************************************************/

Expand Down Expand Up @@ -119,7 +121,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
/* 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 */
Expand Down Expand Up @@ -149,9 +151,6 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
/* 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);
}

Expand Down Expand Up @@ -297,10 +296,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);
}

Expand Down
4 changes: 0 additions & 4 deletions include/acpi/actypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -759,10 +759,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
Expand Down

0 comments on commit 0ee0d34

Please sign in to comment.