summaryrefslogtreecommitdiffstats
path: root/events/evgpeinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'events/evgpeinit.c')
-rw-r--r--events/evgpeinit.c285
1 files changed, 27 insertions, 258 deletions
diff --git a/events/evgpeinit.c b/events/evgpeinit.c
index be38f0c..b46b91a 100644
--- a/events/evgpeinit.c
+++ b/events/evgpeinit.c
@@ -118,12 +118,28 @@
#include "accommon.h"
#include "acevents.h"
#include "acnamesp.h"
-#include "acinterp.h"
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evgpeinit")
+/*
+ * Note: History of _PRW support in ACPICA
+ *
+ * Originally (2000 - 2010), the GPE initialization code performed a walk of
+ * the entire namespace to execute the _PRW methods and detect all GPEs
+ * capable of waking the system.
+ *
+ * As of 10/2010, the _PRW method execution has been removed since it is
+ * actually unnecessary. The host OS must in fact execute all _PRW methods
+ * in order to identify the device/power-resource dependencies. We now put
+ * the onus on the host OS to identify the wake GPEs as part of this process
+ * and to inform ACPICA of these GPEs via the AcpiSetupGpeForWake interface. This
+ * not only reduces the complexity of the ACPICA initialization code, but in
+ * some cases (on systems with very large namespaces) it should reduce the
+ * kernel boot time as well.
+ */
+
/*******************************************************************************
*
* FUNCTION: AcpiEvGpeInitialize
@@ -288,10 +304,7 @@ Cleanup:
*
* DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
* result of a Load() or LoadTable() operation. If new GPE
- * methods have been installed, register the new methods and
- * enable and runtime GPEs that are associated with them. Also,
- * run any newly loaded _PRW methods in order to discover any
- * new CAN_WAKE GPEs.
+ * methods have been installed, register the new methods.
*
******************************************************************************/
@@ -303,49 +316,13 @@ AcpiEvUpdateGpes (
ACPI_GPE_BLOCK_INFO *GpeBlock;
ACPI_GPE_WALK_INFO WalkInfo;
ACPI_STATUS Status = AE_OK;
- UINT32 NewWakeGpeCount = 0;
-
-
- /* We will examine only _PRW/_Lxx/_Exx methods owned by this table */
-
- WalkInfo.OwnerId = TableOwnerId;
- WalkInfo.ExecuteByOwnerId = TRUE;
- WalkInfo.Count = 0;
- if (AcpiGbl_LeaveWakeGpesDisabled)
- {
- /*
- * 1) Run any newly-loaded _PRW methods to find any GPEs that
- * can now be marked as CAN_WAKE GPEs. Note: We must run the
- * _PRW methods before we process the _Lxx/_Exx methods because
- * we will enable all runtime GPEs associated with the new
- * _Lxx/_Exx methods at the time we process those methods.
- *
- * Unlock interpreter so that we can run the _PRW methods.
- */
- WalkInfo.GpeBlock = NULL;
- WalkInfo.GpeDevice = NULL;
-
- AcpiExExitInterpreter ();
-
- Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
- AcpiEvMatchPrwAndGpe, NULL, &WalkInfo, NULL);
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "While executing _PRW methods"));
- }
-
- AcpiExEnterInterpreter ();
- NewWakeGpeCount = WalkInfo.Count;
- }
/*
- * 2) Find any _Lxx/_Exx GPE methods that have just been loaded.
+ * Find any _Lxx/_Exx GPE methods that have just been loaded.
*
- * Any GPEs that correspond to new _Lxx/_Exx methods and are not
- * marked as CAN_WAKE are immediately enabled.
+ * Any GPEs that correspond to new _Lxx/_Exx methods are immediately
+ * enabled.
*
* Examine the namespace underneath each GpeDevice within the
* GpeBlock lists.
@@ -357,7 +334,8 @@ AcpiEvUpdateGpes (
}
WalkInfo.Count = 0;
- WalkInfo.EnableThisGpe = TRUE;
+ WalkInfo.OwnerId = TableOwnerId;
+ WalkInfo.ExecuteByOwnerId = TRUE;
/* Walk the interrupt level descriptor list */
@@ -388,11 +366,9 @@ AcpiEvUpdateGpes (
GpeXruptInfo = GpeXruptInfo->Next;
}
- if (WalkInfo.Count || NewWakeGpeCount)
+ if (WalkInfo.Count)
{
- ACPI_INFO ((AE_INFO,
- "Enabled %u new runtime GPEs, added %u new wakeup GPEs",
- WalkInfo.Count, NewWakeGpeCount));
+ ACPI_INFO ((AE_INFO, "Enabled %u new GPEs", WalkInfo.Count));
}
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
@@ -422,9 +398,7 @@ AcpiEvUpdateGpes (
* xx - is the GPE number [in HEX]
*
* If WalkInfo->ExecuteByOwnerId is TRUE, we only execute examine GPE methods
- * with that owner.
- * If WalkInfo->EnableThisGpe is TRUE, the GPE that is referred to by a GPE
- * method is immediately enabled (Used for Load/LoadTable operators)
+ * with that owner.
*
******************************************************************************/
@@ -438,8 +412,6 @@ AcpiEvMatchGpeMethod (
ACPI_NAMESPACE_NODE *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
ACPI_GPE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_GPE_WALK_INFO, Context);
ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_NAMESPACE_NODE *GpeDevice;
- ACPI_STATUS Status;
UINT32 GpeNumber;
char Name[ACPI_NAME_SIZE + 1];
UINT8 Type;
@@ -474,9 +446,6 @@ AcpiEvMatchGpeMethod (
/*
* 3) Edge/Level determination is based on the 2nd character
* of the method name
- *
- * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
- * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
*/
switch (Name[1])
{
@@ -551,212 +520,12 @@ AcpiEvMatchGpeMethod (
* Add the GPE information from above to the GpeEventInfo block for
* use during dispatch of this GPE.
*/
+ GpeEventInfo->Flags &= ~(ACPI_GPE_DISPATCH_MASK);
GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD);
GpeEventInfo->Dispatch.MethodNode = MethodNode;
- /*
- * Enable this GPE if requested. This only happens when during the
- * execution of a Load or LoadTable operator. We have found a new
- * GPE method and want to immediately enable the GPE if it is a
- * runtime GPE.
- */
- if (WalkInfo->EnableThisGpe)
- {
- /* Ignore GPEs that can wake the system */
-
- if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE) ||
- !AcpiGbl_LeaveWakeGpesDisabled)
- {
- WalkInfo->Count++;
- GpeDevice = WalkInfo->GpeDevice;
-
- if (GpeDevice == AcpiGbl_FadtGpeDevice)
- {
- GpeDevice = NULL;
- }
-
- Status = AcpiEnableGpe (GpeDevice, GpeNumber);
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "Could not enable GPE 0x%02X", GpeNumber));
- }
- }
- }
-
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Registered GPE method %s as GPE number 0x%.2X\n",
Name, GpeNumber));
return_ACPI_STATUS (AE_OK);
}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiEvMatchPrwAndGpe
- *
- * PARAMETERS: Callback from WalkNamespace
- *
- * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is
- * not aborted on a single _PRW failure.
- *
- * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
- * Device. Run the _PRW method. If present, extract the GPE
- * number and mark the GPE as a CAN_WAKE GPE. Allows a
- * per-OwnerId execution if ExecuteByOwnerId is TRUE in the
- * WalkInfo parameter block.
- *
- * If WalkInfo->ExecuteByOwnerId is TRUE, we only execute _PRWs with that
- * owner.
- * If WalkInfo->GpeDevice is NULL, we execute every _PRW found. Otherwise,
- * we only execute _PRWs that refer to the input GpeDevice.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvMatchPrwAndGpe (
- ACPI_HANDLE ObjHandle,
- UINT32 Level,
- void *Context,
- void **ReturnValue)
-{
- ACPI_GPE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_GPE_WALK_INFO, Context);
- ACPI_NAMESPACE_NODE *GpeDevice;
- ACPI_GPE_BLOCK_INFO *GpeBlock;
- ACPI_NAMESPACE_NODE *TargetGpeDevice;
- ACPI_NAMESPACE_NODE *PrwNode;
- ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_OPERAND_OBJECT *PkgDesc;
- ACPI_OPERAND_OBJECT *ObjDesc;
- UINT32 GpeNumber;
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (EvMatchPrwAndGpe);
-
-
- /* Check for a _PRW method under this device */
-
- Status = AcpiNsGetNode (ObjHandle, METHOD_NAME__PRW,
- ACPI_NS_NO_UPSEARCH, &PrwNode);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (AE_OK);
- }
-
- /* Check if requested OwnerId matches this OwnerId */
-
- if ((WalkInfo->ExecuteByOwnerId) &&
- (PrwNode->OwnerId != WalkInfo->OwnerId))
- {
- return_ACPI_STATUS (AE_OK);
- }
-
- /* Execute the _PRW */
-
- Status = AcpiUtEvaluateObject (PrwNode, NULL,
- ACPI_BTYPE_PACKAGE, &PkgDesc);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (AE_OK);
- }
-
- /* The returned _PRW package must have at least two elements */
-
- if (PkgDesc->Package.Count < 2)
- {
- goto Cleanup;
- }
-
- /* Extract pointers from the input context */
-
- GpeDevice = WalkInfo->GpeDevice;
- GpeBlock = WalkInfo->GpeBlock;
-
- /*
- * The _PRW object must return a package, we are only interested
- * in the first element
- */
- ObjDesc = PkgDesc->Package.Elements[0];
-
- if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
- {
- /* Use FADT-defined GPE device (from definition of _PRW) */
-
- TargetGpeDevice = NULL;
- if (GpeDevice)
- {
- TargetGpeDevice = AcpiGbl_FadtGpeDevice;
- }
-
- /* Integer is the GPE number in the FADT described GPE blocks */
-
- GpeNumber = (UINT32) ObjDesc->Integer.Value;
- }
- else if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
- {
- /* Package contains a GPE reference and GPE number within a GPE block */
-
- if ((ObjDesc->Package.Count < 2) ||
- ((ObjDesc->Package.Elements[0])->Common.Type !=
- ACPI_TYPE_LOCAL_REFERENCE) ||
- ((ObjDesc->Package.Elements[1])->Common.Type !=
- ACPI_TYPE_INTEGER))
- {
- goto Cleanup;
- }
-
- /* Get GPE block reference and decode */
-
- TargetGpeDevice = ObjDesc->Package.Elements[0]->Reference.Node;
- GpeNumber = (UINT32) ObjDesc->Package.Elements[1]->Integer.Value;
- }
- else
- {
- /* Unknown type, just ignore it */
-
- goto Cleanup;
- }
-
- /* Get the GpeEventInfo for this GPE */
-
- if (GpeDevice)
- {
- /*
- * Is this GPE within this block?
- *
- * TRUE if and only if these conditions are true:
- * 1) The GPE devices match.
- * 2) The GPE index(number) is within the range of the Gpe Block
- * associated with the GPE device.
- */
- if (GpeDevice != TargetGpeDevice)
- {
- goto Cleanup;
- }
-
- GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
- }
- else
- {
- /* GpeDevice is NULL, just match the TargetDevice and GpeNumber */
-
- GpeEventInfo = AcpiEvGetGpeEventInfo (TargetGpeDevice, GpeNumber);
- }
-
- if (GpeEventInfo)
- {
- if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
- {
- /* This GPE can wake the system */
-
- GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
- WalkInfo->Count++;
- }
- }
-
-Cleanup:
- AcpiUtRemoveReference (PkgDesc);
- return_ACPI_STATUS (AE_OK);
-}
-
OpenPOWER on IntegriCloud