diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-07-01 11:01:12 +0800 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-07-06 22:34:27 -0400 |
commit | 3bd741bd0dfcc1845ae6892baa5192c91addc84c (patch) | |
tree | 3effbfaefa7dfee2c7d7223772847236ea53f718 | |
parent | 3784730b02b9f147a55b0e4623fcad671273e6e6 (diff) | |
download | lwn-3bd741bd0dfcc1845ae6892baa5192c91addc84c.tar.gz lwn-3bd741bd0dfcc1845ae6892baa5192c91addc84c.zip |
ACPICA: Use low-level GPE enable during GPE block initialization
The GPE block initialization code in acpi_ev_initialize_gpe_block()
uses acpi_set_gpe() to make sure that the GPEs with nonzero
runtime counter will remain enabled, but since it already has
a struct acpi_gpe_event_info object for each GPE, it might use
the low-level GPE enabling function, acpi_clear_and_enable_gpe(),
for this purpose.
To make that happen, move acpi_clear_and_enable_gpe() to
drivers/acpi/acpica/evgpe.c and rename it to acpi_ev_enable_gpe(),
modify the two existing users of it accordingly and modify
acpi_ev_initialize_gpe_block() to use it instead of acpi_set_gpe()
and to check its return value.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/acpica/acevents.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpe.c | 40 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpeblk.c | 7 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 42 |
4 files changed, 47 insertions, 44 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index a561944fbaf9..e0e6affb0d80 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -80,6 +80,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); acpi_status acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); +acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); + struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 gpe_number); diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 9413ac61e440..56de460570d6 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -94,6 +94,46 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(AE_OK); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_enable_gpe + * + * PARAMETERS: gpe_event_info - GPE to enable + * + * RETURN: Status + * + * DESCRIPTION: Clear the given GPE from stale events and enable it. + * + ******************************************************************************/ +acpi_status +acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(ev_enable_gpe); + + /* + * We will only allow a GPE to be enabled if it has either an + * associated method (_Lxx/_Exx) or a handler. Otherwise, the + * GPE will be immediately disabled by acpi_ev_gpe_dispatch the + * first time it fires. + */ + if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { + return_ACPI_STATUS(AE_NO_HANDLER); + } + + /* Clear the GPE (of stale events) */ + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Enable the requested GPE */ + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); + + return_ACPI_STATUS(status); +} + /******************************************************************************* * diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 77e8630043f8..0c6f3f878eb5 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -508,10 +508,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, * increment its reference counter. */ if (gpe_event_info->runtime_count) { - acpi_set_gpe(gpe_device, gpe_number, - ACPI_GPE_ENABLE); - gpe_enabled_count++; - continue; + status = acpi_ev_enable_gpe(gpe_event_info); + goto enabled; } if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { @@ -530,6 +528,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, /* Enable this GPE */ status = acpi_enable_gpe(gpe_device, gpe_number); + enabled: if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 467fde961aef..b094cc0183d7 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -210,44 +210,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) /******************************************************************************* * - * FUNCTION: acpi_clear_and_enable_gpe - * - * PARAMETERS: gpe_event_info - GPE to enable - * - * RETURN: Status - * - * DESCRIPTION: Clear the given GPE from stale events and enable it. - * - ******************************************************************************/ -static acpi_status -acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) -{ - acpi_status status; - - /* - * We will only allow a GPE to be enabled if it has either an - * associated method (_Lxx/_Exx) or a handler. Otherwise, the - * GPE will be immediately disabled by acpi_ev_gpe_dispatch the - * first time it fires. - */ - if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { - return_ACPI_STATUS(AE_NO_HANDLER); - } - - /* Clear the GPE (of stale events) */ - status = acpi_hw_clear_gpe(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Enable the requested GPE */ - status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); - - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * * FUNCTION: acpi_set_gpe * * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 @@ -287,7 +249,7 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) switch (action) { case ACPI_GPE_ENABLE: - status = acpi_clear_and_enable_gpe(gpe_event_info); + status = acpi_ev_enable_gpe(gpe_event_info); break; case ACPI_GPE_DISABLE: @@ -414,7 +376,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) if (gpe_event_info->runtime_count == 1) { status = acpi_ev_update_gpe_enable_mask(gpe_event_info); if (ACPI_SUCCESS(status)) { - status = acpi_clear_and_enable_gpe(gpe_event_info); + status = acpi_ev_enable_gpe(gpe_event_info); } if (ACPI_FAILURE(status)) { gpe_event_info->runtime_count--; |