summaryrefslogtreecommitdiff
path: root/source/components/events
diff options
context:
space:
mode:
authorRobert Moore <Robert.Moore@intel.com>2017-09-28 10:24:31 -0700
committerRobert Moore <Robert.Moore@intel.com>2017-09-28 10:24:31 -0700
commitb9dcce0ad8ecb69f1edfc8244db9917554102382 (patch)
tree6af1b13de9255acf7982c6abd845bcbf25dd892b /source/components/events
parent884a0618fcdca932d11aa0eed3ecea21fa24215d (diff)
downloadacpica-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.c238
-rw-r--r--source/components/events/evgpeblk.c9
-rw-r--r--source/components/events/evxface.c14
-rw-r--r--source/components/events/evxfgpe.c35
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