summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--changes.txt72
-rw-r--r--common/dmtable.c27
-rw-r--r--common/dmtbinfo.c2
-rw-r--r--compiler/aslanalyze.c41
-rw-r--r--compiler/aslerror.c65
-rw-r--r--compiler/aslmessages.h7
-rw-r--r--compiler/dtutils.c1
-rw-r--r--debugger/dbcmds.c2
-rw-r--r--debugger/dbdisply.c15
-rw-r--r--debugger/dbexec.c22
-rw-r--r--dispatcher/dswexec.c20
-rw-r--r--events/evevent.c60
-rw-r--r--events/evgpe.c288
-rw-r--r--events/evgpeblk.c106
-rw-r--r--events/evgpeinit.c285
-rw-r--r--events/evgpeutil.c45
-rw-r--r--events/evxface.c142
-rw-r--r--events/evxfevnt.c737
-rw-r--r--events/evxfgpe.c962
-rw-r--r--executer/exconfig.c7
-rw-r--r--include/acdebug.h2
-rw-r--r--include/acdisasm.h1
-rw-r--r--include/acevents.h35
-rw-r--r--include/acglobal.h14
-rw-r--r--include/aclocal.h17
-rw-r--r--include/acpixf.h82
-rw-r--r--include/actypes.h54
-rw-r--r--tests/misc/badcode.asl11
-rw-r--r--tools/acpiexec/Makefile4
-rw-r--r--tools/acpiexec/aecommon.h9
-rw-r--r--tools/acpiexec/aeexec.c21
-rw-r--r--tools/acpiexec/aehandlers.c58
-rw-r--r--tools/acpisrc/astable.c68
-rw-r--r--utilities/utglobal.c2
-rw-r--r--utilities/utxface.c21
35 files changed, 1911 insertions, 1394 deletions
diff --git a/changes.txt b/changes.txt
index 2153841..c586108 100644
--- a/changes.txt
+++ b/changes.txt
@@ -1,4 +1,76 @@
----------------------------------------
+09 December 2010. Summary of changes for version 20101209:
+
+This release is available at www.acpica.org/downloads
+
+1) ACPI CA Core Subsystem:
+
+Completed the major overhaul of the GPE support code that was begun in July
+2010. Major features include: removal of _PRW execution in ACPICA (host
+executes _PRWs anyway), cleanup of "wake" GPE interfaces and processing,
+changes to existing interfaces, simplification of GPE handler operation, and
+a handful of new interfaces:
+
+ AcpiUpdateAllGpes
+ AcpiFinishGpe
+ AcpiSetupGpeForWake
+ AcpiSetGpeWakeMask
+ One new file, evxfgpe.c to consolidate all external GPE interfaces.
+
+See the ACPICA Programmer Reference for full details and programming
+information. See the new section 4.4 "General Purpose Event (GPE) Support"
+for a full overview, and section 8.7 "ACPI General Purpose Event Management"
+for programming details. ACPICA BZ 858,870,877. Matthew Garrett, Lin Ming,
+Bob Moore, Rafael Wysocki.
+
+Implemented a new GPE feature for Windows compatibility, the "Implicit Wake
+GPE Notify". This feature will automatically issue a Notify(2) on a device
+when a Wake GPE is received if there is no corresponding GPE method or
+handler. ACPICA BZ 870.
+
+Fixed a problem with the Scope() operator during table parse and load phase.
+During load phase (table load or method execution), the scope operator should
+not enter the target into the namespace. Instead, it should open a new scope
+at the target location. Linux BZ 19462, ACPICA BZ 882.
+
+Example Code and Data Size: These are the sizes for the OS-independent
+acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
+debug version of the code includes the debug output trace mechanism and has a
+much larger code and data size.
+
+ Previous Release:
+ Non-Debug Version: 89.8K Code, 18.9K Data, 108.7K Total
+ Debug Version: 166.6K Code, 52.1K Data, 218.7K Total
+ Current Release:
+ Non-Debug Version: 89.9K Code, 19.0K Data, 108.9K Total
+ Debug Version: 166.3K Code, 52.1K Data, 218.4K Total
+
+2) iASL Compiler/Disassembler and Tools:
+
+iASL: Relax the alphanumeric restriction on _CID strings. These strings are
+"bus-specific" per the ACPI specification, and therefore any characters are
+acceptable. The only checks that can be performed are for a null string and
+perhaps for a leading asterisk. ACPICA BZ 886.
+
+iASL: Fixed a problem where a syntax error that caused a premature EOF
+condition on the source file emitted a very confusing error message. The
+premature EOF is now detected correctly. ACPICA BZ 891.
+
+Disassembler: Decode the AccessSize within a Generic Address Structure (byte
+access, word access, etc.) Note, this field does not allow arbitrary bit
+access, the size is encoded as 1=byte, 2=word, 3=dword, and 4=qword.
+
+New: AcpiNames utility - Example namespace dump utility. Shows an example of
+ACPICA configuration for a minimal namespace dump utility. Uses table and
+namespace managers, but no AML interpreter. Does not add any functionality
+over AcpiExec, it is a subset of AcpiExec. The purpose is to show how to
+partition and configure ACPICA. ACPICA BZ 883.
+
+AML Debugger: Increased the debugger buffer size for method return objects.
+Was 4K, increased to 16K. Also enhanced error messages for debugger method
+execution, including the buffer overflow case.
+
+----------------------------------------
13 October 2010. Summary of changes for version 20101013:
This release is available at www.acpica.org/downloads
diff --git a/common/dmtable.c b/common/dmtable.c
index 05bd5e4..d2bf698 100644
--- a/common/dmtable.c
+++ b/common/dmtable.c
@@ -295,6 +295,19 @@ static const char *AcpiDmFadtProfiles[] =
"Unknown Profile Type"
};
+#define ACPI_GAS_WIDTH_RESERVED 5
+
+static const char *AcpiDmGasAccessWidth[] =
+{
+ "Undefined/Legacy",
+ "Byte Access:8",
+ "Word Access:16",
+ "DWord Access:32",
+ "QWord Access:64",
+ "Unknown Width Encoding"
+};
+
+
/*******************************************************************************
*
* ACPI Table Data, indexed by signature.
@@ -669,6 +682,7 @@ AcpiDmDumpTable (
case ACPI_DMT_UINT8:
case ACPI_DMT_CHKSUM:
case ACPI_DMT_SPACEID:
+ case ACPI_DMT_ACCWIDTH:
case ACPI_DMT_IVRS:
case ACPI_DMT_MADT:
case ACPI_DMT_SRAT:
@@ -884,6 +898,19 @@ AcpiDmDumpTable (
AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target));
break;
+ case ACPI_DMT_ACCWIDTH:
+
+ /* Encoded Access Width */
+
+ Temp8 = *Target;
+ if (Temp8 > ACPI_GAS_WIDTH_RESERVED)
+ {
+ Temp8 = ACPI_GAS_WIDTH_RESERVED;
+ }
+
+ AcpiOsPrintf ("%2.2X (%s)\n", Temp8, AcpiDmGasAccessWidth[Temp8]);
+ break;
+
case ACPI_DMT_GAS:
/* Generic Address Structure */
diff --git a/common/dmtbinfo.c b/common/dmtbinfo.c
index 9abf586..03705ab 100644
--- a/common/dmtbinfo.c
+++ b/common/dmtbinfo.c
@@ -282,7 +282,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoGas[] =
{ACPI_DMT_SPACEID, ACPI_GAS_OFFSET (SpaceId), "Space ID", 0},
{ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitWidth), "Bit Width", 0},
{ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitOffset), "Bit Offset", 0},
- {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (AccessWidth), "Access Width", 0},
+ {ACPI_DMT_ACCWIDTH, ACPI_GAS_OFFSET (AccessWidth), "Encoded Access Width", 0},
{ACPI_DMT_UINT64, ACPI_GAS_OFFSET (Address), "Address", 0},
ACPI_DMT_TERMINATOR
};
diff --git a/compiler/aslanalyze.c b/compiler/aslanalyze.c
index 1087bca..396c126 100644
--- a/compiler/aslanalyze.c
+++ b/compiler/aslanalyze.c
@@ -684,19 +684,45 @@ AnCheckId (
UINT32 AlphaPrefixLength;
+ /* Only care about string versions of _HID/_CID (integers are legal) */
+
if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)
{
return;
}
+ /* For both _HID and _CID, the string must be non-null */
+
Length = strlen (Op->Asl.Value.String);
+ if (!Length)
+ {
+ AslError (ASL_ERROR, ASL_MSG_NULL_STRING,
+ Op, NULL);
+ return;
+ }
/*
- * If _HID/_CID is a string, all characters must be alphanumeric.
- * One of the things we want to catch here is the use of
- * a leading asterisk in the string -- an odd construct
- * that certain platform manufacturers are fond of.
+ * One of the things we want to catch here is the use of a leading
+ * asterisk in the string -- an odd construct that certain platform
+ * manufacturers are fond of. Technically, a leading asterisk is OK
+ * for _CID, but a valid use of this has not been seen.
*/
+ if (*Op->Asl.Value.String == '*')
+ {
+ AslError (ASL_ERROR, ASL_MSG_LEADING_ASTERISK,
+ Op, Op->Asl.Value.String);
+ return;
+ }
+
+ /* _CID strings are bus-specific, no more checks can be performed */
+
+ if (Type == ASL_TYPE_CID)
+ {
+ return;
+ }
+
+ /* For _HID, all characters must be alphanumeric */
+
for (i = 0; Op->Asl.Value.String[i]; i++)
{
if (!isalnum ((int) Op->Asl.Value.String[i]))
@@ -707,13 +733,6 @@ AnCheckId (
}
}
- if (Type == ASL_TYPE_CID)
- {
- /* _CID strings are bus-specific, no more checks can be performed */
-
- return;
- }
-
/* _HID String must be of the form "XXX####" or "ACPI####" */
if ((Length < 7) || (Length > 8))
diff --git a/compiler/aslerror.c b/compiler/aslerror.c
index 59d3d20..af20368 100644
--- a/compiler/aslerror.c
+++ b/compiler/aslerror.c
@@ -241,6 +241,8 @@ AePrintException (
UINT32 ErrorColumn;
FILE *OutputFile;
FILE *SourceFile;
+ long FileSize;
+ BOOLEAN PrematureEOF = FALSE;
if (Gbl_NoErrors)
@@ -289,6 +291,19 @@ AePrintException (
SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
}
+ if (SourceFile)
+ {
+ /* Determine if the error occurred at source file EOF */
+
+ fseek (SourceFile, 0, SEEK_END);
+ FileSize = ftell (SourceFile);
+
+ if ((long) Enode->LogicalByteOffset >= FileSize)
+ {
+ PrematureEOF = TRUE;
+ }
+ }
+
if (Header)
{
fprintf (OutputFile, "%s", Header);
@@ -307,33 +322,42 @@ AePrintException (
fprintf (OutputFile, " %6u: ", Enode->LineNumber);
/*
- * Seek to the offset in the combined source file, read the source
- * line, and write it to the output.
+ * If not at EOF, get the corresponding source code line and
+ * display it. Don't attempt this if we have a premature EOF
+ * condition.
*/
- Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
- (int) SEEK_SET);
- if (Actual)
- {
- fprintf (OutputFile,
- "[*** iASL: Seek error on source code temp file %s ***]",
- Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
- }
- else
+ if (!PrematureEOF)
{
- RActual = fread (&SourceByte, 1, 1, SourceFile);
- if (!RActual)
+ /*
+ * Seek to the offset in the combined source file, read
+ * the source line, and write it to the output.
+ */
+ Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
+ (int) SEEK_SET);
+ if (Actual)
{
fprintf (OutputFile,
- "[*** iASL: Read error on source code temp file %s ***]",
+ "[*** iASL: Seek error on source code temp file %s ***]",
Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
}
-
- else while (RActual && SourceByte && (SourceByte != '\n'))
+ else
{
- fwrite (&SourceByte, 1, 1, OutputFile);
RActual = fread (&SourceByte, 1, 1, SourceFile);
+ if (!RActual)
+ {
+ fprintf (OutputFile,
+ "[*** iASL: Read error on source code temp file %s ***]",
+ Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
+ }
+
+ else while (RActual && SourceByte && (SourceByte != '\n'))
+ {
+ fwrite (&SourceByte, 1, 1, OutputFile);
+ RActual = fread (&SourceByte, 1, 1, SourceFile);
+ }
}
}
+
fprintf (OutputFile, "\n");
}
}
@@ -376,7 +400,7 @@ AePrintException (
ExtraMessage = NULL;
}
- if (Gbl_VerboseErrors)
+ if (Gbl_VerboseErrors && !PrematureEOF)
{
SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
@@ -406,6 +430,11 @@ AePrintException (
fprintf (OutputFile, " (%s)", ExtraMessage);
}
+ if (PrematureEOF)
+ {
+ fprintf (OutputFile, " and premature End-Of-File");
+ }
+
fprintf (OutputFile, "\n");
if (Gbl_VerboseErrors)
{
diff --git a/compiler/aslmessages.h b/compiler/aslmessages.h
index 0457800..c69f7a2 100644
--- a/compiler/aslmessages.h
+++ b/compiler/aslmessages.h
@@ -258,6 +258,9 @@ typedef enum
ASL_MSG_NULL_DESCRIPTOR,
ASL_MSG_UPPER_CASE,
ASL_MSG_HID_LENGTH,
+ ASL_MSG_NULL_STRING,
+ ASL_MSG_LEADING_ASTERISK,
+
ASL_MSG_INVALID_FIELD_NAME,
ASL_MSG_INTEGER_SIZE,
ASL_MSG_INVALID_HEX_INTEGER,
@@ -382,7 +385,7 @@ char *AslMessages [] = {
/* ASL_MSG_VENDOR_LIST */ "Too many vendor data bytes (7 max)",
/* ASL_MSG_WRITE */ "Could not write file",
/* ASL_MSG_MULTIPLE_DEFAULT */ "More than one Default statement within Switch construct",
-/* ASL_MSG_TIMEOUT */ "Possible operator timeout is ignored",
+/* ASL_MSG_TIMEOUT */ "Result is not used, possible operator timeout will be missed",
/* ASL_MSG_RESULT_NOT_USED */ "Result is not used, operator has no effect",
/* ASL_MSG_NOT_REFERENCED */ "Namespace object is not referenced",
/* ASL_MSG_NON_ZERO */ "Operand evaluates to zero",
@@ -403,6 +406,8 @@ char *AslMessages [] = {
/* ASL_MSG_NULL_DESCRIPTOR */ "Min/Max/Length/Gran are all zero, but no resource tag",
/* ASL_MSG_UPPER_CASE */ "Non-hex letters must be upper case",
/* ASL_MSG_HID_LENGTH */ "_HID string must be exactly 7 or 8 characters",
+/* ASL_MSG_NULL_STRING */ "Invalid zero-length (null) string",
+/* ASL_MSG_LEADING_ASTERISK */ "Invalid leading asterisk",
/* These messages are used by the data table compiler only */
diff --git a/compiler/dtutils.c b/compiler/dtutils.c
index 2394b30..9f71036 100644
--- a/compiler/dtutils.c
+++ b/compiler/dtutils.c
@@ -573,6 +573,7 @@ DtGetFieldLength (
case ACPI_DMT_UINT8:
case ACPI_DMT_CHKSUM:
case ACPI_DMT_SPACEID:
+ case ACPI_DMT_ACCWIDTH:
case ACPI_DMT_IVRS:
case ACPI_DMT_MADT:
case ACPI_DMT_SRAT:
diff --git a/debugger/dbcmds.c b/debugger/dbcmds.c
index 5c4ca82..d25edb7 100644
--- a/debugger/dbcmds.c
+++ b/debugger/dbcmds.c
@@ -2071,7 +2071,7 @@ AcpiDbGenerateGpe (
return;
}
- (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber);
+ (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber);
}
diff --git a/debugger/dbdisply.c b/debugger/dbdisply.c
index a0ae7a5..0bf921b 100644
--- a/debugger/dbdisply.c
+++ b/debugger/dbdisply.c
@@ -896,7 +896,8 @@ AcpiDbDisplayGpes (
GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
- if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
+ if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE)
{
/* This GPE is not used (no method or handler), ignore it */
@@ -906,8 +907,7 @@ AcpiDbDisplayGpes (
AcpiOsPrintf (
" GPE %.2X: %p RunRefs %2.2X Flags %2.2X (",
GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo,
- GpeEventInfo->RuntimeCount,
- GpeEventInfo->Flags);
+ GpeEventInfo->RuntimeCount, GpeEventInfo->Flags);
/* Decode the flags byte */
@@ -931,14 +931,17 @@ AcpiDbDisplayGpes (
switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
{
- case ACPI_GPE_DISPATCH_NOT_USED:
+ case ACPI_GPE_DISPATCH_NONE:
AcpiOsPrintf ("NotUsed");
break;
+ case ACPI_GPE_DISPATCH_METHOD:
+ AcpiOsPrintf ("Method");
+ break;
case ACPI_GPE_DISPATCH_HANDLER:
AcpiOsPrintf ("Handler");
break;
- case ACPI_GPE_DISPATCH_METHOD:
- AcpiOsPrintf ("Method");
+ case ACPI_GPE_DISPATCH_NOTIFY:
+ AcpiOsPrintf ("Notify");
break;
default:
AcpiOsPrintf ("UNKNOWN: %X",
diff --git a/debugger/dbexec.c b/debugger/dbexec.c
index 56e7de7..db2f69b 100644
--- a/debugger/dbexec.c
+++ b/debugger/dbexec.c
@@ -180,6 +180,9 @@ AcpiDbExecuteMethod (
ACPI_DEVICE_INFO *ObjInfo;
+ ACPI_FUNCTION_TRACE (DbExecuteMethod);
+
+
if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel)
{
AcpiOsPrintf ("Warning: debug output is not enabled!\n");
@@ -190,7 +193,7 @@ AcpiDbExecuteMethod (
Status = AcpiGetHandle (NULL, Info->Pathname, &Handle);
if (ACPI_FAILURE (Status))
{
- return (Status);
+ return_ACPI_STATUS (Status);
}
/* Get the object info for number of method parameters */
@@ -198,7 +201,7 @@ AcpiDbExecuteMethod (
Status = AcpiGetObjectInfo (Handle, &ObjInfo);
if (ACPI_FAILURE (Status))
{
- return (Status);
+ return_ACPI_STATUS (Status);
}
ParamObjects.Pointer = NULL;
@@ -269,7 +272,20 @@ AcpiDbExecuteMethod (
AcpiGbl_CmSingleStep = FALSE;
AcpiGbl_MethodExecuting = FALSE;
- return (Status);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "while executing %s from debugger", Info->Pathname));
+
+ if (Status == AE_BUFFER_OVERFLOW)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)",
+ ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length));
+ }
+ }
+
+ return_ACPI_STATUS (Status);
}
diff --git a/dispatcher/dswexec.c b/dispatcher/dswexec.c
index 3c1f85e..81267b5 100644
--- a/dispatcher/dswexec.c
+++ b/dispatcher/dswexec.c
@@ -400,10 +400,26 @@ AcpiDsExecBeginOp (
* we must enter this object into the namespace. The created
* object is temporary and will be deleted upon completion of
* the execution of this method.
+ *
+ * Note 10/2010: Except for the Scope() op. This opcode does
+ * not actually create a new object, it refers to an existing
+ * object. However, for Scope(), we want to indeed open a
+ * new scope.
*/
- Status = AcpiDsLoad2BeginOp (WalkState, NULL);
+ if (Op->Common.AmlOpcode != AML_SCOPE_OP)
+ {
+ Status = AcpiDsLoad2BeginOp (WalkState, NULL);
+ }
+ else
+ {
+ Status = AcpiDsScopeStackPush (Op->Named.Node,
+ Op->Named.Node->Type, WalkState);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
}
-
break;
diff --git a/events/evevent.c b/events/evevent.c
index d9715a8..9da7831 100644
--- a/events/evevent.c
+++ b/events/evevent.c
@@ -180,54 +180,6 @@ AcpiEvInitializeEvents (
/*******************************************************************************
*
- * FUNCTION: AcpiEvInstallFadtGpes
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
- * (0 and 1). This causes the _PRW methods to be run, so the HW
- * must be fully initialized at this point, including global lock
- * support.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEvInstallFadtGpes (
- void)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (EvInstallFadtGpes);
-
-
- /* Namespace must be locked */
-
- Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- /* FADT GPE Block 0 */
-
- (void) AcpiEvInitializeGpeBlock (
- AcpiGbl_FadtGpeDevice, AcpiGbl_GpeFadtBlocks[0]);
-
- /* FADT GPE Block 1 */
-
- (void) AcpiEvInitializeGpeBlock (
- AcpiGbl_FadtGpeDevice, AcpiGbl_GpeFadtBlocks[1]);
-
- (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiEvInstallXruptHandlers
*
* PARAMETERS: None
@@ -366,9 +318,17 @@ AcpiEvFixedEventDetect (
if ((FixedStatus & AcpiGbl_FixedEventInfo[i].StatusBitMask) &&
(FixedEnable & AcpiGbl_FixedEventInfo[i].EnableBitMask))
{
- /* Found an active (signalled) event */
-
+ /*
+ * Found an active (signalled) event. Invoke global event
+ * handler if present.
+ */
AcpiFixedEventCount[i]++;
+ if (AcpiGbl_GlobalEventHandler)
+ {
+ AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_FIXED, NULL,
+ i, AcpiGbl_GlobalEventHandlerContext);
+ }
+
IntStatus |= AcpiEvFixedEventDispatch (i);
}
}
diff --git a/events/evgpe.c b/events/evgpe.c
index f7ab160..2ed4c3c 100644
--- a/events/evgpe.c
+++ b/events/evgpe.c
@@ -202,12 +202,13 @@ AcpiEvEnableGpe (
/*
- * We will only allow a GPE to be enabled if it has either an
- * associated method (_Lxx/_Exx) or a handler. Otherwise, the
- * GPE will be immediately disabled by AcpiEvGpeDispatch the
- * first time it fires.
+ * 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))
+ if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE)
{
return_ACPI_STATUS (AE_NO_HANDLER);
}
@@ -229,6 +230,104 @@ AcpiEvEnableGpe (
/*******************************************************************************
*
+ * FUNCTION: AcpiEvAddGpeReference
+ *
+ * PARAMETERS: GpeEventInfo - Add a reference to this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ * hardware-enabled.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvAddGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (EvAddGpeReference);
+
+
+ if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
+ {
+ return_ACPI_STATUS (AE_LIMIT);
+ }
+
+ GpeEventInfo->RuntimeCount++;
+ if (GpeEventInfo->RuntimeCount == 1)
+ {
+ /* Enable on first reference */
+
+ Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiEvEnableGpe (GpeEventInfo);
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount--;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvRemoveGpeReference
+ *
+ * PARAMETERS: GpeEventInfo - Remove a reference to this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ * removed, the GPE is hardware-disabled.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvRemoveGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (EvRemoveGpeReference);
+
+
+ if (!GpeEventInfo->RuntimeCount)
+ {
+ return_ACPI_STATUS (AE_LIMIT);
+ }
+
+ GpeEventInfo->RuntimeCount--;
+ if (!GpeEventInfo->RuntimeCount)
+ {
+ /* Disable on last reference */
+
+ Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
+ if (ACPI_SUCCESS (Status))
+ {
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+ }
+
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount++;
+ }
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiEvLowGetGpeInfo
*
* PARAMETERS: GpeNumber - Raw GPE number
@@ -412,7 +511,7 @@ AcpiEvGpeDetect (
}
ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
- "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
+ "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg));
/* Check if there is anything active at all in this register */
@@ -437,7 +536,7 @@ AcpiEvGpeDetect (
* Found an active GPE. Dispatch the event to a handler
* or method.
*/
- IntStatus |= AcpiEvGpeDispatch (
+ IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node,
&GpeBlock->EventInfo[((ACPI_SIZE) i *
ACPI_GPE_REGISTER_WIDTH) + j],
j + GpeRegisterInfo->BaseGpeNumber);
@@ -521,13 +620,27 @@ AcpiEvAsynchExecuteGpeMethod (
return_VOID;
}
- /*
- * Must check for control method type dispatch one more time to avoid a
- * race with EvGpeInstallHandler
- */
- if ((LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD)
+ /* Do the correct dispatch - normal method or implicit notify */
+
+ switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
{
+ case ACPI_GPE_DISPATCH_NOTIFY:
+
+ /*
+ * Implicit notify.
+ * Dispatch a DEVICE_WAKE notify to the appropriate handler.
+ * NOTE: the request is queued for execution after this method
+ * completes. The notify handlers are NOT invoked synchronously
+ * from this thread -- because handlers may in turn run other
+ * control methods.
+ */
+ Status = AcpiEvQueueNotifyRequest (
+ LocalGpeEventInfo->Dispatch.DeviceNode,
+ ACPI_NOTIFY_DEVICE_WAKE);
+ break;
+
+ case ACPI_GPE_DISPATCH_METHOD:
+
/* Allocate the evaluation information block */
Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
@@ -538,8 +651,8 @@ AcpiEvAsynchExecuteGpeMethod (
else
{
/*
- * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
- * control method that corresponds to this GPE
+ * 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->Flags = ACPI_IGNORE_RETURN_VALUE;
@@ -554,6 +667,11 @@ AcpiEvAsynchExecuteGpeMethod (
"while evaluating GPE method [%4.4s]",
AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode)));
}
+
+ break;
+
+ default:
+ return_VOID; /* Should never happen */
}
/* Defer enabling of GPE until all notify handlers are done */
@@ -573,6 +691,7 @@ AcpiEvAsynchExecuteGpeMethod (
* FUNCTION: AcpiEvAsynchEnableGpe
*
* PARAMETERS: Context (GpeEventInfo) - Info for this GPE
+ * Callback from AcpiOsExecute
*
* RETURN: None
*
@@ -586,6 +705,32 @@ AcpiEvAsynchEnableGpe (
void *Context)
{
ACPI_GPE_EVENT_INFO *GpeEventInfo = Context;
+
+
+ (void) AcpiEvFinishGpe (GpeEventInfo);
+
+ ACPI_FREE (GpeEventInfo);
+ return;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEvFinishGpe
+ *
+ * PARAMETERS: GpeEventInfo - Info for this GPE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
+ * of a GPE method or a synchronous or asynchronous GPE handler.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvFinishGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo)
+{
ACPI_STATUS Status;
@@ -593,25 +738,23 @@ AcpiEvAsynchEnableGpe (
ACPI_GPE_LEVEL_TRIGGERED)
{
/*
- * GPE is level-triggered, we clear the GPE status bit after handling
- * the event.
+ * GPE is level-triggered, we clear the GPE status bit after
+ * handling the event.
*/
Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
- goto Exit;
+ return (Status);
}
}
/*
- * Enable this GPE, conditionally. This means that the GPE will only be
- * physically enabled if the EnableForRun bit is set in the EventInfo
+ * Enable this GPE, conditionally. This means that the GPE will
+ * only be physically enabled if the EnableForRun bit is set
+ * in the EventInfo.
*/
(void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
-
-Exit:
- ACPI_FREE (GpeEventInfo);
- return;
+ return (AE_OK);
}
@@ -619,8 +762,9 @@ Exit:
*
* FUNCTION: AcpiEvGpeDispatch
*
- * PARAMETERS: GpeEventInfo - Info for this GPE
- * GpeNumber - Number relative to the parent GPE block
+ * 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
*
@@ -633,16 +777,25 @@ Exit:
UINT32
AcpiEvGpeDispatch (
+ ACPI_NAMESPACE_NODE *GpeDevice,
ACPI_GPE_EVENT_INFO *GpeEventInfo,
UINT32 GpeNumber)
{
ACPI_STATUS Status;
+ UINT32 ReturnValue;
ACPI_FUNCTION_TRACE (EvGpeDispatch);
+ /* Invoke global event handler if present */
+
AcpiGpeCount++;
+ if (AcpiGbl_GlobalEventHandler)
+ {
+ AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice,
+ GpeNumber, AcpiGbl_GlobalEventHandlerContext);
+ }
/*
* If edge-triggered, clear the GPE status bit now. Note that
@@ -655,58 +808,55 @@ AcpiEvGpeDispatch (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to clear GPE[0x%2X]", GpeNumber));
+ "Unable to clear GPE%02X", GpeNumber));
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, we disable this GPE to prevent further such pointless
- * events from firing.
+ * 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);
+ }
+
+ /*
+ * 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 (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
{
case ACPI_GPE_DISPATCH_HANDLER:
- /*
- * Invoke the installed handler (at interrupt level)
- * Ignore return status for now.
- * TBD: leave GPE disabled on error?
- */
- (void) GpeEventInfo->Dispatch.Handler->Address (
- GpeEventInfo->Dispatch.Handler->Context);
+ /* Invoke the installed handler (at interrupt level) */
- /* It is now safe to clear level-triggered events. */
+ ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
+ GpeDevice, GpeNumber,
+ GpeEventInfo->Dispatch.Handler->Context);
- if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
- ACPI_GPE_LEVEL_TRIGGERED)
+ /* If requested, clear (if level-triggered) and reenable the GPE */
+
+ if (ReturnValue & ACPI_REENABLE_GPE)
{
- Status = AcpiHwClearGpe (GpeEventInfo);
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to clear GPE[0x%2X]", GpeNumber));
- return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
- }
+ (void) AcpiEvFinishGpe (GpeEventInfo);
}
break;
case ACPI_GPE_DISPATCH_METHOD:
-
- /*
- * Disable the GPE, so it doesn't keep firing before the method has a
- * chance to run (it runs asynchronously with interrupts enabled).
- */
- Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to disable GPE[0x%2X]", GpeNumber));
- return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
- }
+ case ACPI_GPE_DISPATCH_NOTIFY:
/*
* Execute the method associated with the GPE
@@ -717,7 +867,7 @@ AcpiEvGpeDispatch (
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to queue handler for GPE[0x%2X] - event disabled",
+ "Unable to queue handler for GPE%02X - event disabled",
GpeNumber));
}
break;
@@ -730,20 +880,8 @@ AcpiEvGpeDispatch (
* a GPE to be enabled if it has no handler or method.
*/
ACPI_ERROR ((AE_INFO,
- "No handler or method for GPE[0x%2X], disabling event",
+ "No handler or method for GPE%02X, disabling event",
GpeNumber));
-
- /*
- * Disable the GPE. The GPE will remain disabled until a handler
- * is installed or ACPICA is restarted.
- */
- Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status,
- "Unable to disable GPE[0x%2X]", GpeNumber));
- return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
- }
break;
}
diff --git a/events/evgpeblk.c b/events/evgpeblk.c
index 7aaff53..5dbff0f 100644
--- a/events/evgpeblk.c
+++ b/events/evgpeblk.c
@@ -467,6 +467,7 @@ AcpiEvCreateGpeBlock (
GpeBlock->Node = GpeDevice;
GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
+ GpeBlock->Initialized = FALSE;
GpeBlock->RegisterCount = RegisterCount;
GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
@@ -493,11 +494,12 @@ AcpiEvCreateGpeBlock (
return_ACPI_STATUS (Status);
}
+ AcpiGbl_AllGpesInitialized = FALSE;
+
/* Find all GPE methods (_Lxx or_Exx) for this block */
WalkInfo.GpeBlock = GpeBlock;
WalkInfo.GpeDevice = GpeDevice;
- WalkInfo.EnableThisGpe = FALSE;
WalkInfo.ExecuteByOwnerId = FALSE;
Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
@@ -529,30 +531,26 @@ AcpiEvCreateGpeBlock (
*
* FUNCTION: AcpiEvInitializeGpeBlock
*
- * PARAMETERS: GpeDevice - Handle to the parent GPE block
- * GpeBlock - Gpe Block info
+ * PARAMETERS: ACPI_GPE_CALLBACK
*
* RETURN: Status
*
- * DESCRIPTION: Initialize and enable a GPE block. First find and run any
- * _PRT methods associated with the block, then enable the
- * appropriate GPEs.
+ * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
+ * associated methods.
* Note: Assumes namespace is locked.
*
******************************************************************************/
ACPI_STATUS
AcpiEvInitializeGpeBlock (
- ACPI_NAMESPACE_NODE *GpeDevice,
- ACPI_GPE_BLOCK_INFO *GpeBlock)
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Ignored)
{
ACPI_STATUS Status;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_GPE_WALK_INFO WalkInfo;
- UINT32 WakeGpeCount;
UINT32 GpeEnabledCount;
UINT32 GpeIndex;
- UINT32 GpeNumber;
UINT32 i;
UINT32 j;
@@ -560,51 +558,22 @@ AcpiEvInitializeGpeBlock (
ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);
- /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */
-
- if (!GpeBlock)
- {
- return_ACPI_STATUS (AE_OK);
- }
-
/*
- * Runtime option: Should wake GPEs be enabled at runtime? The default
- * is no, they should only be enabled just as the machine goes to sleep.
+ * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
+ * any GPE blocks that have been initialized already.
*/
- if (AcpiGbl_LeaveWakeGpesDisabled)
+ if (!GpeBlock || GpeBlock->Initialized)
{
- /*
- * Differentiate runtime vs wake GPEs, via the _PRW control methods.
- * Each GPE that has one or more _PRWs that reference it is by
- * definition a wake GPE and will not be enabled while the machine
- * is running.
- */
- WalkInfo.GpeBlock = GpeBlock;
- WalkInfo.GpeDevice = GpeDevice;
- WalkInfo.ExecuteByOwnerId = FALSE;
-
- Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
- ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
- AcpiEvMatchPrwAndGpe, NULL, &WalkInfo, NULL);
- if (ACPI_FAILURE (Status))
- {
- ACPI_EXCEPTION ((AE_INFO, Status, "While executing _PRW methods"));
- }
+ return_ACPI_STATUS (AE_OK);
}
/*
- * Enable all GPEs that have a corresponding method and are not
- * capable of generating wakeups. Any other GPEs within this block
- * must be enabled via the AcpiEnableGpe interface.
+ * Enable all GPEs that have a corresponding method and have the
+ * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
+ * must be enabled via the acpi_enable_gpe() interface.
*/
- WakeGpeCount = 0;
GpeEnabledCount = 0;
- if (GpeDevice == AcpiGbl_FadtGpeDevice)
- {
- GpeDevice = NULL;
- }
-
for (i = 0; i < GpeBlock->RegisterCount; i++)
{
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
@@ -613,45 +582,24 @@ AcpiEvInitializeGpeBlock (
GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
- GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber;
/*
- * If the GPE has already been enabled for runtime
- * signalling, make sure that it remains enabled, but
- * do not increment its reference count.
+ * Ignore GPEs that have no corresponding _Lxx/_Exx method
+ * and GPEs that are used to wake the system
*/
- if (GpeEventInfo->RuntimeCount)
- {
- Status = AcpiEvEnableGpe (GpeEventInfo);
- goto Enabled;
- }
-
- /* Ignore GPEs that can wake the system */
-
- if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
- {
- WakeGpeCount++;
- if (AcpiGbl_LeaveWakeGpesDisabled)
- {
- continue;
- }
- }
-
- /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
-
- if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD))
+ if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_NONE) ||
+ ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) ||
+ (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
{
continue;
}
- /* Enable this GPE */
-
- Status = AcpiEnableGpe (GpeDevice, GpeNumber);
-Enabled:
+ Status = AcpiEvAddGpeReference (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "Could not enable GPE 0x%02X", GpeNumber));
+ "Could not enable GPE 0x%02X",
+ GpeIndex + GpeBlock->BlockBaseNumber));
continue;
}
@@ -659,13 +607,13 @@ Enabled:
}
}
- if (GpeEnabledCount || WakeGpeCount)
+ if (GpeEnabledCount)
{
ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
- "Enabled %u Runtime GPEs, added %u Wake GPEs in this block\n",
- GpeEnabledCount, WakeGpeCount));
+ "Enabled %u GPEs in this block\n", GpeEnabledCount));
}
+ GpeBlock->Initialized = TRUE;
return_ACPI_STATUS (AE_OK);
}
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);
-}
-
diff --git a/events/evgpeutil.c b/events/evgpeutil.c
index 1bd42b2..d155837 100644
--- a/events/evgpeutil.c
+++ b/events/evgpeutil.c
@@ -241,6 +241,51 @@ AcpiEvValidGpeEvent (
/*******************************************************************************
*
+ * FUNCTION: AcpiEvGetGpeDevice
+ *
+ * PARAMETERS: GPE_WALK_CALLBACK
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
+ * block device. NULL if the GPE is one of the FADT-defined GPEs.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEvGetGpeDevice (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context)
+{
+ ACPI_GPE_DEVICE_INFO *Info = Context;
+
+
+ /* Increment Index by the number of GPEs in this block */
+
+ Info->NextBlockBaseIndex += GpeBlock->GpeCount;
+
+ if (Info->Index < Info->NextBlockBaseIndex)
+ {
+ /*
+ * The GPE index is within this block, get the node. Leave the node
+ * NULL for the FADT-defined GPEs
+ */
+ if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
+ {
+ Info->GpeDevice = GpeBlock->Node;
+ }
+
+ Info->Status = AE_OK;
+ return (AE_CTRL_END);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiEvGetGpeXruptBlock
*
* PARAMETERS: InterruptNumber - Interrupt for a GPE block
diff --git a/events/evxface.c b/events/evxface.c
index 5019b66..d6c7232 100644
--- a/events/evxface.c
+++ b/events/evxface.c
@@ -177,6 +177,66 @@ ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
/*******************************************************************************
*
+ * FUNCTION: AcpiInstallGlobalEventHandler
+ *
+ * PARAMETERS: Handler - Pointer to the global event handler function
+ * Context - Value passed to the handler on each event
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Saves the pointer to the handler function. The global handler
+ * is invoked upon each incoming GPE and Fixed Event. It is
+ * invoked at interrupt level at the time of the event dispatch.
+ * Can be used to update event counters, etc.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallGlobalEventHandler (
+ ACPI_GBL_EVENT_HANDLER Handler,
+ void *Context)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
+
+
+ /* Parameter validation */
+
+ if (!Handler)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Don't allow two handlers. */
+
+ if (AcpiGbl_GlobalEventHandler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto Cleanup;
+ }
+
+ AcpiGbl_GlobalEventHandler = Handler;
+ AcpiGbl_GlobalEventHandlerContext = Context;
+
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiInstallFixedEventHandler
*
* PARAMETERS: Event - Event type to enable.
@@ -691,11 +751,11 @@ AcpiInstallGpeHandler (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Type,
- ACPI_EVENT_HANDLER Address,
+ ACPI_GPE_HANDLER Address,
void *Context)
{
ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_HANDLER_INFO *Handler;
+ ACPI_GPE_HANDLER_INFO *Handler;
ACPI_STATUS Status;
ACPI_CPU_FLAGS Flags;
@@ -716,13 +776,24 @@ AcpiInstallGpeHandler (
return_ACPI_STATUS (Status);
}
+ /* Allocate and init handler object (before lock) */
+
+ Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
+ if (!Handler)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
if (!GpeEventInfo)
{
Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
+ goto FreeAndExit;
}
/* Make sure that there isn't a handler there already */
@@ -731,28 +802,40 @@ AcpiInstallGpeHandler (
ACPI_GPE_DISPATCH_HANDLER)
{
Status = AE_ALREADY_EXISTS;
- goto UnlockAndExit;
+ goto FreeAndExit;
}
- /* Allocate and init handler object */
+ Handler->Address = Address;
+ Handler->Context = Context;
+ Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
+ Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
+ (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
- Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_HANDLER_INFO));
- if (!Handler)
+ /*
+ * If the GPE is associated with a method, it may have been enabled
+ * automatically during initialization, in which case it has to be
+ * disabled now to avoid spurious execution of the handler.
+ */
+ if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) ||
+ (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) &&
+ GpeEventInfo->RuntimeCount)
{
- Status = AE_NO_MEMORY;
- goto UnlockAndExit;
- }
+ Handler->OriginallyEnabled = TRUE;
+ (void) AcpiEvRemoveGpeReference (GpeEventInfo);
- Handler->Address = Address;
- Handler->Context = Context;
- Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
+ /* Sanity check of original type against new type */
+
+ if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
+ {
+ ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
+ }
+ }
/* Install the handler */
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
GpeEventInfo->Dispatch.Handler = Handler;
- /* Setup up dispatch flags to indicate handler (vs. method) */
+ /* Setup up dispatch flags to indicate handler (vs. method/notify) */
GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
@@ -763,6 +846,11 @@ AcpiInstallGpeHandler (
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (Status);
+
+FreeAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ ACPI_FREE (Handler);
+ goto UnlockAndExit;
}
ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
@@ -787,10 +875,10 @@ ACPI_STATUS
AcpiRemoveGpeHandler (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- ACPI_EVENT_HANDLER Address)
+ ACPI_GPE_HANDLER Address)
{
ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_HANDLER_INFO *Handler;
+ ACPI_GPE_HANDLER_INFO *Handler;
ACPI_STATUS Status;
ACPI_CPU_FLAGS Flags;
@@ -811,6 +899,8 @@ AcpiRemoveGpeHandler (
return_ACPI_STATUS (Status);
}
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
@@ -839,18 +929,25 @@ AcpiRemoveGpeHandler (
/* Remove the handler */
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
Handler = GpeEventInfo->Dispatch.Handler;
/* Restore Method node (if any), set dispatch flags */
GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
- GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
- if (Handler->MethodNode)
+ GpeEventInfo->Flags &=
+ ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
+ GpeEventInfo->Flags |= Handler->OriginalFlags;
+
+ /*
+ * If the GPE was previously associated with a method and it was
+ * enabled, it should be enabled at this point to restore the
+ * post-initialization configuration.
+ */
+ if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) &&
+ Handler->OriginallyEnabled)
{
- GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD;
+ (void) AcpiEvAddGpeReference (GpeEventInfo);
}
- AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
/* Now we can free the handler object */
@@ -858,6 +955,7 @@ AcpiRemoveGpeHandler (
UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (Status);
}
diff --git a/events/evxfevnt.c b/events/evxfevnt.c
index 9c0e9b9..476c35d 100644
--- a/events/evxfevnt.c
+++ b/events/evxfevnt.c
@@ -118,21 +118,11 @@
#include "acpi.h"
#include "accommon.h"
-#include "acevents.h"
-#include "acnamesp.h"
#include "actables.h"
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evxfevnt")
-/* Local prototypes */
-
-static ACPI_STATUS
-AcpiEvGetGpeDevice (
- ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
- ACPI_GPE_BLOCK_INFO *GpeBlock,
- void *Context);
-
/*******************************************************************************
*
@@ -307,290 +297,9 @@ ACPI_EXPORT_SYMBOL (AcpiEnableEvent)
/*******************************************************************************
*
- * FUNCTION: AcpiGpeWakeup
- *
- * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
- * GpeNumber - GPE level within the GPE block
- * Action - Enable or Disable
- *
- * RETURN: Status
- *
- * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiGpeWakeup (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- UINT8 Action)
-{
- ACPI_STATUS Status = AE_OK;
- ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
- ACPI_CPU_FLAGS Flags;
- UINT32 RegisterBit;
-
-
- ACPI_FUNCTION_TRACE (AcpiGpeWakeup);
-
-
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-
- /* Ensure that we have a valid GPE number */
-
- GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
- if (!GpeEventInfo)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- GpeRegisterInfo = GpeEventInfo->RegisterInfo;
- if (!GpeRegisterInfo)
- {
- Status = AE_NOT_EXIST;
- goto UnlockAndExit;
- }
-
- RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
-
- /* Perform the action */
-
- switch (Action)
- {
- case ACPI_GPE_ENABLE:
- ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
- break;
-
- case ACPI_GPE_DISABLE:
- ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
- break;
-
- default:
- ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
- Status = AE_BAD_PARAMETER;
- break;
- }
-
-UnlockAndExit:
- AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiGpeWakeup)
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiEnableGpe
- *
- * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
- * GpeNumber - GPE level within the GPE block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
- * hardware-enabled.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEnableGpe (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber)
-{
- ACPI_STATUS Status = AE_OK;
- ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_CPU_FLAGS Flags;
-
-
- ACPI_FUNCTION_TRACE (AcpiEnableGpe);
-
-
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-
- /* Ensure that we have a valid GPE number */
-
- GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
- if (!GpeEventInfo)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
- {
- Status = AE_LIMIT; /* Too many references */
- goto UnlockAndExit;
- }
-
- GpeEventInfo->RuntimeCount++;
- if (GpeEventInfo->RuntimeCount == 1)
- {
- Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
- if (ACPI_SUCCESS (Status))
- {
- Status = AcpiEvEnableGpe (GpeEventInfo);
- }
- if (ACPI_FAILURE (Status))
- {
- GpeEventInfo->RuntimeCount--;
- }
- }
-
-UnlockAndExit:
- AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiDisableGpe
- *
- * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
- * GpeNumber - GPE level within the GPE block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Remove a reference to a GPE. When the last reference is
- * removed, only then is the GPE disabled (for runtime GPEs), or
- * the GPE mask bit disabled (for wake GPEs)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDisableGpe (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber)
-{
- ACPI_STATUS Status = AE_OK;
- ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_CPU_FLAGS Flags;
-
-
- ACPI_FUNCTION_TRACE (AcpiDisableGpe);
-
-
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-
- /* Ensure that we have a valid GPE number */
-
- GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
- if (!GpeEventInfo)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- /* Hardware-disable a runtime GPE on removal of the last reference */
-
- if (!GpeEventInfo->RuntimeCount)
- {
- Status = AE_LIMIT; /* There are no references to remove */
- goto UnlockAndExit;
- }
-
- GpeEventInfo->RuntimeCount--;
- if (!GpeEventInfo->RuntimeCount)
- {
- Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
- if (ACPI_SUCCESS (Status))
- {
- Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
- }
- if (ACPI_FAILURE (Status))
- {
- GpeEventInfo->RuntimeCount++;
- }
- }
-
-UnlockAndExit:
- AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiSetGpe
- *
- * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
- * GpeNumber - GPE level within the GPE block
- * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
- *
- * RETURN: Status
- *
- * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
- * the reference count mechanism used in the AcpiEnableGpe and
- * AcpiDisableGpe interfaces -- and should be used with care.
- *
- * Note: Typically used to disable a runtime GPE for short period of time,
- * then re-enable it, without disturbing the existing reference counts. This
- * is useful, for example, in the Embedded Controller (EC) driver.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiSetGpe (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- UINT8 Action)
-{
- ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_STATUS Status;
- ACPI_CPU_FLAGS Flags;
-
-
- ACPI_FUNCTION_TRACE (AcpiSetGpe);
-
-
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-
- /* Ensure that we have a valid GPE number */
-
- GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
- if (!GpeEventInfo)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- /* Perform the action */
-
- switch (Action)
- {
- case ACPI_GPE_ENABLE:
- Status = AcpiEvEnableGpe (GpeEventInfo);
- break;
-
- case ACPI_GPE_DISABLE:
- Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
- break;
-
- default:
- Status = AE_BAD_PARAMETER;
- break;
- }
-
-UnlockAndExit:
- AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiSetGpe)
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiDisableEvent
*
- * PARAMETERS: Event - The fixed eventto be enabled
+ * PARAMETERS: Event - The fixed event to be disabled
* Flags - Reserved
*
* RETURN: Status
@@ -695,53 +404,6 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent)
/*******************************************************************************
*
- * FUNCTION: AcpiClearGpe
- *
- * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
- * GpeNumber - GPE level within the GPE block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Clear an ACPI event (general purpose)
- *
- ******************************************************************************/
-
-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_EXPORT_SYMBOL (AcpiClearGpe)
-
-
-/*******************************************************************************
- *
* FUNCTION: AcpiGetEventStatus
*
* PARAMETERS: Event - The fixed event
@@ -788,400 +450,3 @@ AcpiGetEventStatus (
ACPI_EXPORT_SYMBOL (AcpiGetEventStatus)
-/*******************************************************************************
- *
- * FUNCTION: AcpiGetGpeStatus
- *
- * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
- * GpeNumber - GPE level within the GPE block
- * EventStatus - Where the current status of the event will
- * be returned
- *
- * RETURN: Status
- *
- * DESCRIPTION: Get status of an event (general purpose)
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiGetGpeStatus (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- ACPI_EVENT_STATUS *EventStatus)
-{
- ACPI_STATUS Status = AE_OK;
- ACPI_GPE_EVENT_INFO *GpeEventInfo;
- ACPI_CPU_FLAGS Flags;
-
-
- ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
-
-
- Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
-
- /* Ensure that we have a valid GPE number */
-
- GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
- if (!GpeEventInfo)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- /* Obtain status on the requested GPE number */
-
- Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
-
-UnlockAndExit:
- AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiInstallGpeBlock
- *
- * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
- * GpeBlockAddress - Address and SpaceID
- * RegisterCount - Number of GPE register pairs in the block
- * InterruptNumber - H/W interrupt for the block
- *
- * RETURN: Status
- *
- * DESCRIPTION: Create and Install a block of GPE registers
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiInstallGpeBlock (
- ACPI_HANDLE GpeDevice,
- ACPI_GENERIC_ADDRESS *GpeBlockAddress,
- UINT32 RegisterCount,
- UINT32 InterruptNumber)
-{
- ACPI_STATUS Status;
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_NAMESPACE_NODE *Node;
- ACPI_GPE_BLOCK_INFO *GpeBlock;
-
-
- ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
-
-
- if ((!GpeDevice) ||
- (!GpeBlockAddress) ||
- (!RegisterCount))
- {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- Node = AcpiNsValidateHandle (GpeDevice);
- if (!Node)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- /*
- * For user-installed GPE Block Devices, the GpeBlockBaseNumber
- * is always zero
- */
- Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
- 0, InterruptNumber, &GpeBlock);
- if (ACPI_FAILURE (Status))
- {
- goto UnlockAndExit;
- }
-
- /* Install block in the DeviceObject attached to the node */
-
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (!ObjDesc)
- {
- /*
- * No object, create a new one (Device nodes do not always have
- * an attached object)
- */
- ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
- if (!ObjDesc)
- {
- Status = AE_NO_MEMORY;
- goto UnlockAndExit;
- }
-
- Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
-
- /* Remove local reference to the object */
-
- AcpiUtRemoveReference (ObjDesc);
- if (ACPI_FAILURE (Status))
- {
- goto UnlockAndExit;
- }
- }
-
- /* Now install the GPE block in the DeviceObject */
-
- ObjDesc->Device.GpeBlock = GpeBlock;
-
- /* Run the _PRW methods and enable the runtime GPEs in the new block */
-
- Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
-
-
-UnlockAndExit:
- (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiRemoveGpeBlock
- *
- * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
- *
- * RETURN: Status
- *
- * DESCRIPTION: Remove a previously installed block of GPE registers
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiRemoveGpeBlock (
- ACPI_HANDLE GpeDevice)
-{
- ACPI_OPERAND_OBJECT *ObjDesc;
- ACPI_STATUS Status;
- ACPI_NAMESPACE_NODE *Node;
-
-
- ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
-
-
- if (!GpeDevice)
- {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
-
- Node = AcpiNsValidateHandle (GpeDevice);
- if (!Node)
- {
- Status = AE_BAD_PARAMETER;
- goto UnlockAndExit;
- }
-
- /* Get the DeviceObject attached to the node */
-
- ObjDesc = AcpiNsGetAttachedObject (Node);
- if (!ObjDesc ||
- !ObjDesc->Device.GpeBlock)
- {
- return_ACPI_STATUS (AE_NULL_OBJECT);
- }
-
- /* Delete the GPE block (but not the DeviceObject) */
-
- Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
- if (ACPI_SUCCESS (Status))
- {
- ObjDesc->Device.GpeBlock = NULL;
- }
-
-UnlockAndExit:
- (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
- return_ACPI_STATUS (Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiGetGpeDevice
- *
- * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
- * GpeDevice - Where the parent GPE Device is returned
- *
- * RETURN: Status
- *
- * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
- * gpe device indicates that the gpe number is contained in one of
- * the FADT-defined gpe blocks. Otherwise, the GPE block device.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiGetGpeDevice (
- UINT32 Index,
- ACPI_HANDLE *GpeDevice)
-{
- ACPI_GPE_DEVICE_INFO Info;
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
-
-
- if (!GpeDevice)
- {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- if (Index >= AcpiCurrentGpeCount)
- {
- return_ACPI_STATUS (AE_NOT_EXIST);
- }
-
- /* Setup and walk the GPE list */
-
- Info.Index = Index;
- Info.Status = AE_NOT_EXIST;
- Info.GpeDevice = NULL;
- Info.NextBlockBaseIndex = 0;
-
- Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
- return_ACPI_STATUS (Info.Status);
-}
-
-ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiEvGetGpeDevice
- *
- * PARAMETERS: GPE_WALK_CALLBACK
- *
- * RETURN: Status
- *
- * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE
- * block device. NULL if the GPE is one of the FADT-defined GPEs.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiEvGetGpeDevice (
- ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
- ACPI_GPE_BLOCK_INFO *GpeBlock,
- void *Context)
-{
- ACPI_GPE_DEVICE_INFO *Info = Context;
-
-
- /* Increment Index by the number of GPEs in this block */
-
- Info->NextBlockBaseIndex += GpeBlock->GpeCount;
-
- if (Info->Index < Info->NextBlockBaseIndex)
- {
- /*
- * The GPE index is within this block, get the node. Leave the node
- * NULL for the FADT-defined GPEs
- */
- if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
- {
- Info->GpeDevice = GpeBlock->Node;
- }
-
- Info->Status = AE_OK;
- return (AE_CTRL_END);
- }
-
- return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: AcpiDisableAllGpes
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiDisableAllGpes (
- void)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
-
-
- Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- Status = AcpiHwDisableAllGpes ();
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
-
- return_ACPI_STATUS (Status);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION: AcpiEnableAllRuntimeGpes
- *
- * PARAMETERS: None
- *
- * RETURN: Status
- *
- * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiEnableAllRuntimeGpes (
- void)
-{
- ACPI_STATUS Status;
-
-
- ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
-
-
- Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- Status = AcpiHwEnableAllRuntimeGpes ();
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
-
- return_ACPI_STATUS (Status);
-}
-
-
diff --git a/events/evxfgpe.c b/events/evxfgpe.c
new file mode 100644
index 0000000..39f1e5d
--- /dev/null
+++ b/events/evxfgpe.c
@@ -0,0 +1,962 @@
+/******************************************************************************
+ *
+ * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ *
+ * 1. Copyright Notice
+ *
+ * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
+ * All rights reserved.
+ *
+ * 2. License
+ *
+ * 2.1. This is your license from Intel Corp. under its intellectual property
+ * rights. You may have additional license terms from the party that provided
+ * you this software, covering your right to use that party's intellectual
+ * property rights.
+ *
+ * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
+ * copy of the source code appearing in this file ("Covered Code") an
+ * irrevocable, perpetual, worldwide license under Intel's copyrights in the
+ * base code distributed originally by Intel ("Original Intel Code") to copy,
+ * make derivatives, distribute, use and display any portion of the Covered
+ * Code in any form, with the right to sublicense such rights; and
+ *
+ * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
+ * license (with the right to sublicense), under only those claims of Intel
+ * patents that are infringed by the Original Intel Code, to make, use, sell,
+ * offer to sell, and import the Covered Code and derivative works thereof
+ * solely to the minimum extent necessary to exercise the above copyright
+ * license, and in no event shall the patent license extend to any additions
+ * to or modifications of the Original Intel Code. No other license or right
+ * is granted directly or by implication, estoppel or otherwise;
+ *
+ * The above copyright and patent license is granted only if the following
+ * conditions are met:
+ *
+ * 3. Conditions
+ *
+ * 3.1. Redistribution of Source with Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification with rights to further distribute source must include
+ * the above Copyright Notice, the above License, this list of Conditions,
+ * and the following Disclaimer and Export Compliance provision. In addition,
+ * Licensee must cause all Covered Code to which Licensee contributes to
+ * contain a file documenting the changes Licensee made to create that Covered
+ * Code and the date of any change. Licensee must include in that file the
+ * documentation of any changes made by any predecessor Licensee. Licensee
+ * must include a prominent statement that the modification is derived,
+ * directly or indirectly, from Original Intel Code.
+ *
+ * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
+ * Redistribution of source code of any substantial portion of the Covered
+ * Code or modification without rights to further distribute source must
+ * include the following Disclaimer and Export Compliance provision in the
+ * documentation and/or other materials provided with distribution. In
+ * addition, Licensee may not authorize further sublicense of source of any
+ * portion of the Covered Code, and must include terms to the effect that the
+ * license from Licensee to its licensee is limited to the intellectual
+ * property embodied in the software Licensee provides to its licensee, and
+ * not to intellectual property embodied in modifications its licensee may
+ * make.
+ *
+ * 3.3. Redistribution of Executable. Redistribution in executable form of any
+ * substantial portion of the Covered Code or modification must reproduce the
+ * above Copyright Notice, and the following Disclaimer and Export Compliance
+ * provision in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3.4. Intel retains all right, title, and interest in and to the Original
+ * Intel Code.
+ *
+ * 3.5. Neither the name Intel nor any other trademark owned or controlled by
+ * Intel shall be used in advertising or otherwise to promote the sale, use or
+ * other dealings in products derived from or relating to the Covered Code
+ * without prior written authorization from Intel.
+ *
+ * 4. Disclaimer and Export Compliance
+ *
+ * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
+ * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
+ * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
+ * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
+ * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
+ * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
+ * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
+ * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
+ * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
+ * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
+ * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
+ * LIMITED REMEDY.
+ *
+ * 4.3. Licensee shall not export, either directly or indirectly, any of this
+ * software or system incorporating such software without first obtaining any
+ * required license or other approval from the U. S. Department of Commerce or
+ * any other agency or department of the United States Government. In the
+ * event Licensee exports any such software from the United States or
+ * re-exports any such software from a foreign destination, Licensee shall
+ * ensure that the distribution and export/re-export of the software is in
+ * compliance with all laws, regulations, orders, or other restrictions of the
+ * U.S. Export Administration Regulations. Licensee agrees that neither it nor
+ * any of its subsidiaries will export/re-export any technical data, process,
+ * software, or service, directly or indirectly, to any country for which the
+ * United States government or any agency thereof requires an export license,
+ * other governmental approval, or letter of assurance, without first obtaining
+ * such license, approval or letter.
+ *
+ *****************************************************************************/
+
+
+#define __EVXFGPE_C__
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acevents.h"
+#include "acnamesp.h"
+
+#define _COMPONENT ACPI_EVENTS
+ ACPI_MODULE_NAME ("evxfgpe")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiUpdateAllGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
+ * associated _Lxx or _Exx methods and are not pointed to by any
+ * device _PRW methods (this indicates that these GPEs are
+ * generally intended for system or device wakeup. Such GPEs
+ * have to be enabled directly when the devices whose _PRW
+ * methods point to them are set up for wakeup signaling.)
+ *
+ * NOTE: Should be called after any GPEs are added to the system. Primarily,
+ * after the system _PRW methods have been run, but also after a GPE Block
+ * Device has been added or if any new GPE methods have been added via a
+ * dynamic table load.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiUpdateAllGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiUpdateGpes);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (AcpiGbl_AllGpesInitialized)
+ {
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL);
+ if (ACPI_SUCCESS (Status))
+ {
+ AcpiGbl_AllGpesInitialized = TRUE;
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiEnableGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
+ * hardware-enabled.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (GpeEventInfo)
+ {
+ Status = AcpiEvAddGpeReference (GpeEventInfo);
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDisableGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a reference to a GPE. When the last reference is
+ * removed, only then is the GPE disabled (for runtime GPEs), or
+ * the GPE mask bit disabled (for wake GPEs)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDisableGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (GpeEventInfo)
+ {
+ Status = AcpiEvRemoveGpeReference (GpeEventInfo);
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
+ * the reference count mechanism used in the AcpiEnableGpe and
+ * AcpiDisableGpe interfaces -- and should be used with care.
+ *
+ * Note: Typically used to disable a runtime GPE for short period of time,
+ * then re-enable it, without disturbing the existing reference counts. This
+ * is useful, for example, in the Embedded Controller (EC) driver.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT8 Action)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiSetGpe);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Perform the action */
+
+ switch (Action)
+ {
+ case ACPI_GPE_ENABLE:
+ Status = AcpiEvEnableGpe (GpeEventInfo);
+ break;
+
+ case ACPI_GPE_DISABLE:
+ Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
+ break;
+
+ default:
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetupGpeForWake
+ *
+ * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW)
+ * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
+ * interface is intended to be used as the host executes the
+ * _PRW methods (Power Resources for Wake) in the system tables.
+ * Each _PRW appears under a Device Object (The WakeDevice), and
+ * contains the info for the wake GPE associated with the
+ * WakeDevice.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetupGpeForWake (
+ ACPI_HANDLE WakeDevice,
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_NAMESPACE_NODE *DeviceNode;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
+
+
+ /* Parameter Validation */
+
+ if (!WakeDevice)
+ {
+ /*
+ * By forcing WakeDevice to be valid, we automatically enable the
+ * implicit notify feature on all hosts.
+ */
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /* Validate WakeDevice is of type Device */
+
+ DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
+ if (DeviceNode->Type != ACPI_TYPE_DEVICE)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (GpeEventInfo)
+ {
+ /*
+ * If there is no method or handler for this GPE, then the
+ * WakeDevice will be notified whenever this GPE fires (aka
+ * "implicit notify") Note: The GPE is assumed to be
+ * level-triggered (for windows compatibility).
+ */
+ if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
+ ACPI_GPE_DISPATCH_NONE)
+ {
+ GpeEventInfo->Flags =
+ (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
+ GpeEventInfo->Dispatch.DeviceNode = DeviceNode;
+ }
+
+ GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
+ Status = AE_OK;
+ }
+
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiSetGpeWakeMask
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ * Action - Enable or Disable
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
+ * already be marked as a WAKE GPE.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetGpeWakeMask (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT8 Action)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
+ ACPI_CPU_FLAGS Flags;
+ UINT32 RegisterBit;
+
+
+ ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /*
+ * Ensure that we have a valid GPE number and that this GPE is in
+ * fact a wake GPE
+ */
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
+ {
+ Status = AE_TYPE;
+ goto UnlockAndExit;
+ }
+
+ GpeRegisterInfo = GpeEventInfo->RegisterInfo;
+ if (!GpeRegisterInfo)
+ {
+ Status = AE_NOT_EXIST;
+ goto UnlockAndExit;
+ }
+
+ RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
+
+ /* Perform the action */
+
+ switch (Action)
+ {
+ case ACPI_GPE_ENABLE:
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
+ break;
+
+ case ACPI_GPE_DISABLE:
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
+ break;
+
+ default:
+ ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
+ Status = AE_BAD_PARAMETER;
+ break;
+ }
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiClearGpe
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+
+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_EXPORT_SYMBOL (AcpiClearGpe)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetGpeStatus
+ *
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
+ * GpeNumber - GPE level within the GPE block
+ * EventStatus - Where the current status of the event
+ * will be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetGpeStatus (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ ACPI_EVENT_STATUS *EventStatus)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
+
+
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
+
+ /* Ensure that we have a valid GPE number */
+
+ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
+ if (!GpeEventInfo)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Obtain status on the requested GPE number */
+
+ Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiFinishGpe
+ *
+ * PARAMETERS: GpeDevice - Namespace node for the GPE Block
+ * (NULL for FADT defined GPEs)
+ * GpeNumber - GPE level within the GPE block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
+ * processing. Intended for use by asynchronous host-installed
+ * GPE handlers. The GPE is only reenabled if the EnableForRun bit
+ * is set in the GPE info.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiFinishGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber)
+{
+ ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiFinishGpe);
+
+
+ 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 = AcpiEvFinishGpe (GpeEventInfo);
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiDisableAllGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableAllGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiHwDisableAllGpes ();
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiEnableAllRuntimeGpes
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableAllRuntimeGpes (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ Status = AcpiHwEnableAllRuntimeGpes ();
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallGpeBlock
+ *
+ * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
+ * GpeBlockAddress - Address and SpaceID
+ * RegisterCount - Number of GPE register pairs in the block
+ * InterruptNumber - H/W interrupt for the block
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
+ * enabled here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallGpeBlock (
+ ACPI_HANDLE GpeDevice,
+ ACPI_GENERIC_ADDRESS *GpeBlockAddress,
+ UINT32 RegisterCount,
+ UINT32 InterruptNumber)
+{
+ ACPI_STATUS Status;
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_GPE_BLOCK_INFO *GpeBlock;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
+
+
+ if ((!GpeDevice) ||
+ (!GpeBlockAddress) ||
+ (!RegisterCount))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Node = AcpiNsValidateHandle (GpeDevice);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * For user-installed GPE Block Devices, the GpeBlockBaseNumber
+ * is always zero
+ */
+ Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount,
+ 0, InterruptNumber, &GpeBlock);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+
+ /* Install block in the DeviceObject attached to the node */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc)
+ {
+ /*
+ * No object, create a new one (Device nodes do not always have
+ * an attached object)
+ */
+ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
+ if (!ObjDesc)
+ {
+ Status = AE_NO_MEMORY;
+ goto UnlockAndExit;
+ }
+
+ Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
+
+ /* Remove local reference to the object */
+
+ AcpiUtRemoveReference (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ goto UnlockAndExit;
+ }
+ }
+
+ /* Now install the GPE block in the DeviceObject */
+
+ ObjDesc->Device.GpeBlock = GpeBlock;
+
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveGpeBlock
+ *
+ * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a previously installed block of GPE registers
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveGpeBlock (
+ ACPI_HANDLE GpeDevice)
+{
+ ACPI_OPERAND_OBJECT *ObjDesc;
+ ACPI_STATUS Status;
+ ACPI_NAMESPACE_NODE *Node;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
+
+
+ if (!GpeDevice)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ Node = AcpiNsValidateHandle (GpeDevice);
+ if (!Node)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
+ }
+
+ /* Get the DeviceObject attached to the node */
+
+ ObjDesc = AcpiNsGetAttachedObject (Node);
+ if (!ObjDesc ||
+ !ObjDesc->Device.GpeBlock)
+ {
+ return_ACPI_STATUS (AE_NULL_OBJECT);
+ }
+
+ /* Delete the GPE block (but not the DeviceObject) */
+
+ Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
+ if (ACPI_SUCCESS (Status))
+ {
+ ObjDesc->Device.GpeBlock = NULL;
+ }
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetGpeDevice
+ *
+ * PARAMETERS: Index - System GPE index (0-CurrentGpeCount)
+ * GpeDevice - Where the parent GPE Device is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
+ * gpe device indicates that the gpe number is contained in one of
+ * the FADT-defined gpe blocks. Otherwise, the GPE block device.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetGpeDevice (
+ UINT32 Index,
+ ACPI_HANDLE *GpeDevice)
+{
+ ACPI_GPE_DEVICE_INFO Info;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
+
+
+ if (!GpeDevice)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (Index >= AcpiCurrentGpeCount)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Setup and walk the GPE list */
+
+ Info.Index = Index;
+ Info.Status = AE_NOT_EXIST;
+ Info.GpeDevice = NULL;
+ Info.NextBlockBaseIndex = 0;
+
+ Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
+ return_ACPI_STATUS (Info.Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
diff --git a/executer/exconfig.c b/executer/exconfig.c
index ab2be8a..958603f 100644
--- a/executer/exconfig.c
+++ b/executer/exconfig.c
@@ -206,8 +206,11 @@ AcpiExAddTable (
AcpiNsExecModuleCodeList ();
AcpiExEnterInterpreter ();
- /* Update GPEs for any new _PRW or _Lxx/_Exx methods. Ignore errors */
-
+ /*
+ * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
+ * responsible for discovering any new wake GPEs by running _PRW methods
+ * that may have been loaded by this table.
+ */
Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
if (ACPI_SUCCESS (Status))
{
diff --git a/include/acdebug.h b/include/acdebug.h
index 7103e4f..50d88ce 100644
--- a/include/acdebug.h
+++ b/include/acdebug.h
@@ -117,7 +117,7 @@
#define __ACDEBUG_H__
-#define ACPI_DEBUG_BUFFER_SIZE 4196
+#define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */
typedef struct CommandInfo
{
diff --git a/include/acdisasm.h b/include/acdisasm.h
index 7e7cea0..8c90a9b 100644
--- a/include/acdisasm.h
+++ b/include/acdisasm.h
@@ -189,6 +189,7 @@ typedef const struct acpi_dmtable_info
#define ACPI_DMT_EINJINST 38
#define ACPI_DMT_ERSTACT 39
#define ACPI_DMT_ERSTINST 40
+#define ACPI_DMT_ACCWIDTH 41
typedef
diff --git a/include/acevents.h b/include/acevents.h
index c03e9e3..fe25ab2 100644
--- a/include/acevents.h
+++ b/include/acevents.h
@@ -128,10 +128,6 @@ ACPI_STATUS
AcpiEvInstallXruptHandlers (
void);
-ACPI_STATUS
-AcpiEvInstallFadtGpes (
- void);
-
UINT32
AcpiEvFixedEventDetect (
void);
@@ -181,6 +177,14 @@ ACPI_STATUS
AcpiEvEnableGpe (
ACPI_GPE_EVENT_INFO *GpeEventInfo);
+ACPI_STATUS
+AcpiEvAddGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
+ACPI_STATUS
+AcpiEvRemoveGpeReference (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
ACPI_GPE_EVENT_INFO *
AcpiEvGetGpeEventInfo (
ACPI_HANDLE GpeDevice,
@@ -191,6 +195,10 @@ AcpiEvLowGetGpeInfo (
UINT32 GpeNumber,
ACPI_GPE_BLOCK_INFO *GpeBlock);
+ACPI_STATUS
+AcpiEvFinishGpe (
+ ACPI_GPE_EVENT_INFO *GpeEventInfo);
+
/*
* evgpeblk - Upper-level GPE block support
@@ -206,8 +214,9 @@ AcpiEvCreateGpeBlock (
ACPI_STATUS
AcpiEvInitializeGpeBlock (
- ACPI_NAMESPACE_NODE *GpeDevice,
- ACPI_GPE_BLOCK_INFO *GpeBlock);
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
ACPI_STATUS
AcpiEvDeleteGpeBlock (
@@ -215,6 +224,7 @@ AcpiEvDeleteGpeBlock (
UINT32
AcpiEvGpeDispatch (
+ ACPI_NAMESPACE_NODE *GpeDevice,
ACPI_GPE_EVENT_INFO *GpeEventInfo,
UINT32 GpeNumber);
@@ -236,13 +246,6 @@ AcpiEvMatchGpeMethod (
void *Context,
void **ReturnValue);
-ACPI_STATUS
-AcpiEvMatchPrwAndGpe (
- ACPI_HANDLE ObjHandle,
- UINT32 Level,
- void *Context,
- void **ReturnValue);
-
/*
* evgpeutil - GPE utilities
*/
@@ -255,6 +258,12 @@ BOOLEAN
AcpiEvValidGpeEvent (
ACPI_GPE_EVENT_INFO *GpeEventInfo);
+ACPI_STATUS
+AcpiEvGetGpeDevice (
+ ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
+ ACPI_GPE_BLOCK_INFO *GpeBlock,
+ void *Context);
+
ACPI_GPE_XRUPT_INFO *
AcpiEvGetGpeXruptBlock (
UINT32 InterruptNumber);
diff --git a/include/acglobal.h b/include/acglobal.h
index 2e158fb..68cb077 100644
--- a/include/acglobal.h
+++ b/include/acglobal.h
@@ -174,13 +174,6 @@ UINT8 ACPI_INIT_GLOBAL (AcpiGbl_AllMethodsSerialized, FALSE);
UINT8 ACPI_INIT_GLOBAL (AcpiGbl_CreateOsiMethod, TRUE);
/*
- * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and
- * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only
- * be enabled just before going to sleep.
- */
-UINT8 ACPI_INIT_GLOBAL (AcpiGbl_LeaveWakeGpesDisabled, TRUE);
-
-/*
* Optionally use default values for the ACPI register widths. Set this to
* TRUE to use the defaults, if an FADT contains incorrect widths/lengths.
*/
@@ -434,10 +427,13 @@ ACPI_EXTERN UINT8 AcpiGbl_SleepTypeB;
*
****************************************************************************/
-extern ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS];
-ACPI_EXTERN ACPI_FIXED_EVENT_HANDLER AcpiGbl_FixedEventHandlers[ACPI_NUM_FIXED_EVENTS];
+ACPI_EXTERN UINT8 AcpiGbl_AllGpesInitialized;
ACPI_EXTERN ACPI_GPE_XRUPT_INFO *AcpiGbl_GpeXruptListHead;
ACPI_EXTERN ACPI_GPE_BLOCK_INFO *AcpiGbl_GpeFadtBlocks[ACPI_MAX_GPE_BLOCKS];
+ACPI_EXTERN ACPI_GBL_EVENT_HANDLER AcpiGbl_GlobalEventHandler;
+ACPI_EXTERN void *AcpiGbl_GlobalEventHandlerContext;
+ACPI_EXTERN ACPI_FIXED_EVENT_HANDLER AcpiGbl_FixedEventHandlers[ACPI_NUM_FIXED_EVENTS];
+extern ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS];
/*****************************************************************************
diff --git a/include/aclocal.h b/include/aclocal.h
index 062972f..2c755f6 100644
--- a/include/aclocal.h
+++ b/include/aclocal.h
@@ -537,18 +537,25 @@ typedef struct acpi_predefined_data
/* Dispatch info for each GPE -- either a method or handler, cannot be both */
-typedef struct acpi_handler_info
+typedef struct acpi_gpe_handler_info
{
- ACPI_EVENT_HANDLER Address; /* Address of handler, if any */
+ ACPI_GPE_HANDLER Address; /* Address of handler, if any */
void *Context; /* Context to be passed to handler */
ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level (saved) */
+ UINT8 OriginalFlags; /* Original (pre-handler) GPE info */
+ BOOLEAN OriginallyEnabled; /* True if GPE was originally enabled */
-} ACPI_HANDLER_INFO;
+} ACPI_GPE_HANDLER_INFO;
+/*
+ * GPE dispatch info. At any time, the GPE can have at most one type
+ * of dispatch - Method, Handler, or Implicit Notify.
+ */
typedef union acpi_gpe_dispatch_info
{
ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level */
- struct acpi_handler_info *Handler;
+ struct acpi_gpe_handler_info *Handler; /* Installed GPE handler */
+ ACPI_NAMESPACE_NODE *DeviceNode; /* Parent _PRW device for implicit notify */
} ACPI_GPE_DISPATCH_INFO;
@@ -594,6 +601,7 @@ typedef struct acpi_gpe_block_info
UINT32 RegisterCount; /* Number of register pairs in block */
UINT16 GpeCount; /* Number of individual GPEs in block */
UINT8 BlockBaseNumber;/* Base GPE number for this block */
+ BOOLEAN Initialized; /* TRUE if this block is initialized */
} ACPI_GPE_BLOCK_INFO;
@@ -614,7 +622,6 @@ typedef struct acpi_gpe_walk_info
ACPI_GPE_BLOCK_INFO *GpeBlock;
UINT16 Count;
ACPI_OWNER_ID OwnerId;
- BOOLEAN EnableThisGpe;
BOOLEAN ExecuteByOwnerId;
} ACPI_GPE_WALK_INFO;
diff --git a/include/acpixf.h b/include/acpixf.h
index e2f310d..cbe0524 100644
--- a/include/acpixf.h
+++ b/include/acpixf.h
@@ -120,7 +120,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
-#define ACPI_CA_VERSION 0x20101013
+#define ACPI_CA_VERSION 0x20101209
#include "actypes.h"
#include "actbl.h"
@@ -142,7 +142,6 @@ extern UINT32 AcpiDbgLayer;
extern UINT8 AcpiGbl_EnableInterpreterSlack;
extern UINT8 AcpiGbl_AllMethodsSerialized;
extern UINT8 AcpiGbl_CreateOsiMethod;
-extern UINT8 AcpiGbl_LeaveWakeGpesDisabled;
extern UINT8 AcpiGbl_UseDefaultRegisterWidths;
extern ACPI_NAME AcpiGbl_TraceMethodName;
extern UINT32 AcpiGbl_TraceFlags;
@@ -152,7 +151,7 @@ extern UINT8 AcpiGbl_TruncateIoAddresses;
/*
- * Global interfaces
+ * Initialization
*/
ACPI_STATUS
AcpiInitializeTables (
@@ -176,10 +175,10 @@ ACPI_STATUS
AcpiTerminate (
void);
-ACPI_STATUS
-AcpiSubsystemStatus (
- void);
+/*
+ * Miscellaneous global interfaces
+ */
ACPI_STATUS
AcpiEnable (
void);
@@ -189,6 +188,10 @@ AcpiDisable (
void);
ACPI_STATUS
+AcpiSubsystemStatus (
+ void);
+
+ACPI_STATUS
AcpiGetSystemInfo (
ACPI_BUFFER *RetBuffer);
@@ -212,6 +215,7 @@ ACPI_STATUS
AcpiRemoveInterface (
ACPI_STRING InterfaceName);
+
/*
* ACPI Memory management
*/
@@ -381,6 +385,11 @@ AcpiInstallInitializationHandler (
UINT32 Function);
ACPI_STATUS
+AcpiInstallGlobalEventHandler (
+ ACPI_GBL_EVENT_HANDLER Handler,
+ void *Context);
+
+ACPI_STATUS
AcpiInstallFixedEventHandler (
UINT32 AcpiEvent,
ACPI_EVENT_HANDLER Handler,
@@ -392,6 +401,20 @@ AcpiRemoveFixedEventHandler (
ACPI_EVENT_HANDLER Handler);
ACPI_STATUS
+AcpiInstallGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT32 Type,
+ ACPI_GPE_HANDLER Address,
+ void *Context);
+
+ACPI_STATUS
+AcpiRemoveGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ ACPI_GPE_HANDLER Address);
+
+ACPI_STATUS
AcpiInstallNotifyHandler (
ACPI_HANDLE Device,
UINT32 HandlerType,
@@ -419,20 +442,6 @@ AcpiRemoveAddressSpaceHandler (
ACPI_ADR_SPACE_HANDLER Handler);
ACPI_STATUS
-AcpiInstallGpeHandler (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- UINT32 Type,
- ACPI_EVENT_HANDLER Address,
- void *Context);
-
-ACPI_STATUS
-AcpiRemoveGpeHandler (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- ACPI_EVENT_HANDLER Address);
-
-ACPI_STATUS
AcpiInstallExceptionHandler (
ACPI_EXCEPTION_HANDLER Handler);
@@ -442,7 +451,7 @@ AcpiInstallInterfaceHandler (
/*
- * Event interfaces
+ * Global Lock interfaces
*/
ACPI_STATUS
AcpiAcquireGlobalLock (
@@ -453,6 +462,10 @@ ACPI_STATUS
AcpiReleaseGlobalLock (
UINT32 Handle);
+
+/*
+ * Fixed Event interfaces
+ */
ACPI_STATUS
AcpiEnableEvent (
UINT32 Event,
@@ -474,13 +487,11 @@ AcpiGetEventStatus (
/*
- * GPE Interfaces
+ * General Purpose Event (GPE) Interfaces
*/
ACPI_STATUS
-AcpiSetGpe (
- ACPI_HANDLE GpeDevice,
- UINT32 GpeNumber,
- UINT8 Action);
+AcpiUpdateAllGpes (
+ void);
ACPI_STATUS
AcpiEnableGpe (
@@ -498,7 +509,24 @@ AcpiClearGpe (
UINT32 GpeNumber);
ACPI_STATUS
-AcpiGpeWakeup (
+AcpiSetGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ UINT8 Action);
+
+ACPI_STATUS
+AcpiFinishGpe (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber);
+
+ACPI_STATUS
+AcpiSetupGpeForWake (
+ ACPI_HANDLE ParentDevice,
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber);
+
+ACPI_STATUS
+AcpiSetGpeWakeMask (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT8 Action);
diff --git a/include/actypes.h b/include/actypes.h
index e4290ae..3a37da0 100644
--- a/include/actypes.h
+++ b/include/actypes.h
@@ -738,25 +738,26 @@ typedef UINT32 ACPI_EVENT_STATUS;
/*
* GPE info flags - Per GPE
- * +-------+---+-+-+
- * | 7:4 |3:2|1|0|
- * +-------+---+-+-+
- * | | | |
- * | | | +--- Interrupt type: edge or level triggered
- * | | +----- GPE can wake the system
- * | +-------- Type of dispatch:to method, handler, or none
- * +-------------- <Reserved>
+ * +-------+-+-+---+
+ * | 7:4 |3|2|1:0|
+ * +-------+-+-+---+
+ * | | | |
+ * | | | +-- Type of dispatch:to method, handler, notify, or none
+ * | | +----- Interrupt type: edge or level triggered
+ * | +------- Is a Wake GPE
+ * +------------ <Reserved>
*/
-#define ACPI_GPE_XRUPT_TYPE_MASK (UINT8) 0x01
-#define ACPI_GPE_LEVEL_TRIGGERED (UINT8) 0x01
-#define ACPI_GPE_EDGE_TRIGGERED (UINT8) 0x00
+#define ACPI_GPE_DISPATCH_NONE (UINT8) 0x00
+#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x01
+#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x02
+#define ACPI_GPE_DISPATCH_NOTIFY (UINT8) 0x03
+#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x03
-#define ACPI_GPE_CAN_WAKE (UINT8) 0x02
+#define ACPI_GPE_LEVEL_TRIGGERED (UINT8) 0x04
+#define ACPI_GPE_EDGE_TRIGGERED (UINT8) 0x00
+#define ACPI_GPE_XRUPT_TYPE_MASK (UINT8) 0x04
-#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x0C
-#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x04
-#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x08
-#define ACPI_GPE_DISPATCH_NOT_USED (UINT8) 0x00
+#define ACPI_GPE_CAN_WAKE (UINT8) 0x08
/*
* Flags for GPE and Lock interfaces
@@ -1015,10 +1016,26 @@ typedef void
* Various handlers and callback procedures
*/
typedef
+void (*ACPI_GBL_EVENT_HANDLER) (
+ UINT32 EventType,
+ ACPI_HANDLE Device,
+ UINT32 EventNumber,
+ void *Context);
+
+#define ACPI_EVENT_TYPE_GPE 0
+#define ACPI_EVENT_TYPE_FIXED 1
+
+typedef
UINT32 (*ACPI_EVENT_HANDLER) (
void *Context);
typedef
+UINT32 (*ACPI_GPE_HANDLER) (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ void *Context);
+
+typedef
void (*ACPI_NOTIFY_HANDLER) (
ACPI_HANDLE Device,
UINT32 Value,
@@ -1098,6 +1115,11 @@ UINT32 (*ACPI_INTERFACE_HANDLER) (
#define ACPI_INTERRUPT_NOT_HANDLED 0x00
#define ACPI_INTERRUPT_HANDLED 0x01
+/* GPE handler return values */
+
+#define ACPI_REENABLE_GPE 0x80
+
+
/* Length of 32-bit EISAID values when converted back to a string */
#define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */
diff --git a/tests/misc/badcode.asl b/tests/misc/badcode.asl
index 1230ec0..9b576c5 100644
--- a/tests/misc/badcode.asl
+++ b/tests/misc/badcode.asl
@@ -132,7 +132,16 @@ DefinitionBlock ("badcode.aml", "DSDT", 1, "Intel", "Example", 0x00000001)
}
Device (H4)
{
- Name (_HID, "acpi0001") // non-hex chars must be uppercase
+ Name (_HID, "acpi0001") // non-hex chars must be uppercase
+ }
+ Device (H5)
+ {
+ Name (_HID, "PNP-123") // HID must be alphanumeric
+ }
+ Device (H6)
+ {
+ Name (_HID, "") // Illegal Null HID
+ Name (_CID, "") // Illegal Null CID
}
// Predefined Name typechecking
diff --git a/tools/acpiexec/Makefile b/tools/acpiexec/Makefile
index 640d992..827a418 100644
--- a/tools/acpiexec/Makefile
+++ b/tools/acpiexec/Makefile
@@ -61,6 +61,7 @@ OBJS = \
evsci.o \
evxface.o \
evxfevnt.o \
+ evxfgpe.o \
evxfregn.o \
exconfig.o \
exconvrt.o \
@@ -317,6 +318,9 @@ evxface.o : $(ACPICA_CORE)/events/evxface.c
evxfevnt.o : $(ACPICA_CORE)/events/evxfevnt.c
$(COMPILE)
+evxfgpe.o : $(ACPICA_CORE)/events/evxfgpe.c
+ $(COMPILE)
+
evxfregn.o : $(ACPICA_CORE)/events/evxfregn.c
$(COMPILE)
diff --git a/tools/acpiexec/aecommon.h b/tools/acpiexec/aecommon.h
index 3b7d36d..ce13410 100644
--- a/tools/acpiexec/aecommon.h
+++ b/tools/acpiexec/aecommon.h
@@ -250,6 +250,15 @@ AeRegionHandler (
UINT32
AeGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
+ void *Context);
+
+void
+AeGlobalEventHandler (
+ UINT32 Type,
+ ACPI_HANDLE GpeDevice,
+ UINT32 EventNumber,
void *Context);
#endif /* _AECOMMON */
diff --git a/tools/acpiexec/aeexec.c b/tools/acpiexec/aeexec.c
index baf1aeb..b90ecae 100644
--- a/tools/acpiexec/aeexec.c
+++ b/tools/acpiexec/aeexec.c
@@ -586,6 +586,9 @@ AeMiscellaneousTests (
Status = AcpiEnableEvent (ACPI_EVENT_GLOBAL, 0);
AE_CHECK_OK (AcpiEnableEvent, Status);
+ Status = AcpiInstallGlobalEventHandler (AeGlobalEventHandler, NULL);
+ AE_CHECK_OK (AcpiInstallGlobalEventHandler, Status);
+
/*
* GPEs: Handlers, enable/disable, etc.
*/
@@ -634,6 +637,20 @@ AeMiscellaneousTests (
Status = AcpiInstallGpeHandler (NULL, 5, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL);
AE_CHECK_OK (AcpiInstallGpeHandler, Status);
+ Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
+ AE_CHECK_OK (AcpiGetHandle, Status);
+
+ Status = AcpiSetupGpeForWake (Handle, NULL, 5);
+ AE_CHECK_OK (AcpiSetupGpeForWake, Status);
+
+ Status = AcpiSetGpeWakeMask (NULL, 5, ACPI_GPE_ENABLE);
+ AE_CHECK_OK (AcpiGpeWakeup, Status);
+
+ Status = AcpiSetupGpeForWake (Handle, NULL, 6);
+ AE_CHECK_OK (AcpiSetupGpeForWake, Status);
+
+ Status = AcpiSetupGpeForWake (Handle, NULL, 9);
+ AE_CHECK_OK (AcpiSetupGpeForWake, Status);
Status = AcpiInstallGpeHandler (NULL, 0x19, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL);
AE_CHECK_OK (AcpiInstallGpeHandler, Status);
@@ -653,6 +670,10 @@ AeMiscellaneousTests (
AfInstallGpeBlock ();
+ /* Here is where the GPEs are actually "enabled" */
+
+ Status = AcpiUpdateAllGpes ();
+ AE_CHECK_OK (AcpiUpdateAllGpes, Status);
Status = AcpiGetHandle (NULL, "RSRC", &Handle);
if (ACPI_SUCCESS (Status))
diff --git a/tools/acpiexec/aehandlers.c b/tools/acpiexec/aehandlers.c
index 1f9b1f6..da57140 100644
--- a/tools/acpiexec/aehandlers.c
+++ b/tools/acpiexec/aehandlers.c
@@ -428,13 +428,18 @@ AeTableHandler (
void *Table,
void *Context)
{
+ ACPI_STATUS Status;
+
if (Event > ACPI_NUM_TABLE_EVENTS)
{
Event = ACPI_NUM_TABLE_EVENTS;
}
- /* TBD: could dump entire table header, need a header dump routine */
+ /* Enable any GPEs associated with newly-loaded GPE methods */
+
+ Status = AcpiUpdateAllGpes ();
+ AE_CHECK_OK (AcpiUpdateAllGpes, Status);
printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
@@ -446,16 +451,61 @@ AeTableHandler (
*
* FUNCTION: AeGpeHandler
*
- * DESCRIPTION: GPE handler for acpiexec
+ * DESCRIPTION: Common GPE handler for acpiexec
*
*****************************************************************************/
UINT32
AeGpeHandler (
+ ACPI_HANDLE GpeDevice,
+ UINT32 GpeNumber,
void *Context)
{
- AcpiOsPrintf ("Received a GPE at handler\n");
- return (0);
+ ACPI_NAMESPACE_NODE *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
+
+
+ AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
+ GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
+
+ return (ACPI_REENABLE_GPE);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AeGlobalEventHandler
+ *
+ * DESCRIPTION: Global GPE/Fixed event handler
+ *
+ *****************************************************************************/
+
+void
+AeGlobalEventHandler (
+ UINT32 Type,
+ ACPI_HANDLE Device,
+ UINT32 EventNumber,
+ void *Context)
+{
+ char *TypeName;
+
+
+ switch (Type)
+ {
+ case ACPI_EVENT_TYPE_GPE:
+ TypeName = "GPE";
+ break;
+
+ case ACPI_EVENT_TYPE_FIXED:
+ TypeName = "FixedEvent";
+ break;
+
+ default:
+ TypeName = "UNKNOWN";
+ break;
+ }
+
+ AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
+ TypeName, EventNumber, Device);
}
diff --git a/tools/acpisrc/astable.c b/tools/acpisrc/astable.c
index c850891..a980322 100644
--- a/tools/acpisrc/astable.c
+++ b/tools/acpisrc/astable.c
@@ -208,40 +208,44 @@ ACPI_STRING_TABLE LinuxDataTypes[] = {
/* Declarations first - ACPI types and standard C types */
- {"INT64 ", "s64 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"UINT64 ", "u64 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"UINT32 ", "u32 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"INT32 ", "s32 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"UINT16 ", "u16 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"INT16 ", "s16 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"UINT8 ", "u8 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"BOOLEAN ", "u8 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"char ", "char ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"void ", "void ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"char * ", "char * ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"void * ", "void * ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"int ", "int ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"FILE ", "FILE ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
- {"size_t ", "size_t ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"INT64 ", "s64 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"UINT64 ", "u64 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"UINT32 ", "u32 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"INT32 ", "s32 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"UINT16 ", "u16 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"INT16 ", "s16 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"UINT8 ", "u8 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"BOOLEAN ", "u8 ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"char ", "char ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"void ", "void ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"char * ", "char * ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"void * ", "void * ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"int ", "int ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"FILE ", "FILE ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
+ {"size_t ", "size_t ", REPLACE_WHOLE_WORD | EXTRA_INDENT_C},
/* Now do embedded typecasts */
- {"UINT64", "u64", REPLACE_WHOLE_WORD},
- {"UINT32", "u32", REPLACE_WHOLE_WORD},
- {"UINT16", "u16", REPLACE_WHOLE_WORD},
- {"UINT8", "u8", REPLACE_WHOLE_WORD},
- {"BOOLEAN", "u8", REPLACE_WHOLE_WORD},
-
- {"INT64 ", "s64 ", REPLACE_WHOLE_WORD},
- {"INT64", "s64", REPLACE_WHOLE_WORD},
- {"INT32 ", "s32 ", REPLACE_WHOLE_WORD},
- {"INT32", "s32", REPLACE_WHOLE_WORD},
- {"INT16 ", "s16 ", REPLACE_WHOLE_WORD},
- {"INT8 ", "s8 ", REPLACE_WHOLE_WORD},
- {"INT16", "s16", REPLACE_WHOLE_WORD},
- {"INT8", "s8", REPLACE_WHOLE_WORD},
-
- {NULL, NULL, 0},
+ {"UINT64", "u64", REPLACE_WHOLE_WORD},
+ {"UINT32", "u32", REPLACE_WHOLE_WORD},
+ {"UINT16", "u16", REPLACE_WHOLE_WORD},
+ {"UINT8", "u8", REPLACE_WHOLE_WORD},
+ {"BOOLEAN", "u8", REPLACE_WHOLE_WORD},
+
+ {"INT64 ", "s64 ", REPLACE_WHOLE_WORD},
+ {"INT64", "s64", REPLACE_WHOLE_WORD},
+ {"INT32 ", "s32 ", REPLACE_WHOLE_WORD},
+ {"INT32", "s32", REPLACE_WHOLE_WORD},
+ {"INT16 ", "s16 ", REPLACE_WHOLE_WORD},
+ {"INT8 ", "s8 ", REPLACE_WHOLE_WORD},
+ {"INT16", "s16", REPLACE_WHOLE_WORD},
+ {"INT8", "s8", REPLACE_WHOLE_WORD},
+
+ /* Include file paths */
+
+ {"\"acpi.h\"", "<acpi/acpi.h>", REPLACE_WHOLE_WORD},
+
+ {NULL, NULL, 0}
};
ACPI_TYPED_IDENTIFIER_TABLE AcpiIdentifiers[] = {
@@ -298,12 +302,12 @@ ACPI_TYPED_IDENTIFIER_TABLE AcpiIdentifiers[] = {
{"ACPI_GPE_DEVICE_INFO", SRC_TYPE_STRUCT},
{"ACPI_GPE_EVENT_INFO", SRC_TYPE_STRUCT},
{"ACPI_GPE_HANDLER", SRC_TYPE_SIMPLE},
+ {"ACPI_GPE_HANDLER_INFO", SRC_TYPE_STRUCT},
{"ACPI_GPE_INDEX_INFO", SRC_TYPE_STRUCT},
{"ACPI_GPE_REGISTER_INFO", SRC_TYPE_STRUCT},
{"ACPI_GPE_WALK_INFO", SRC_TYPE_STRUCT},
{"ACPI_GPE_XRUPT_INFO", SRC_TYPE_STRUCT},
{"ACPI_HANDLE", SRC_TYPE_SIMPLE},
- {"ACPI_HANDLER_INFO", SRC_TYPE_STRUCT},
{"ACPI_INIT_HANDLER", SRC_TYPE_SIMPLE},
{"ACPI_IDENTIFIER_TABLE", SRC_TYPE_STRUCT},
{"ACPI_INIT_WALK_INFO", SRC_TYPE_STRUCT},
diff --git a/utilities/utglobal.c b/utilities/utglobal.c
index a7e1baa..84b8248 100644
--- a/utilities/utglobal.c
+++ b/utilities/utglobal.c
@@ -895,6 +895,7 @@ AcpiUtInitGlobals (
/* GPE support */
+ AcpiGbl_AllGpesInitialized = FALSE;
AcpiGbl_GpeXruptListHead = NULL;
AcpiGbl_GpeFadtBlocks[0] = NULL;
AcpiGbl_GpeFadtBlocks[1] = NULL;
@@ -908,6 +909,7 @@ AcpiUtInitGlobals (
AcpiGbl_InitHandler = NULL;
AcpiGbl_TableHandler = NULL;
AcpiGbl_InterfaceHandler = NULL;
+ AcpiGbl_GlobalEventHandler = NULL;
/* Global Lock support */
diff --git a/utilities/utxface.c b/utilities/utxface.c
index 9e52017..ef383e1 100644
--- a/utilities/utxface.c
+++ b/utilities/utxface.c
@@ -412,27 +412,6 @@ AcpiInitializeObjects (
}
/*
- * Initialize the GPE blocks defined in the FADT (GPE block 0 and 1).
- * The runtime GPEs are enabled here.
- *
- * This is where the _PRW methods are executed for the GPEs. These
- * methods can only be executed after the SCI and Global Lock handlers are
- * installed and initialized.
- *
- * GPEs can only be enabled after the _REG, _STA, and _INI methods have
- * been run. This ensures that all Operation Regions and all Devices have
- * been initialized and are ready.
- */
- if (!(Flags & ACPI_NO_EVENT_INIT))
- {
- Status = AcpiEvInstallFadtGpes ();
- if (ACPI_FAILURE (Status))
- {
- return (Status);
- }
- }
-
- /*
* Empty the caches (delete the cached objects) on the assumption that
* the table load filled them up more than they will be at runtime --
* thus wasting non-paged memory.
OpenPOWER on IntegriCloud