예제 #1
0
파일: evxfgpe.c 프로젝트: matter123/mossy
ACPI_STATUS
AcpiDisableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status = AE_BAD_PARAMETER;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiDisableGpe);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    if (GpeEventInfo)
    {
        Status = AcpiEvRemoveGpeReference (GpeEventInfo);
    }

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #2
0
파일: evxfgpe.c 프로젝트: matter123/mossy
ACPI_STATUS
AcpiFinishGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_STATUS             Status;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiFinishGpe);


    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 = AcpiEvFinishGpe (GpeEventInfo);

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #3
0
파일: evxfgpe.c 프로젝트: matter123/mossy
ACPI_STATUS
AcpiMarkGpeForWake (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_STATUS             Status = AE_BAD_PARAMETER;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    if (GpeEventInfo)
    {
        /* Mark the GPE as a possible wake event */

        GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
        Status = AE_OK;
    }

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #4
0
파일: dbcmds.c 프로젝트: zenny/DragonFlyBSD
void
AcpiDbGenerateGpe (
    char                    *GpeArg,
    char                    *BlockArg)
{
    UINT32                  BlockNumber = 0;
    UINT32                  GpeNumber;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0);

    /*
     * If no block arg, or block arg == 0 or 1, use the FADT-defined
     * GPE blocks.
     */
    if (BlockArg)
    {
        BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);
        if (BlockNumber == 1)
        {
            BlockNumber = 0;
        }
    }

    GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
        GpeNumber);
    if (!GpeEventInfo)
    {
        AcpiOsPrintf ("Invalid GPE\n");
        return;
    }

    (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
}
예제 #5
0
파일: evxfevnt.c 프로젝트: mmanley/Antares
ACPI_STATUS
AcpiSetGpeType (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT8                   Type)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE (AcpiSetGpeType);


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

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

    if ((GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) == Type)
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Set the new type (will disable GPE if currently enabled) */

    Status = AcpiEvSetGpeType (GpeEventInfo, Type);

UnlockAndExit:
    return_ACPI_STATUS (Status);
}
예제 #6
0
파일: evxfgpe.c 프로젝트: matter123/mossy
ACPI_STATUS
AcpiGetGpeStatus (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    ACPI_EVENT_STATUS       *EventStatus)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    /* Obtain status on the requested GPE number */

    Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #7
0
파일: evxfevnt.c 프로젝트: CoryXie/CellOS
ACPI_STATUS
AcpiGpeWakeup (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT8                   Action)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
    ACPI_CPU_FLAGS          Flags;
    UINT32                  RegisterBit;


    ACPI_FUNCTION_TRACE (AcpiGpeWakeup);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    GpeRegisterInfo = GpeEventInfo->RegisterInfo;
    if (!GpeRegisterInfo)
    {
        Status = AE_NOT_EXIST;
        goto UnlockAndExit;
    }

    RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);

    /* Perform the action */

    switch (Action)
    {
    case ACPI_GPE_ENABLE:
        ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
        break;

    case ACPI_GPE_DISABLE:
        ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
        break;

    default:
        ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
        Status = AE_BAD_PARAMETER;
        break;
    }

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #8
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);
}
예제 #9
0
파일: evxfgpe.c 프로젝트: 9elements/fwts
ACPI_STATUS
AcpiSetGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT8                   Action)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_STATUS             Status;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiSetGpe);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    /* Perform the action */

    switch (Action)
    {
    case ACPI_GPE_ENABLE:

        Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
        GpeEventInfo->DisableForDispatch = FALSE;
        break;

    case ACPI_GPE_DISABLE:

        Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
        GpeEventInfo->DisableForDispatch = TRUE;
        break;

    default:

        Status = AE_BAD_PARAMETER;
        break;
    }

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #10
0
파일: evxfevnt.c 프로젝트: CoryXie/CellOS
ACPI_STATUS
AcpiDisableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiDisableGpe);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    /* Hardware-disable a runtime GPE on removal of the last reference */

    if (!GpeEventInfo->RuntimeCount)
    {
        Status = AE_LIMIT; /* There are no references to remove */
        goto UnlockAndExit;
    }

    GpeEventInfo->RuntimeCount--;
    if (!GpeEventInfo->RuntimeCount)
    {
        Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
        if (ACPI_SUCCESS (Status))
        {
            Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
        }
        if (ACPI_FAILURE (Status))
        {
            GpeEventInfo->RuntimeCount++;
        }
    }

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #11
0
파일: evxfevnt.c 프로젝트: CoryXie/CellOS
ACPI_STATUS
AcpiEnableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiEnableGpe);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
    {
        Status = AE_LIMIT; /* Too many references */
        goto UnlockAndExit;
    }

    GpeEventInfo->RuntimeCount++;
    if (GpeEventInfo->RuntimeCount == 1)
    {
        Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
        if (ACPI_SUCCESS (Status))
        {
            Status = AcpiEvEnableGpe (GpeEventInfo);
        }
        if (ACPI_FAILURE (Status))
        {
            GpeEventInfo->RuntimeCount--;
        }
    }

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #12
0
파일: evxfgpe.c 프로젝트: 9elements/fwts
ACPI_STATUS
AcpiEnableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status = AE_BAD_PARAMETER;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiEnableGpe);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

    /*
     * Ensure that we have a valid GPE number and that there is some way
     * of handling the GPE (handler or a GPE method). In other words, we
     * won't allow a valid GPE to be enabled if there is no way to handle it.
     */
    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    if (GpeEventInfo)
    {
        if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
            ACPI_GPE_DISPATCH_NONE)
        {
            Status = AcpiEvAddGpeReference (GpeEventInfo);
            if (ACPI_SUCCESS (Status) &&
                ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
            {
                /* Poll edge-triggered GPEs to handle existing events */

                AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
                (void) AcpiEvDetectGpe (
                    GpeDevice, GpeEventInfo, GpeNumber);
                Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
            }
        }
        else
        {
            Status = AE_NO_HANDLER;
        }
    }

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #13
0
파일: evxfevnt.c 프로젝트: mmanley/Antares
ACPI_STATUS
AcpiGetGpeStatus (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT32                  Flags,
    ACPI_EVENT_STATUS       *EventStatus)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);


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

    /* Obtain status on the requested GPE number */

    Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);

UnlockAndExit:
    if (Flags & ACPI_NOT_ISR)
    {
        (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    }
    return_ACPI_STATUS (Status);
}
예제 #14
0
ACPI_STATUS
AcpiEnableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status = AE_BAD_PARAMETER;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiEnableGpe);


    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

    /*
     * Ensure that we have a valid GPE number and that there is some way
     * of handling the GPE (handler or a GPE method). In other words, we
     * won't allow a valid GPE to be enabled if there is no way to handle it.
     */
    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    if (GpeEventInfo)
    {
        if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) !=
            ACPI_GPE_DISPATCH_NONE)
        {
            Status = AcpiEvAddGpeReference (GpeEventInfo);
        }
        else
        {
            Status = AE_NO_HANDLER;
        }
    }

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #15
0
void
AcpiDbGenerateGpe (
    char                    *GpeArg,
    char                    *BlockArg)
{
    UINT32                  BlockNumber;
    UINT32                  GpeNumber;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    GpeNumber   = ACPI_STRTOUL (GpeArg, NULL, 0);
    BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0);


    GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber),
        GpeNumber);
    if (!GpeEventInfo)
    {
        AcpiOsPrintf ("Invalid GPE\n");
        return;
    }

    (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
}
예제 #16
0
ACPI_STATUS
AcpiEnableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT8                   GpeType)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiEnableGpe);


    /* Parameter validation */

    if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    if (GpeType & ACPI_GPE_TYPE_RUNTIME)
    {
        if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
        {
            Status = AE_LIMIT; /* Too many references */
            goto UnlockAndExit;
        }

        GpeEventInfo->RuntimeCount++;
        if (GpeEventInfo->RuntimeCount == 1)
        {
            Status = AcpiEvEnableGpe (GpeEventInfo);
            if (ACPI_FAILURE (Status))
            {
                GpeEventInfo->RuntimeCount--;
                goto UnlockAndExit;
            }
        }
    }

    if (GpeType & ACPI_GPE_TYPE_WAKE)
    {
        /* The GPE must have the ability to wake the system */

        if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
        {
            Status = AE_TYPE;
            goto UnlockAndExit;
        }

        if (GpeEventInfo->WakeupCount == ACPI_UINT8_MAX)
        {
            Status = AE_LIMIT; /* Too many references */
            goto UnlockAndExit;
        }

        /*
         * Update the enable mask on the first wakeup reference. Wake GPEs
         * are only hardware-enabled just before sleeping.
         */
        GpeEventInfo->WakeupCount++;
        if (GpeEventInfo->WakeupCount == 1)
        {
            (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
        }
    }

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #17
0
static ACPI_STATUS
AcpiEvInstallGpeHandler (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT32                  Type,
    BOOLEAN                 IsRawHandler,
    ACPI_GPE_HANDLER        Address,
    void                    *Context)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_GPE_HANDLER_INFO   *Handler;
    ACPI_STATUS             Status;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (EvInstallGpeHandler);


    /* Parameter validation */

    if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

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

    /* Allocate and init handler object (before lock) */

    Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
    if (!Handler)
    {
        Status = AE_NO_MEMORY;
        goto UnlockAndExit;
    }

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    /* Make sure that there isn't a handler there already */

    if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
            ACPI_GPE_DISPATCH_HANDLER) ||
        (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
            ACPI_GPE_DISPATCH_RAW_HANDLER))
    {
        Status = AE_ALREADY_EXISTS;
        goto FreeAndExit;
    }

    Handler->Address = Address;
    Handler->Context = Context;
    Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
    Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
        (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));

    /*
     * If the GPE is associated with a method, it may have been enabled
     * automatically during initialization, in which case it has to be
     * disabled now to avoid spurious execution of the handler.
     */
    if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
            ACPI_GPE_DISPATCH_METHOD) ||
         (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
            ACPI_GPE_DISPATCH_NOTIFY)) &&
        GpeEventInfo->RuntimeCount)
    {
        Handler->OriginallyEnabled = TRUE;
        (void) AcpiEvRemoveGpeReference (GpeEventInfo);

        /* Sanity check of original type against new type */

        if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
        {
            ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
        }
    }

    /* Install the handler */

    GpeEventInfo->Dispatch.Handler = Handler;

    /* Setup up dispatch flags to indicate handler (vs. method/notify) */

    GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
    GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ?
        ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER));

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);


UnlockAndExit:
    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    return_ACPI_STATUS (Status);

FreeAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    ACPI_FREE (Handler);
    goto UnlockAndExit;
}
예제 #18
0
ACPI_STATUS
AcpiRemoveGpeHandler (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    ACPI_GPE_HANDLER        Address)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_GPE_HANDLER_INFO   *Handler;
    ACPI_STATUS             Status;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);


    /* Parameter validation */

    if (!Address)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

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

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    /* Make sure that a handler is indeed installed */

    if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
            ACPI_GPE_DISPATCH_HANDLER) &&
        (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
            ACPI_GPE_DISPATCH_RAW_HANDLER))
    {
        Status = AE_NOT_EXIST;
        goto UnlockAndExit;
    }

    /* Make sure that the installed handler is the same */

    if (GpeEventInfo->Dispatch.Handler->Address != Address)
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit;
    }

    /* Remove the handler */

    Handler = GpeEventInfo->Dispatch.Handler;
    GpeEventInfo->Dispatch.Handler = NULL;

    /* Restore Method node (if any), set dispatch flags */

    GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
    GpeEventInfo->Flags &=
        ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
    GpeEventInfo->Flags |= Handler->OriginalFlags;

    /*
     * If the GPE was previously associated with a method and it was
     * enabled, it should be enabled at this point to restore the
     * post-initialization configuration.
     */
    if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
            ACPI_GPE_DISPATCH_METHOD) ||
         (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
            ACPI_GPE_DISPATCH_NOTIFY)) &&
        Handler->OriginallyEnabled)
    {
        (void) AcpiEvAddGpeReference (GpeEventInfo);
    }

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);

    /* Make sure all deferred GPE tasks are completed */

    AcpiOsWaitEventsComplete ();

    /* Now we can free the handler object */

    ACPI_FREE (Handler);
    return_ACPI_STATUS (Status);

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    return_ACPI_STATUS (Status);
}
예제 #19
0
ACPI_STATUS
AcpiRemoveGpeHandler (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    ACPI_EVENT_HANDLER      Address)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_HANDLER_INFO       *Handler;
    ACPI_STATUS             Status;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);


    /* Parameter validation */

    if (!Address)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    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;
    }

    /* Make sure that a handler is indeed installed */

    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER)
    {
        Status = AE_NOT_EXIST;
        goto UnlockAndExit;
    }

    /* Make sure that the installed handler is the same */

    if (GpeEventInfo->Dispatch.Handler->Address != Address)
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit;
    }

    /* Disable the GPE before removing the handler */

    Status = AcpiEvDisableGpe (GpeEventInfo);
    if (ACPI_FAILURE (Status))
    {
        goto UnlockAndExit;
    }

    /* Remove the handler */

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    Handler = GpeEventInfo->Dispatch.Handler;

    /* Restore Method node (if any), set dispatch flags */

    GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
    GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;  /* Clear bits */
    if (Handler->MethodNode)
    {
        GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD;
    }
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);

    /* Now we can free the handler object */

    ACPI_FREE (Handler);


UnlockAndExit:
    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    return_ACPI_STATUS (Status);
}
예제 #20
0
ACPI_STATUS
AcpiInstallGpeHandler (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT32                  Type,
    ACPI_EVENT_HANDLER      Address,
    void                    *Context)
{
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_HANDLER_INFO       *Handler;
    ACPI_STATUS             Status;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);


    /* Parameter validation */

    if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    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;
    }

    /* Make sure that there isn't a handler there already */

    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER)
    {
        Status = AE_ALREADY_EXISTS;
        goto UnlockAndExit;
    }

    /* Allocate and init handler object */

    Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_HANDLER_INFO));
    if (!Handler)
    {
        Status = AE_NO_MEMORY;
        goto UnlockAndExit;
    }

    Handler->Address    = Address;
    Handler->Context    = Context;
    Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;

    /* Disable the GPE before installing the handler */

    Status = AcpiEvDisableGpe (GpeEventInfo);
    if (ACPI_FAILURE (Status))
    {
        goto UnlockAndExit;
    }

    /* Install the handler */

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    GpeEventInfo->Dispatch.Handler = Handler;

    /* Setup up dispatch flags to indicate handler (vs. method) */

    GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);  /* Clear bits */
    GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);


UnlockAndExit:
    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    return_ACPI_STATUS (Status);
}
예제 #21
0
파일: evgpeinit.c 프로젝트: 0xffea/MINIX3
ACPI_STATUS
AcpiEvMatchPrwAndGpe (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_GPE_WALK_INFO      *WalkInfo = ACPI_CAST_PTR (ACPI_GPE_WALK_INFO, Context);
    ACPI_NAMESPACE_NODE     *GpeDevice;
    ACPI_GPE_BLOCK_INFO     *GpeBlock;
    ACPI_NAMESPACE_NODE     *TargetGpeDevice;
    ACPI_NAMESPACE_NODE     *PrwNode;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_OPERAND_OBJECT     *PkgDesc;
    ACPI_OPERAND_OBJECT     *ObjDesc;
    UINT32                  GpeNumber;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (EvMatchPrwAndGpe);


    /* Check for a _PRW method under this device */

    Status = AcpiNsGetNode (ObjHandle, METHOD_NAME__PRW,
                ACPI_NS_NO_UPSEARCH, &PrwNode);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Check if requested OwnerId matches this OwnerId */

    if ((WalkInfo->ExecuteByOwnerId) &&
        (PrwNode->OwnerId != WalkInfo->OwnerId))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Execute the _PRW */

    Status = AcpiUtEvaluateObject (PrwNode, NULL,
                ACPI_BTYPE_PACKAGE, &PkgDesc);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* The returned _PRW package must have at least two elements */

    if (PkgDesc->Package.Count < 2)
    {
        goto Cleanup;
    }

    /* Extract pointers from the input context */

    GpeDevice = WalkInfo->GpeDevice;
    GpeBlock = WalkInfo->GpeBlock;

    /*
     * The _PRW object must return a package, we are only interested
     * in the first element
     */
    ObjDesc = PkgDesc->Package.Elements[0];

    if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
    {
        /* Use FADT-defined GPE device (from definition of _PRW) */

        TargetGpeDevice = NULL;
        if (GpeDevice)
        {
            TargetGpeDevice = AcpiGbl_FadtGpeDevice;
        }

        /* Integer is the GPE number in the FADT described GPE blocks */

        GpeNumber = (UINT32) ObjDesc->Integer.Value;
    }
    else if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
    {
        /* Package contains a GPE reference and GPE number within a GPE block */

        if ((ObjDesc->Package.Count < 2) ||
            ((ObjDesc->Package.Elements[0])->Common.Type !=
                ACPI_TYPE_LOCAL_REFERENCE) ||
            ((ObjDesc->Package.Elements[1])->Common.Type !=
                ACPI_TYPE_INTEGER))
        {
            goto Cleanup;
        }

        /* Get GPE block reference and decode */

        TargetGpeDevice = ObjDesc->Package.Elements[0]->Reference.Node;
        GpeNumber = (UINT32) ObjDesc->Package.Elements[1]->Integer.Value;
    }
    else
    {
        /* Unknown type, just ignore it */

        goto Cleanup;
    }

    /* Get the GpeEventInfo for this GPE */

    if (GpeDevice)
    {
        /*
         * Is this GPE within this block?
         *
         * TRUE if and only if these conditions are true:
         *     1) The GPE devices match.
         *     2) The GPE index(number) is within the range of the Gpe Block
         *          associated with the GPE device.
         */
        if (GpeDevice != TargetGpeDevice)
        {
            goto Cleanup;
        }

        GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
    }
    else
    {
        /* GpeDevice is NULL, just match the TargetDevice and GpeNumber */

        GpeEventInfo = AcpiEvGetGpeEventInfo (TargetGpeDevice, GpeNumber);
    }

    if (GpeEventInfo)
    {
        if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
        {
            /* This GPE can wake the system */

            GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
            WalkInfo->Count++;
        }
    }

Cleanup:
    AcpiUtRemoveReference (PkgDesc);
    return_ACPI_STATUS (AE_OK);
}
예제 #22
0
ACPI_STATUS
AcpiDisableEvent (
    UINT32                  Event,
    UINT32                  Type,
    UINT32                  Flags)
{
    ACPI_STATUS             Status = AE_OK;
    UINT32                  Value;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE ("AcpiDisableEvent");


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

        /*
         * Disable the requested fixed event (by writing a zero to the
         * enable register bit)
         */
        Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
                    0, ACPI_MTX_LOCK);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
                    &Value, ACPI_MTX_LOCK);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        if (Value != 0)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                "Could not disable %s events\n", AcpiUtGetEventName (Event)));
            return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
        }
        break;


    case ACPI_EVENT_GPE:

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

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

        /*
         * Only disable the requested GPE number for wake if specified.
         * Otherwise, turn it totally off
         */

        if (Flags & ACPI_EVENT_WAKE_DISABLE)
        {
            AcpiHwDisableGpeForWakeup (GpeEventInfo);
        }
        else
        {
            Status = AcpiHwDisableGpe (GpeEventInfo);
        }
        break;


    default:
        Status = AE_BAD_PARAMETER;
    }

    return_ACPI_STATUS (Status);
}
예제 #23
0
ACPI_STATUS
AcpiGetEventStatus (
    UINT32                  Event,
    UINT32                  Type,
    ACPI_EVENT_STATUS       *EventStatus)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE ("AcpiGetEventStatus");


    if (!EventStatus)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }


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

        /* Get the status of the requested fixed event */

        Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].StatusRegisterId,
                        EventStatus, 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);
        }

        /* Obtain status on the requested GPE number */

        Status = AcpiHwGetGpeStatus (Event, EventStatus);
        break;


    default:
        Status = AE_BAD_PARAMETER;
    }

    return_ACPI_STATUS (Status);
}
예제 #24
0
파일: evxfgpe.c 프로젝트: matter123/mossy
ACPI_STATUS
AcpiSetupGpeForWake (
    ACPI_HANDLE             WakeDevice,
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_NAMESPACE_NODE     *DeviceNode;
    ACPI_GPE_NOTIFY_INFO    *Notify;
    ACPI_GPE_NOTIFY_INFO    *NewNotify;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);


    /* Parameter Validation */

    if (!WakeDevice)
    {
        /*
         * By forcing WakeDevice to be valid, we automatically enable the
         * implicit notify feature on all hosts.
         */
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Handle root object case */

    if (WakeDevice == ACPI_ROOT_OBJECT)
    {
        DeviceNode = AcpiGbl_RootNode;
    }
    else
    {
        DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
    }

    /* Validate WakeDevice is of type Device */

    if (DeviceNode->Type != ACPI_TYPE_DEVICE)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /*
     * Allocate a new notify object up front, in case it is needed.
     * Memory allocation while holding a spinlock is a big no-no
     * on some hosts.
     */
    NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
    if (!NewNotify)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    /*
     * If there is no method or handler for this GPE, then the
     * WakeDevice will be notified whenever this GPE fires. This is
     * known as an "implicit notify". Note: The GPE is assumed to be
     * level-triggered (for windows compatibility).
     */
    if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
        ACPI_GPE_DISPATCH_NONE)
    {
        /*
         * This is the first device for implicit notify on this GPE.
         * Just set the flags here, and enter the NOTIFY block below.
         */
        GpeEventInfo->Flags =
            (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
    }

    /*
     * If we already have an implicit notify on this GPE, add
     * this device to the notify list.
     */
    if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
        ACPI_GPE_DISPATCH_NOTIFY)
    {
        /* Ensure that the device is not already in the list */

        Notify = GpeEventInfo->Dispatch.NotifyList;
        while (Notify)
        {
            if (Notify->DeviceNode == DeviceNode)
            {
                Status = AE_ALREADY_EXISTS;
                goto UnlockAndExit;
            }
            Notify = Notify->Next;
        }

        /* Add this device to the notify list for this GPE */

        NewNotify->DeviceNode = DeviceNode;
        NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
        GpeEventInfo->Dispatch.NotifyList = NewNotify;
        NewNotify = NULL;
    }

    /* Mark the GPE as a possible wake event */

    GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
    Status = AE_OK;


UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);

    /* Delete the notify object if it was not used above */

    if (NewNotify)
    {
        ACPI_FREE (NewNotify);
    }
    return_ACPI_STATUS (Status);
}
예제 #25
0
ACPI_STATUS
AcpiDisableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT8                   GpeType)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiDisableGpe);


    /* Parameter validation */

    if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

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

    /* Hardware-disable a runtime GPE on removal of the last reference */

    if (GpeType & ACPI_GPE_TYPE_RUNTIME)
    {
        if (!GpeEventInfo->RuntimeCount)
        {
            Status = AE_LIMIT; /* There are no references to remove */
            goto UnlockAndExit;
        }

        GpeEventInfo->RuntimeCount--;
        if (!GpeEventInfo->RuntimeCount)
        {
            Status = AcpiEvDisableGpe (GpeEventInfo);
            if (ACPI_FAILURE (Status))
            {
                GpeEventInfo->RuntimeCount++;
                goto UnlockAndExit;
            }
        }
    }

    /*
     * Update masks for wake GPE on removal of the last reference.
     * No need to hardware-disable wake GPEs here, they are not currently
     * enabled.
     */
    if (GpeType & ACPI_GPE_TYPE_WAKE)
    {
        if (!GpeEventInfo->WakeupCount)
        {
            Status = AE_LIMIT; /* There are no references to remove */
            goto UnlockAndExit;
        }

        GpeEventInfo->WakeupCount--;
        if (!GpeEventInfo->WakeupCount)
        {
            (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
        }
    }


UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #26
0
ACPI_STATUS
AcpiSetupGpeForWake (
    ACPI_HANDLE             WakeDevice,
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber)
{
    ACPI_STATUS             Status = AE_BAD_PARAMETER;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_NAMESPACE_NODE     *DeviceNode;
    ACPI_CPU_FLAGS          Flags;


    ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);


    /* Parameter Validation */

    if (!WakeDevice)
    {
        /*
         * By forcing WakeDevice to be valid, we automatically enable the
         * implicit notify feature on all hosts.
         */
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Validate WakeDevice is of type Device */

    DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
    if (DeviceNode->Type != ACPI_TYPE_DEVICE)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);

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

    GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    if (GpeEventInfo)
    {
        /*
         * If there is no method or handler for this GPE, then the
         * WakeDevice will be notified whenever this GPE fires (aka
         * "implicit notify") Note: The GPE is assumed to be
         * level-triggered (for windows compatibility).
         */
        if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
                ACPI_GPE_DISPATCH_NONE)
        {
            GpeEventInfo->Flags =
                (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
            GpeEventInfo->Dispatch.DeviceNode = DeviceNode;
        }

        GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
        Status = AE_OK;
    }

    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
예제 #27
0
ACPI_STATUS
AcpiEnableEvent (
    UINT32                  Event,
    UINT32                  Type,
    UINT32                  Flags)
{
    ACPI_STATUS             Status = AE_OK;
    UINT32                  Value;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE ("AcpiEnableEvent");


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

        /*
         * Enable the requested fixed event (by writing a one to the
         * enable register bit)
         */
        Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
                    1, ACPI_MTX_LOCK);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        /* Make sure that the hardware responded */

        Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId,
                        &Value, ACPI_MTX_LOCK);
        if (ACPI_FAILURE (Status))
        {
            return_ACPI_STATUS (Status);
        }

        if (Value != 1)
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                "Could not enable %s event\n", AcpiUtGetEventName (Event)));
            return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
        }
        break;


    case ACPI_EVENT_GPE:

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

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

        /* Enable the requested GPE number */

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

        if (Flags & ACPI_EVENT_WAKE_ENABLE)
        {
            AcpiHwEnableGpeForWakeup (GpeEventInfo);
        }
        break;


    default:

        Status = AE_BAD_PARAMETER;
    }

    return_ACPI_STATUS (Status);
}