diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-10 15:58:57 +0100 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-10 15:58:57 +0100 |
commit | 55c39fc2b18c384f51d8ed47678cca851b80a063 (patch) | |
tree | d3263b37f61f29fc41bd504f731f82f4bfdf9a1c /drivers/acpi/acpica/evxfgpe.c | |
parent | bfa76d49576599a4b9f9b7a71f23d73d6dcff735 (diff) | |
parent | 2eedd3d8398b266ee8e846ded03218bb6a00e2c1 (diff) | |
download | linux-rt-55c39fc2b18c384f51d8ed47678cca851b80a063.tar.gz |
Merge branch 'acpica'
* acpica:
ACPICA: Events: Enable APIs to allow interrupt/polling adaptive request based GPE handling model
ACPICA: Events: Introduce acpi_set_gpe()/acpi_finish_gpe() to reduce divergences
ACPICA: Events: Introduce ACPI_GPE_DISPATCH_RAW_HANDLER to fix 2 issues for the current GPE APIs
ACPICA: Update version to 20150204
ACPICA: Update Copyright headers to 2015
ACPICA: Hardware: Cast GPE enable_mask before storing
ACPICA: Events: Cleanup GPE dispatcher type obtaining code
ACPICA: Events: Cleanup to move acpi_gbl_global_event_handler invocation out of acpi_ev_gpe_dispatch()
ACPICA: Events: Cleanup of resetting the GPE handler to NULL before removing
ACPICA: Events: Fix uninitialized variable
ACPICA: Events: Remove acpi_ev_valid_gpe_event() due to current restriction
ACPICA: Events: Remove duplicated sanity check in acpi_ev_enable_gpe()
ACPICA: Events: Back port "ACPICA: Save current masks of enabled GPEs after enable register writes"
ACPICA: Resources: Provide common part for struct acpi_resource_address structures.
ACPI: Introduce acpi_unload_parent_table() usages in Linux kernel
ACPICA: take ACPI_MTX_INTERPRETER in acpi_unload_table_id()
Diffstat (limited to 'drivers/acpi/acpica/evxfgpe.c')
-rw-r--r-- | drivers/acpi/acpica/evxfgpe.c | 123 |
1 files changed, 118 insertions, 5 deletions
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index e889a5304abd..70eb47e3d724 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,7 +132,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); if (gpe_event_info) { - if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != + if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != ACPI_GPE_DISPATCH_NONE) { status = acpi_ev_add_gpe_reference(gpe_event_info); } else { @@ -183,6 +183,77 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) ACPI_EXPORT_SYMBOL(acpi_disable_gpe) +/******************************************************************************* + * + * FUNCTION: acpi_set_gpe + * + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block + * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE + * + * RETURN: Status + * + * DESCRIPTION: Enable or disable an individual GPE. This function bypasses + * the reference count mechanism used in the acpi_enable_gpe(), + * acpi_disable_gpe() interfaces. + * This API is typically used by the GPE raw handler mode driver + * to switch between the polling mode and the interrupt mode after + * the driver has enabled the GPE. + * The APIs should be invoked in this order: + * acpi_enable_gpe() <- Ensure the reference count > 0 + * acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode + * acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode + * acpi_disable_gpe() <- Decrease the reference count + * + * Note: If a GPE is shared by 2 silicon components, then both the drivers + * should support GPE polling mode or disabling the GPE for long period + * for one driver may break the other. So use it with care since all + * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. + * + ******************************************************************************/ +acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) +{ + struct acpi_gpe_event_info *gpe_event_info; + acpi_status status; + acpi_cpu_flags flags; + + ACPI_FUNCTION_TRACE(acpi_set_gpe); + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + /* Ensure that we have a valid GPE number */ + + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + /* Perform the action */ + + switch (action) { + case ACPI_GPE_ENABLE: + + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); + break; + + case ACPI_GPE_DISABLE: + + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); + break; + + default: + + status = AE_BAD_PARAMETER; + break; + } + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_set_gpe) /******************************************************************************* * @@ -313,7 +384,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, * known as an "implicit notify". Note: The GPE is assumed to be * level-triggered (for windows compatibility). */ - if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == + if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == ACPI_GPE_DISPATCH_NONE) { /* * This is the first device for implicit notify on this GPE. @@ -327,7 +398,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, * If we already have an implicit notify on this GPE, add * this device to the notify list. */ - if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == + if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == ACPI_GPE_DISPATCH_NOTIFY) { /* Ensure that the device is not already in the list */ @@ -530,6 +601,49 @@ unlock_and_exit: ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) +/******************************************************************************* + * + * FUNCTION: acpi_finish_gpe + * + * PARAMETERS: gpe_device - Namespace node for the GPE Block + * (NULL for FADT defined GPEs) + * gpe_number - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE + * processing. Intended for use by asynchronous host-installed + * GPE handlers. The GPE is only reenabled if the enable_for_run bit + * is set in the GPE info. + * + ******************************************************************************/ +acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number) +{ + struct acpi_gpe_event_info *gpe_event_info; + acpi_status status; + acpi_cpu_flags flags; + + ACPI_FUNCTION_TRACE(acpi_finish_gpe); + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + /* Ensure that we have a valid GPE number */ + + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + status = acpi_ev_finish_gpe(gpe_event_info); + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_finish_gpe) + /****************************************************************************** * * FUNCTION: acpi_disable_all_gpes @@ -604,7 +718,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes) * all GPE blocks. * ******************************************************************************/ - acpi_status acpi_enable_all_wakeup_gpes(void) { acpi_status status; |