diff options
author | Robert Moore <Robert.Moore@intel.com> | 2017-09-28 10:24:31 -0700 |
---|---|---|
committer | Robert Moore <Robert.Moore@intel.com> | 2017-09-28 10:24:31 -0700 |
commit | b9dcce0ad8ecb69f1edfc8244db9917554102382 (patch) | |
tree | 6af1b13de9255acf7982c6abd845bcbf25dd892b /source/components/events | |
parent | 884a0618fcdca932d11aa0eed3ecea21fa24215d (diff) | |
download | acpica-b9dcce0ad8ecb69f1edfc8244db9917554102382.tar.gz |
Revert "Merge pull request #300 from zetalog/acpica-gpe"
This reverts commit 884a0618fcdca932d11aa0eed3ecea21fa24215d, reversing
changes made to d6756a8e6d72426b26bb80e4baa9bab9fd05b764.
Causes a flood of GPEs in AcpiExec.
Diffstat (limited to 'source/components/events')
-rw-r--r-- | source/components/events/evgpe.c | 238 | ||||
-rw-r--r-- | source/components/events/evgpeblk.c | 9 | ||||
-rw-r--r-- | source/components/events/evxface.c | 14 | ||||
-rw-r--r-- | source/components/events/evxfgpe.c | 35 |
4 files changed, 105 insertions, 191 deletions
diff --git a/source/components/events/evgpe.c b/source/components/events/evgpe.c index a63e94f48..a00dc3786 100644 --- a/source/components/events/evgpe.c +++ b/source/components/events/evgpe.c @@ -226,7 +226,7 @@ AcpiEvUpdateGpeEnableMask ( * * RETURN: Status * - * DESCRIPTION: Enable a GPE. + * DESCRIPTION: Clear a GPE of stale events and enable it. * ******************************************************************************/ @@ -240,6 +240,14 @@ AcpiEvEnableGpe ( 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); @@ -534,12 +542,17 @@ UINT32 AcpiEvGpeDetect ( ACPI_GPE_XRUPT_INFO *GpeXruptList) { + ACPI_STATUS Status; ACPI_GPE_BLOCK_INFO *GpeBlock; ACPI_NAMESPACE_NODE *GpeDevice; ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; ACPI_GPE_EVENT_INFO *GpeEventInfo; UINT32 GpeNumber; + ACPI_GPE_HANDLER_INFO *GpeHandlerInfo; UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; + UINT8 EnabledStatusByte; + UINT64 StatusReg; + UINT64 EnableReg; ACPI_CPU_FLAGS Flags; UINT32 i; UINT32 j; @@ -595,25 +608,105 @@ AcpiEvGpeDetect ( continue; } + /* Read the Status Register */ + + Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + + /* Read the Enable Register */ + + Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, + "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, " + "RunEnable=%02X, WakeEnable=%02X\n", + GpeRegisterInfo->BaseGpeNumber, + GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1), + (UINT32) StatusReg, (UINT32) EnableReg, + GpeRegisterInfo->EnableForRun, + GpeRegisterInfo->EnableForWake)); + + /* Check if there is anything active at all in this register */ + + EnabledStatusByte = (UINT8) (StatusReg & EnableReg); + if (!EnabledStatusByte) + { + /* No active GPEs in this register, move on */ + + continue; + } + /* Now look at the individual GPEs in this byte register */ for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { - /* Detect and dispatch one GPE bit */ + /* Examine one GPE bit */ GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i * ACPI_GPE_REGISTER_WIDTH) + j]; GpeNumber = j + GpeRegisterInfo->BaseGpeNumber; - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - IntStatus |= AcpiEvDetectGpe ( - GpeDevice, GpeEventInfo, GpeNumber); - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + if (EnabledStatusByte & (1 << j)) + { + /* Invoke global event handler if present */ + + AcpiGpeCount++; + if (AcpiGbl_GlobalEventHandler) + { + AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, + GpeDevice, GpeNumber, + AcpiGbl_GlobalEventHandlerContext); + } + + /* Found an active GPE */ + + if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_RAW_HANDLER) + { + /* Dispatch the event to a raw handler */ + + GpeHandlerInfo = GpeEventInfo->Dispatch.Handler; + + /* + * There is no protection around the namespace node + * and the GPE handler to ensure a safe destruction + * because: + * 1. The namespace node is expected to always + * exist after loading a table. + * 2. The GPE handler is expected to be flushed by + * AcpiOsWaitEventsComplete() before the + * destruction. + */ + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + IntStatus |= GpeHandlerInfo->Address ( + GpeDevice, GpeNumber, GpeHandlerInfo->Context); + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + } + else + { + /* + * Dispatch the event to a standard handler or + * method. + */ + IntStatus |= AcpiEvGpeDispatch (GpeDevice, + GpeEventInfo, GpeNumber); + } + } } } GpeBlock = GpeBlock->Next; } +UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); return (IntStatus); } @@ -801,137 +894,6 @@ AcpiEvFinishGpe ( /******************************************************************************* * - * FUNCTION: AcpiEvDetectGpe - * - * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 - * GpeEventInfo - Info for this GPE - * GpeNumber - Number relative to the parent GPE block - * - * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED - * - * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function - * (e.g. EC) or method (e.g. _Lxx/_Exx) handler. - * NOTE: GPE is W1C, so it is possible to handle a single GPE from both - * task and irq context in parallel as long as the process to - * detect and mask the GPE is atomic. - * However the atomicity of ACPI_GPE_DISPATCH_RAW_HANDLER is - * dependent on the raw handler itself. - * - ******************************************************************************/ - -UINT32 -AcpiEvDetectGpe ( - ACPI_NAMESPACE_NODE *GpeDevice, - ACPI_GPE_EVENT_INFO *GpeEventInfo, - UINT32 GpeNumber) -{ - UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; - UINT8 EnabledStatusByte; - UINT64 StatusReg; - UINT64 EnableReg; - UINT32 RegisterBit; - ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; - ACPI_GPE_HANDLER_INFO *GpeHandlerInfo; - ACPI_CPU_FLAGS Flags; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (EvGpeDetect); - - - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - - /* Get the info block for the entire GPE register */ - - GpeRegisterInfo = GpeEventInfo->RegisterInfo; - - /* Get the register bitmask for this GPE */ - - RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); - - /* GPE currently enabled (enable bit == 1)? */ - - Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); - if (ACPI_FAILURE (Status)) - { - goto ErrorExit; - } - - /* GPE currently active (status bit == 1)? */ - - Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); - if (ACPI_FAILURE (Status)) - { - goto ErrorExit; - } - - /* Check if there is anything active at all in this GPE */ - - ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, - "Read registers for GPE %02X: Status=%02X, Enable=%02X, " - "RunEnable=%02X, WakeEnable=%02X\n", - GpeNumber, - (UINT32) (StatusReg & RegisterBit), - (UINT32) (EnableReg & RegisterBit), - GpeRegisterInfo->EnableForRun, - GpeRegisterInfo->EnableForWake)); - - EnabledStatusByte = (UINT8) (StatusReg & EnableReg); - if (!(EnabledStatusByte & RegisterBit)) - { - goto ErrorExit; - } - - /* Invoke global event handler if present */ - - AcpiGpeCount++; - if (AcpiGbl_GlobalEventHandler) - { - AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, - GpeDevice, GpeNumber, - AcpiGbl_GlobalEventHandlerContext); - } - - /* Found an active GPE */ - - if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == - ACPI_GPE_DISPATCH_RAW_HANDLER) - { - /* Dispatch the event to a raw handler */ - - GpeHandlerInfo = GpeEventInfo->Dispatch.Handler; - - /* - * There is no protection around the namespace node - * and the GPE handler to ensure a safe destruction - * because: - * 1. The namespace node is expected to always - * exist after loading a table. - * 2. The GPE handler is expected to be flushed by - * AcpiOsWaitEventsComplete() before the - * destruction. - */ - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - IntStatus |= GpeHandlerInfo->Address ( - GpeDevice, GpeNumber, GpeHandlerInfo->Context); - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - } - else - { - /* Dispatch the event to a standard handler or method. */ - - IntStatus |= AcpiEvGpeDispatch (GpeDevice, - GpeEventInfo, GpeNumber); - } - -ErrorExit: - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - return (IntStatus); -} - - -/******************************************************************************* - * * FUNCTION: AcpiEvGpeDispatch * * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 @@ -943,6 +905,8 @@ ErrorExit: * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) * or method (e.g. _Lxx/_Exx) handler. * + * This function executes at interrupt level. + * ******************************************************************************/ UINT32 diff --git a/source/components/events/evgpeblk.c b/source/components/events/evgpeblk.c index 3b240cfb6..e7495368a 100644 --- a/source/components/events/evgpeblk.c +++ b/source/components/events/evgpeblk.c @@ -591,7 +591,6 @@ AcpiEvInitializeGpeBlock ( ACPI_GPE_EVENT_INFO *GpeEventInfo; UINT32 GpeEnabledCount; UINT32 GpeIndex; - UINT32 GpeNumber; UINT32 i; UINT32 j; @@ -623,13 +622,14 @@ AcpiEvInitializeGpeBlock ( GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j; GpeEventInfo = &GpeBlock->EventInfo[GpeIndex]; - GpeNumber = GpeBlock->BlockBaseNumber + GpeIndex; /* * 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) || + if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_NONE) || + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_HANDLER) || + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_RAW_HANDLER) || (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) { continue; @@ -640,11 +640,10 @@ AcpiEvInitializeGpeBlock ( { ACPI_EXCEPTION ((AE_INFO, Status, "Could not enable GPE 0x%02X", - GpeNumber)); + GpeIndex + GpeBlock->BlockBaseNumber)); continue; } - GpeEventInfo->Flags |= ACPI_GPE_AUTO_ENABLED; GpeEnabledCount++; } } diff --git a/source/components/events/evxface.c b/source/components/events/evxface.c index 968525bf1..fa8d85ce9 100644 --- a/source/components/events/evxface.c +++ b/source/components/events/evxface.c @@ -1257,20 +1257,6 @@ AcpiRemoveGpeHandler ( Handler->OriginallyEnabled) { (void) AcpiEvAddGpeReference (GpeEventInfo); - if (GpeEventInfo->RuntimeCount == 1 && - AcpiGbl_AllGpesInitialized) - { - /* - * Poll GPEs to handle already triggered events. - * It is not sufficient to trigger edge-triggered GPE with - * specific GPE chips, software need to poll once after - * enabling. - */ - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - (void) AcpiEvDetectGpe ( - GpeDevice, GpeEventInfo, GpeNumber); - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - } } AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); diff --git a/source/components/events/evxfgpe.c b/source/components/events/evxfgpe.c index b8e8969d8..61ac74ad0 100644 --- a/source/components/events/evxfgpe.c +++ b/source/components/events/evxfgpe.c @@ -212,16 +212,6 @@ AcpiUpdateAllGpes ( UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - - /* - * Poll GPEs to handle already triggered events. - * It is not sufficient to trigger edge-triggered GPE with specific - * GPE chips, software need to poll once after enabling. - */ - if (AcpiGbl_AllGpesInitialized) - { - AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead); - } return_ACPI_STATUS (Status); } @@ -269,21 +259,6 @@ AcpiEnableGpe ( ACPI_GPE_DISPATCH_NONE) { Status = AcpiEvAddGpeReference (GpeEventInfo); - if (ACPI_SUCCESS (Status) && - GpeEventInfo->RuntimeCount == 1 && - AcpiGbl_AllGpesInitialized) - { - /* - * Poll GPEs to handle already triggered events. - * It is not sufficient to trigger edge-triggered GPE with - * specific GPE chips, software need to poll once after - * enabling. - */ - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - (void) AcpiEvDetectGpe ( - GpeDevice, GpeEventInfo, GpeNumber); - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - } } else { @@ -634,16 +609,6 @@ AcpiSetupGpeForWake ( GpeEventInfo->Flags = (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); } - else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED) - { - /* - * A reference to this GPE has been added during the GPE block - * initialization, so drop it now to prevent the GPE from being - * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag. - */ - (void) AcpiEvRemoveGpeReference (GpeEventInfo); - GpeEventInfo->Flags &= ~~ACPI_GPE_AUTO_ENABLED; - } /* * If we already have an implicit notify on this GPE, add |