lkml.org 
[lkml]   [2014]   [Jul]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 4/9] ACPICA: Events: Introduce acpi_set_gpe()/acpi_finish_gpe() to reduce divergences.
    Date
    This can help to reduce source code differences between Linux and ACPICA
    upstream. Further driver cleanups also require these APIs to eliminate GPE
    storms.
    1. acpi_set_gpe(): An API that driver should invoke in the case it wants
    to disable/enable IRQ without honoring the reference
    count implemented in the acpi_disable_gpe() and
    acpi_enable_gpe(). Note that this API should only be
    invoked inside a acpi_enable_gpe()/acpi_disable_gpe()
    pair.
    2. acpi_finish_gpe(): Drivers returned ACPI_REENABLE_GPE unset from the
    GPE handler should use this API instead of
    invoking acpi_set_gpe()/acpi_enable_gpe() to
    re-enable the GPE.
    The GPE APIs can be invoked inside of a GPE handler or in the task context
    with a driver provided lock held. This driver provided lock is safe to be
    held in the GPE handler by the driver.

    Signed-off-by: Lv Zheng <lv.zheng@intel.com>
    ---
    drivers/acpi/acpica/evxfgpe.c | 105 +++++++++++++++++++++++++++++++++++++++++
    1 file changed, 105 insertions(+)

    diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
    index cb534fa..d66d50b 100644
    --- a/drivers/acpi/acpica/evxfgpe.c
    +++ b/drivers/acpi/acpica/evxfgpe.c
    @@ -176,6 +176,68 @@ 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 and
    + * acpi_disable_gpe interfaces -- and should be used with care.
    + *
    + * Note: Typically used to disable a runtime GPE for short period of time,
    + * then re-enable it, without disturbing the existing reference counts. This
    + * is useful, for example, in the Embedded Controller (EC) driver.
    + *
    + ******************************************************************************/
    +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_ev_enable_gpe(gpe_event_info);
    + 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)

    /*******************************************************************************
    *
    @@ -479,6 +541,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
    --
    1.7.10


    \
     
     \ /
      Last update: 2014-07-15 05:41    [W:4.109 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site