summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/evgpe.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/evgpe.c')
-rw-r--r--sys/contrib/dev/acpica/evgpe.c198
1 files changed, 81 insertions, 117 deletions
diff --git a/sys/contrib/dev/acpica/evgpe.c b/sys/contrib/dev/acpica/evgpe.c
index 20a7dc4..e470eae 100644
--- a/sys/contrib/dev/acpica/evgpe.c
+++ b/sys/contrib/dev/acpica/evgpe.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: evgpe - General Purpose Event handling and dispatch
- * $Revision: 1.53 $
+ * $Revision: 1.68 $
*
*****************************************************************************/
@@ -9,7 +9,7 @@
*
* 1. Copyright Notice
*
- * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
* All rights reserved.
*
* 2. License
@@ -149,7 +149,7 @@ AcpiEvSetGpeType (
ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE ("EvSetGpeType");
+ ACPI_FUNCTION_TRACE (EvSetGpeType);
/* Validate type and update register enable masks */
@@ -200,7 +200,7 @@ AcpiEvUpdateGpeEnableMasks (
UINT8 RegisterBit;
- ACPI_FUNCTION_TRACE ("EvUpdateGpeEnableMasks");
+ ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMasks);
GpeRegisterInfo = GpeEventInfo->RegisterInfo;
@@ -208,7 +208,8 @@ AcpiEvUpdateGpeEnableMasks (
{
return_ACPI_STATUS (AE_NOT_EXIST);
}
- RegisterBit = GpeEventInfo->RegisterBit;
+ RegisterBit = (UINT8)
+ (1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
/* 1) Disable case. Simply clear all enable bits */
@@ -268,7 +269,7 @@ AcpiEvEnableGpe (
ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE ("EvEnableGpe");
+ ACPI_FUNCTION_TRACE (EvEnableGpe);
/* Make sure HW enable masks are updated */
@@ -341,7 +342,7 @@ AcpiEvDisableGpe (
ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE ("EvDisableGpe");
+ ACPI_FUNCTION_TRACE (EvDisableGpe);
if (!(GpeEventInfo->Flags & ACPI_GPE_ENABLE_MASK))
@@ -488,12 +489,12 @@ AcpiEvGpeDetect (
UINT8 EnabledStatusByte;
UINT32 StatusReg;
UINT32 EnableReg;
- ACPI_NATIVE_UINT Flags;
+ ACPI_CPU_FLAGS Flags;
ACPI_NATIVE_UINT i;
ACPI_NATIVE_UINT j;
- ACPI_FUNCTION_NAME ("EvGpeDetect");
+ ACPI_FUNCTION_NAME (EvGpeDetect);
/* Check for the case where there are no GPEs */
@@ -502,9 +503,15 @@ AcpiEvGpeDetect (
return (IntStatus);
}
+ /*
+ * We need to obtain the GPE lock for both the data structs and registers
+ * Note: Not necessary to obtain the hardware lock, since the GPE registers
+ * are owned by the GpeLock.
+ */
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
/* Examine all GPE blocks attached to this interrupt level */
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
GpeBlock = GpeXruptList->GpeBlockListHead;
while (GpeBlock)
{
@@ -557,7 +564,7 @@ AcpiEvGpeDetect (
{
/* Examine one GPE bit */
- if (EnabledStatusByte & AcpiGbl_DecodeTo8bit[j])
+ if (EnabledStatusByte & (1 << j))
{
/*
* Found an active GPE. Dispatch the event to a handler
@@ -588,9 +595,9 @@ UnlockAndExit:
*
* RETURN: None
*
- * DESCRIPTION: Perform the actual execution of a GPE control method. This
- * function is called from an invocation of AcpiOsQueueForExecution
- * (and therefore does NOT execute at interrupt level) so that
+ * DESCRIPTION: Perform the actual execution of a GPE control method. This
+ * function is called from an invocation of AcpiOsExecute and
+ * therefore does NOT execute at interrupt level - so that
* the control method itself is not executed in the context of
* an interrupt handler.
*
@@ -601,13 +608,12 @@ AcpiEvAsynchExecuteGpeMethod (
void *Context)
{
ACPI_GPE_EVENT_INFO *GpeEventInfo = (void *) Context;
- UINT32 GpeNumber = 0;
ACPI_STATUS Status;
ACPI_GPE_EVENT_INFO LocalGpeEventInfo;
- ACPI_PARAMETER_INFO Info;
+ ACPI_EVALUATE_INFO *Info;
- ACPI_FUNCTION_TRACE ("EvAsynchExecuteGpeMethod");
+ ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod);
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
@@ -648,22 +654,33 @@ AcpiEvAsynchExecuteGpeMethod (
if ((LocalGpeEventInfo.Flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_METHOD)
{
- /*
- * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
- * control method that corresponds to this GPE
- */
- Info.Node = LocalGpeEventInfo.Dispatch.MethodNode;
- Info.Parameters = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT *, GpeEventInfo);
- Info.ParameterType = ACPI_PARAM_GPE;
+ /* Allocate the evaluation information block */
+
+ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
+ if (!Info)
+ {
+ Status = AE_NO_MEMORY;
+ }
+ else
+ {
+ /*
+ * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
+ * control method that corresponds to this GPE
+ */
+ Info->PrefixNode = LocalGpeEventInfo.Dispatch.MethodNode;
+ Info->Parameters = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT *, GpeEventInfo);
+ Info->ParameterType = ACPI_PARAM_GPE;
+ Info->Flags = ACPI_IGNORE_RETURN_VALUE;
+
+ Status = AcpiNsEvaluate (Info);
+ ACPI_FREE (Info);
+ }
- Status = AcpiNsEvaluateByHandle (&Info);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR ((
- "%s while evaluating method [%4.4s] for GPE[%2X]\n",
- AcpiFormatException (Status),
- AcpiUtGetNodeName (LocalGpeEventInfo.Dispatch.MethodNode),
- GpeNumber));
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "while evaluating GPE method [%4.4s]",
+ AcpiUtGetNodeName (LocalGpeEventInfo.Dispatch.MethodNode)));
}
}
@@ -712,8 +729,10 @@ AcpiEvGpeDispatch (
ACPI_STATUS Status;
- ACPI_FUNCTION_TRACE ("EvGpeDispatch");
+ ACPI_FUNCTION_TRACE (EvGpeDispatch);
+
+ AcpiGpeCount++;
/*
* If edge-triggered, clear the GPE status bit now. Note that
@@ -725,30 +744,30 @@ AcpiEvGpeDispatch (
Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR ((
- "AcpiEvGpeDispatch: %s, Unable to clear GPE[%2X]\n",
- AcpiFormatException (Status), GpeNumber));
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to clear GPE[%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
}
- /* Save current system state */
-
- if (AcpiGbl_SystemAwakeAndRunning)
- {
- ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_SYSTEM_RUNNING);
- }
- else
+ if (!AcpiGbl_SystemAwakeAndRunning)
{
- ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_SYSTEM_RUNNING);
+ /*
+ * We just woke up because of a wake GPE. Disable any further GPEs
+ * until we are fully up and running (Only wake GPEs should be enabled
+ * at this time, but we just brute-force disable them all.)
+ * 1) We must disable this particular wake GPE so it won't fire again
+ * 2) We want to disable all wake GPEs, since we are now awake
+ */
+ (void) AcpiHwDisableAllGpes ();
}
/*
- * 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, we disable the level to
- * prevent further events from coming in here.
+ * 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, we disable this GPE to prevent further such pointless
+ * events from firing.
*/
switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
{
@@ -769,9 +788,8 @@ AcpiEvGpeDispatch (
Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR ((
- "AcpiEvGpeDispatch: %s, Unable to clear GPE[%2X]\n",
- AcpiFormatException (Status), GpeNumber));
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to clear GPE[%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
}
@@ -780,15 +798,14 @@ AcpiEvGpeDispatch (
case ACPI_GPE_DISPATCH_METHOD:
/*
- * Disable GPE, so it doesn't keep firing before the method has a
- * chance to run.
+ * Disable the GPE, so it doesn't keep firing before the method has a
+ * chance to run (it runs asynchronously with interrupts enabled).
*/
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR ((
- "AcpiEvGpeDispatch: %s, Unable to disable GPE[%2X]\n",
- AcpiFormatException (Status), GpeNumber));
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to disable GPE[%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
@@ -796,13 +813,13 @@ AcpiEvGpeDispatch (
* Execute the method associated with the GPE
* NOTE: Level-triggered GPEs are cleared after the method completes.
*/
- Status = AcpiOsQueueForExecution (OSD_PRIORITY_GPE,
+ Status = AcpiOsExecute (OSL_GPE_HANDLER,
AcpiEvAsynchExecuteGpeMethod, GpeEventInfo);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR ((
- "AcpiEvGpeDispatch: %s, Unable to queue handler for GPE[%2X] - event disabled\n",
- AcpiFormatException (Status), GpeNumber));
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to queue handler for GPE[%2X] - event disabled",
+ GpeNumber));
}
break;
@@ -810,20 +827,19 @@ AcpiEvGpeDispatch (
/* No handler or method to run! */
- ACPI_REPORT_ERROR ((
- "AcpiEvGpeDispatch: No handler or method for GPE[%2X], disabling event\n",
+ ACPI_ERROR ((AE_INFO,
+ "No handler or method for GPE[%2X], disabling event",
GpeNumber));
/*
- * Disable the GPE. The GPE will remain disabled until the ACPI
+ * Disable the GPE. The GPE will remain disabled until the ACPI
* Core Subsystem is restarted, or a handler is installed.
*/
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR ((
- "AcpiEvGpeDispatch: %s, Unable to disable GPE[%2X]\n",
- AcpiFormatException (Status), GpeNumber));
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "Unable to disable GPE[%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
break;
@@ -832,55 +848,3 @@ AcpiEvGpeDispatch (
return_UINT32 (ACPI_INTERRUPT_HANDLED);
}
-
-#ifdef ACPI_GPE_NOTIFY_CHECK
-/*******************************************************************************
- * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
- *
- * FUNCTION: AcpiEvCheckForWakeOnlyGpe
- *
- * PARAMETERS: GpeEventInfo - info for this GPE
- *
- * RETURN: Status
- *
- * DESCRIPTION: Determine if a a GPE is "wake-only".
- *
- * Called from Notify() code in interpreter when a "DeviceWake"
- * Notify comes in.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvCheckForWakeOnlyGpe (
- ACPI_GPE_EVENT_INFO *GpeEventInfo)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE ("EvCheckForWakeOnlyGpe");
-
-
- if ((GpeEventInfo) && /* Only >0 for _Lxx/_Exx */
- ((GpeEventInfo->Flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */
- {
- /* This must be a wake-only GPE, disable it */
-
- Status = AcpiEvDisableGpe (GpeEventInfo);
-
- /* Set GPE to wake-only. Do not change wake disabled/enabled status */
-
- AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
-
- ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n",
- GpeEventInfo));
-
- /* This was a wake-only GPE */
-
- return_ACPI_STATUS (AE_WAKE_ONLY_GPE);
- }
-
- return_ACPI_STATUS (AE_OK);
-}
-#endif
-
-
OpenPOWER on IntegriCloud