Example #1
0
ACPI_STATUS
AcpiEvAddGpeReference (
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
{
    ACPI_STATUS             Status = AE_OK;


    ACPI_FUNCTION_TRACE (EvAddGpeReference);


    if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
    {
        return_ACPI_STATUS (AE_LIMIT);
    }

    GpeEventInfo->RuntimeCount++;
    if (GpeEventInfo->RuntimeCount == 1)
    {
        /* Enable on first reference */

        Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
        if (ACPI_SUCCESS (Status))
        {
            Status = AcpiEvEnableGpe (GpeEventInfo);
        }

        if (ACPI_FAILURE (Status))
        {
            GpeEventInfo->RuntimeCount--;
        }
    }

    return_ACPI_STATUS (Status);
}
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 = AcpiEvEnableGpe (GpeEventInfo);
        break;

    case ACPI_GPE_DISABLE:

        Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
        break;

    default:

        Status = AE_BAD_PARAMETER;
        break;
    }

UnlockAndExit:
    AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    return_ACPI_STATUS (Status);
}
Example #3
0
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);
}
Example #4
0
ACPI_STATUS
AcpiEnableGpe (
    ACPI_HANDLE             GpeDevice,
    UINT32                  GpeNumber,
    UINT32                  Flags)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;


    ACPI_FUNCTION_TRACE (AcpiEnableGpe);


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

    /* Perform the enable */

    Status = AcpiEvEnableGpe (GpeEventInfo, TRUE);

UnlockAndExit:
    if (Flags & ACPI_NOT_ISR)
    {
        (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    }
    return_ACPI_STATUS (Status);
}
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);
}
Example #6
0
static ACPI_STATUS
AcpiEvSaveMethodInfo (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *ObjDesc,
    void                    **ReturnValue)
{
    ACPI_GPE_BLOCK_INFO     *GpeBlock = (void *) ObjDesc;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    UINT32                  GpeNumber;
    char                    Name[ACPI_NAME_SIZE + 1];
    UINT8                   Type;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (EvSaveMethodInfo);


    /*
     * _Lxx and _Exx GPE method support
     *
     * 1) Extract the name from the object and convert to a string
     */
    ACPI_MOVE_32_TO_32 (
        Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
    Name[ACPI_NAME_SIZE] = 0;

    /*
     * 2) Edge/Level determination is based on the 2nd character
     *    of the method name
     *
     * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
     * if a _PRW object is found that points to this GPE.
     */
    switch (Name[1])
    {
    case 'L':
        Type = ACPI_GPE_LEVEL_TRIGGERED;
        break;

    case 'E':
        Type = ACPI_GPE_EDGE_TRIGGERED;
        break;

    default:
        /* Unknown method type, just ignore it! */

        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
            "Ignoring unknown GPE method type: %s "
            "(name not of form _Lxx or _Exx)",
            Name));
        return_ACPI_STATUS (AE_OK);
    }

    /* Convert the last two characters of the name to the GPE Number */

    GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
    if (GpeNumber == ACPI_UINT32_MAX)
    {
        /* Conversion failed; invalid method, just ignore it */

        ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
            "Could not extract GPE number from name: %s "
            "(name is not of form _Lxx or _Exx)",
            Name));
        return_ACPI_STATUS (AE_OK);
    }

    /* Ensure that we have a valid GPE number for this GPE block */

    if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
        (GpeNumber >= (GpeBlock->BlockBaseNumber +
            (GpeBlock->RegisterCount * 8))))
    {
        /*
         * Not valid for this GPE block, just ignore it. However, it may be
         * valid for a different GPE block, since GPE0 and GPE1 methods both
         * appear under \_GPE.
         */
        return_ACPI_STATUS (AE_OK);
    }

    /*
     * Now we can add this information to the GpeEventInfo block for use
     * during dispatch of this GPE. Default type is RUNTIME, although this may
     * change when the _PRW methods are executed later.
     */
    GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];

    GpeEventInfo->Flags = (UINT8)
        (Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);

    GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle;

    /* Update enable mask, but don't enable the HW GPE as of yet */

    Status = AcpiEvEnableGpe (GpeEventInfo, FALSE);

    ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
        "Registered GPE method %s as GPE number 0x%.2X\n",
        Name, GpeNumber));
    return_ACPI_STATUS (Status);
}