Example #1
0
ACPI_STATUS
AcpiClearGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiClearGpe);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

    /* Ensure that we have a valid GPE number */

    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    if (!GpeEventInfo)
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit;
    }

    Status = AcpiHwClearGpe (GpeEventInfo);

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
Example #2
0
ACPI_STATUS
AcpiEvFinishGpe (
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
{
    ACPI_STATUS             Status;


    if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
            ACPI_GPE_LEVEL_TRIGGERED)
    {
        /*
         * GPE is level-triggered, we clear the GPE status bit after
         * handling the event.
         */
        Status = AcpiHwClearGpe (GpeEventInfo);
        if (ACPI_FAILURE (Status))
        {
            return (Status);
        }
    }

    /*
     * Enable this GPE, conditionally. This means that the GPE will
     * only be physically enabled if the EnableMask bit is set
     * in the EventInfo.
     */
    (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
    return (AE_OK);
}
Example #3
0
ACPI_STATUS
AcpiEvEnableGpe (
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (EvEnableGpe);


    /*
     * We will only allow a GPE to be enabled if it has either an associated
     * method (_Lxx/_Exx) or a handler, or is using the implicit notify
     * feature. Otherwise, the GPE will be immediately disabled by
     * AcpiEvGpeDispatch the first time it fires.
     */
    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
        ACPI_GPE_DISPATCH_NONE)
    {
        return_ACPI_STATUS (AE_NO_HANDLER);
    }

    /* Clear the GPE (of stale events) */

    Status = AcpiHwClearGpe (GpeEventInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Enable the requested GPE */

    Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
    return_ACPI_STATUS (Status);
}
Example #4
0
ACPI_STATUS
AcpiClearEvent (
    UINT32                  Event,
    UINT32                  Type)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE ("AcpiClearEvent");


    /* The Type must be either Fixed Event or GPE */

    switch (Type)
    {
    case ACPI_EVENT_FIXED:

        /* Decode the Fixed Event */

        if (Event > ACPI_EVENT_MAX)
        {
            return_ACPI_STATUS (AE_BAD_PARAMETER);
        }

        /*
         * Clear the requested fixed event (By writing a one to the
         * status register bit)
         */
        Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].StatusRegisterId,
                1, ACPI_MTX_LOCK);
        break;


    case ACPI_EVENT_GPE:

        /* Ensure that we have a valid GPE number */

        GpeEventInfo = AcpiEvGetGpeEventInfo (Event);
        if (!GpeEventInfo)
        {
            return_ACPI_STATUS (AE_BAD_PARAMETER);
        }

        Status = AcpiHwClearGpe (GpeEventInfo);
        break;


    default:

        Status = AE_BAD_PARAMETER;
    }

    return_ACPI_STATUS (Status);
}
Example #5
0
ACPI_STATUS
AcpiClearGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT32                  Flags)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE (AcpiClearGpe);


    /* Use semaphore lock if not executing at interrupt level */

    if (Flags & ACPI_NOT_ISR)
    {
        Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }
    }

    /* Ensure that we have a valid GPE number */

    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    if (!GpeEventInfo)
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit;
    }

    Status = AcpiHwClearGpe (GpeEventInfo);

UnlockAndExit:
    if (Flags & ACPI_NOT_ISR)
    {
        (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    }
    return_ACPI_STATUS (Status);
}
Example #6
0
ACPI_STATUS
AcpiEvEnableGpe (
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (EvEnableGpe);


    /* Clear the GPE (of stale events) */

    Status = AcpiHwClearGpe (GpeEventInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Enable the requested GPE */

    Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
    return_ACPI_STATUS (Status);
}
Example #7
0
UINT32
AcpiEvGpeDispatch (
    ACPI_NAMESPACE_NODE     *GpeDevice,
    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status;
    UINT32                  ReturnValue;


    ACPI_FUNCTION_TRACE (EvGpeDispatch);


    /*
     * Always disable the GPE so that it does not keep firing before
     * any asynchronous activity completes (either from the execution
     * of a GPE method or an asynchronous GPE handler.)
     *
     * If there is no handler or method to run, just disable the
     * GPE and leave it disabled permanently to prevent further such
     * pointless events from firing.
     */
    Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status,
            "Unable to disable GPE %02X", GpeNumber));
        return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
    }

    /*
     * If edge-triggered, clear the GPE status bit now. Note that
     * level-triggered events are cleared after the GPE is serviced.
     */
    if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
            ACPI_GPE_EDGE_TRIGGERED)
    {
        Status = AcpiHwClearGpe (GpeEventInfo);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "Unable to clear GPE %02X", GpeNumber));
            (void) AcpiHwLowSetGpe (
                GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
            return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
        }
    }

    /*
     * Dispatch the GPE to either an installed handler or the control
     * method associated with this GPE (_Lxx or _Exx). If a handler
     * exists, we invoke it and do not attempt to run the method.
     * If there is neither a handler nor a method, leave the GPE
     * disabled.
     */
    switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags))
    {
    case ACPI_GPE_DISPATCH_HANDLER:

        /* Invoke the installed handler (at interrupt level) */

        ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
            GpeDevice, GpeNumber,
            GpeEventInfo->Dispatch.Handler->Context);

        /* If requested, clear (if level-triggered) and reenable the GPE */

        if (ReturnValue & ACPI_REENABLE_GPE)
        {
            (void) AcpiEvFinishGpe (GpeEventInfo);
        }
        break;

    case ACPI_GPE_DISPATCH_METHOD:
    case ACPI_GPE_DISPATCH_NOTIFY:
        /*
         * Execute the method associated with the GPE
         * NOTE: Level-triggered GPEs are cleared after the method completes.
         */
        Status = AcpiOsExecute (OSL_GPE_HANDLER,
            AcpiEvAsynchExecuteGpeMethod, GpeEventInfo);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "Unable to queue handler for GPE %02X - event disabled",
                GpeNumber));
        }
        break;

    default:
        /*
         * No handler or method to run!
         * 03/2010: This case should no longer be possible. We will not allow
         * a GPE to be enabled if it has no handler or method.
         */
        ACPI_ERROR ((AE_INFO,
            "No handler or method for GPE %02X, disabling event",
            GpeNumber));
        break;
    }

    return_UINT32 (ACPI_INTERRUPT_HANDLED);
}
Example #8
0
ACPI_STATUS
AcpiClearEvent (
    UINT32                  Event,
    UINT32                  Type)
{
    ACPI_STATUS             Status = AE_OK;
    UINT32                  RegisterId;


    FUNCTION_TRACE ("AcpiClearEvent");


    /* Ensure that ACPI has been initialized */

    ACPI_IS_INITIALIZATION_COMPLETE (Status);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* The Type must be either Fixed AcpiEvent or GPE */

    switch (Type)
    {

    case ACPI_EVENT_FIXED:

        /* Decode the Fixed AcpiEvent */

        switch (Event)
        {
        case ACPI_EVENT_PMTIMER:
            RegisterId = TMR_STS;
            break;

        case ACPI_EVENT_GLOBAL:
            RegisterId = GBL_STS;
            break;

        case ACPI_EVENT_POWER_BUTTON:
            RegisterId = PWRBTN_STS;
            break;

        case ACPI_EVENT_SLEEP_BUTTON:
            RegisterId = SLPBTN_STS;
            break;

        case ACPI_EVENT_RTC:
            RegisterId = RTC_STS;
            break;

        default:
            return_ACPI_STATUS (AE_BAD_PARAMETER);
            break;
        }

        /*
         * Clear the requested fixed event (By writing a one to the
         * status register bit)
         */
        AcpiHwRegisterBitAccess (ACPI_WRITE, ACPI_MTX_LOCK, RegisterId, 1);
        break;


    case ACPI_EVENT_GPE:

        /* Ensure that we have a valid GPE number */

        if ((Event > ACPI_GPE_MAX) ||
            (AcpiGbl_GpeValid[Event] == ACPI_GPE_INVALID))
        {
            return_ACPI_STATUS (AE_BAD_PARAMETER);
        }


        AcpiHwClearGpe (Event);
        break;


    default:

        Status = AE_BAD_PARAMETER;
    }

    return_ACPI_STATUS (Status);
}