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