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); }
ACPI_STATUS AcpiEvInitializeGpeBlock ( ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, void *Context) { ACPI_STATUS Status; ACPI_GPE_EVENT_INFO *GpeEventInfo; UINT32 GpeEnabledCount; UINT32 GpeIndex; UINT32 i; UINT32 j; BOOLEAN *IsPollingNeeded = Context; ACPI_ERROR_ONLY (UINT32 GpeNumber); ACPI_FUNCTION_TRACE (EvInitializeGpeBlock); /* * Ignore a null GPE block (e.g., if no GPE block 1 exists), and * any GPE blocks that have been initialized already. */ if (!GpeBlock || GpeBlock->Initialized) { return_ACPI_STATUS (AE_OK); } /* * Enable all GPEs that have a corresponding method and have the * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block * must be enabled via the acpi_enable_gpe() interface. */ GpeEnabledCount = 0; for (i = 0; i < GpeBlock->RegisterCount; i++) { for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { /* Get the info block for this particular GPE */ GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j; GpeEventInfo = &GpeBlock->EventInfo[GpeIndex]; ACPI_ERROR_ONLY(GpeNumber = GpeBlock->BlockBaseNumber + GpeIndex); GpeEventInfo->Flags |= ACPI_GPE_INITIALIZED; /* * Ignore GPEs that have no corresponding _Lxx/_Exx method * and GPEs that are used to wake the system */ if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != ACPI_GPE_DISPATCH_METHOD) || (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) { continue; } Status = AcpiEvAddGpeReference (GpeEventInfo); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not enable GPE 0x%02X", GpeNumber)); continue; } GpeEventInfo->Flags |= ACPI_GPE_AUTO_ENABLED; if (IsPollingNeeded && ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo)) { *IsPollingNeeded = TRUE; } GpeEnabledCount++; } } if (GpeEnabledCount) { ACPI_INFO (( "Enabled %u GPEs in block %02X to %02X", GpeEnabledCount, (UINT32) GpeBlock->BlockBaseNumber, (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)))); } GpeBlock->Initialized = TRUE; return_ACPI_STATUS (AE_OK); }