Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1875 → Rev 2216

/drivers/devman/acpica/events/evevent.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
180,54 → 180,6
 
/*******************************************************************************
*
* 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
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);
}
 
AcpiFixedEventCount[i]++;
IntStatus |= AcpiEvFixedEventDispatch (i);
}
}
/drivers/devman/acpica/events/evglock.c
0,0 → 1,439
/******************************************************************************
*
* Module Name: evglock - Global Lock support
*
*****************************************************************************/
 
/******************************************************************************
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2011, 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.
*
*****************************************************************************/
 
#include "acpi.h"
#include "accommon.h"
#include "acevents.h"
#include "acinterp.h"
 
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evglock")
 
 
/* Local prototypes */
 
static UINT32
AcpiEvGlobalLockHandler (
void *Context);
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvInitGlobalLockHandler
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Install a handler for the global lock release event
*
******************************************************************************/
 
ACPI_STATUS
AcpiEvInitGlobalLockHandler (
void)
{
ACPI_STATUS Status;
 
 
ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler);
 
 
/* Attempt installation of the global lock handler */
 
Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL,
AcpiEvGlobalLockHandler, NULL);
 
/*
* If the global lock does not exist on this platform, the attempt to
* enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
* Map to AE_OK, but mark global lock as not present. Any attempt to
* actually use the global lock will be flagged with an error.
*/
AcpiGbl_GlobalLockPresent = FALSE;
if (Status == AE_NO_HARDWARE_RESPONSE)
{
ACPI_ERROR ((AE_INFO,
"No response from Global Lock hardware, disabling lock"));
 
return_ACPI_STATUS (AE_OK);
}
 
Status = AcpiOsCreateLock (&AcpiGbl_GlobalLockPendingLock);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
 
AcpiGbl_GlobalLockPending = FALSE;
AcpiGbl_GlobalLockPresent = TRUE;
return_ACPI_STATUS (Status);
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvRemoveGlobalLockHandler
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Remove the handler for the Global Lock
*
******************************************************************************/
 
ACPI_STATUS
AcpiEvRemoveGlobalLockHandler (
void)
{
ACPI_STATUS Status;
 
 
ACPI_FUNCTION_TRACE (EvRemoveGlobalLockHandler);
 
AcpiGbl_GlobalLockPresent = FALSE;
Status = AcpiRemoveFixedEventHandler (ACPI_EVENT_GLOBAL,
AcpiEvGlobalLockHandler);
 
return_ACPI_STATUS (Status);
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvGlobalLockHandler
*
* PARAMETERS: Context - From thread interface, not used
*
* RETURN: ACPI_INTERRUPT_HANDLED
*
* DESCRIPTION: Invoked directly from the SCI handler when a global lock
* release interrupt occurs. If there is actually a pending
* request for the lock, signal the waiting thread.
*
******************************************************************************/
 
static UINT32
AcpiEvGlobalLockHandler (
void *Context)
{
ACPI_STATUS Status;
ACPI_CPU_FLAGS Flags;
 
 
Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
 
/*
* If a request for the global lock is not actually pending,
* we are done. This handles "spurious" global lock interrupts
* which are possible (and have been seen) with bad BIOSs.
*/
if (!AcpiGbl_GlobalLockPending)
{
goto CleanupAndExit;
}
 
/*
* Send a unit to the global lock semaphore. The actual acquisition
* of the global lock will be performed by the waiting thread.
*/
Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 1);
if (ACPI_FAILURE (Status))
{
ACPI_ERROR ((AE_INFO, "Could not signal Global Lock semaphore"));
}
 
AcpiGbl_GlobalLockPending = FALSE;
 
 
CleanupAndExit:
 
AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
return (ACPI_INTERRUPT_HANDLED);
}
 
 
/******************************************************************************
*
* FUNCTION: AcpiEvAcquireGlobalLock
*
* PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
*
* RETURN: Status
*
* DESCRIPTION: Attempt to gain ownership of the Global Lock.
*
* MUTEX: Interpreter must be locked
*
* Note: The original implementation allowed multiple threads to "acquire" the
* Global Lock, and the OS would hold the lock until the last thread had
* released it. However, this could potentially starve the BIOS out of the
* lock, especially in the case where there is a tight handshake between the
* Embedded Controller driver and the BIOS. Therefore, this implementation
* allows only one thread to acquire the HW Global Lock at a time, and makes
* the global lock appear as a standard mutex on the OS side.
*
*****************************************************************************/
 
ACPI_STATUS
AcpiEvAcquireGlobalLock (
UINT16 Timeout)
{
ACPI_CPU_FLAGS Flags;
ACPI_STATUS Status;
BOOLEAN Acquired = FALSE;
 
 
ACPI_FUNCTION_TRACE (EvAcquireGlobalLock);
 
 
/*
* Only one thread can acquire the GL at a time, the GlobalLockMutex
* enforces this. This interface releases the interpreter if we must wait.
*/
Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex,
Timeout);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
 
/*
* Update the global lock handle and check for wraparound. The handle is
* only used for the external global lock interfaces, but it is updated
* here to properly handle the case where a single thread may acquire the
* lock via both the AML and the AcpiAcquireGlobalLock interfaces. The
* handle is therefore updated on the first acquire from a given thread
* regardless of where the acquisition request originated.
*/
AcpiGbl_GlobalLockHandle++;
if (AcpiGbl_GlobalLockHandle == 0)
{
AcpiGbl_GlobalLockHandle = 1;
}
 
/*
* Make sure that a global lock actually exists. If not, just
* treat the lock as a standard mutex.
*/
if (!AcpiGbl_GlobalLockPresent)
{
AcpiGbl_GlobalLockAcquired = TRUE;
return_ACPI_STATUS (AE_OK);
}
 
Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
 
do
{
/* Attempt to acquire the actual hardware lock */
 
ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
if (Acquired)
{
AcpiGbl_GlobalLockAcquired = TRUE;
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"Acquired hardware Global Lock\n"));
break;
}
 
/*
* Did not get the lock. The pending bit was set above, and
* we must now wait until we receive the global lock
* released interrupt.
*/
AcpiGbl_GlobalLockPending = TRUE;
AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
 
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"Waiting for hardware Global Lock\n"));
 
/*
* Wait for handshake with the global lock interrupt handler.
* This interface releases the interpreter if we must wait.
*/
Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore,
ACPI_WAIT_FOREVER);
 
Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock);
 
} while (ACPI_SUCCESS (Status));
 
AcpiGbl_GlobalLockPending = FALSE;
AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags);
 
return_ACPI_STATUS (Status);
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvReleaseGlobalLock
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Releases ownership of the Global Lock.
*
******************************************************************************/
 
ACPI_STATUS
AcpiEvReleaseGlobalLock (
void)
{
BOOLEAN Pending = FALSE;
ACPI_STATUS Status = AE_OK;
 
 
ACPI_FUNCTION_TRACE (EvReleaseGlobalLock);
 
 
/* Lock must be already acquired */
 
if (!AcpiGbl_GlobalLockAcquired)
{
ACPI_WARNING ((AE_INFO,
"Cannot release the ACPI Global Lock, it has not been acquired"));
return_ACPI_STATUS (AE_NOT_ACQUIRED);
}
 
if (AcpiGbl_GlobalLockPresent)
{
/* Allow any thread to release the lock */
 
ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_FACS, Pending);
 
/*
* If the pending bit was set, we must write GBL_RLS to the control
* register
*/
if (Pending)
{
Status = AcpiWriteBitRegister (
ACPI_BITREG_GLOBAL_LOCK_RELEASE, ACPI_ENABLE_EVENT);
}
 
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Released hardware Global Lock\n"));
}
 
AcpiGbl_GlobalLockAcquired = FALSE;
 
/* Release the local GL mutex */
 
AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex);
return_ACPI_STATUS (Status);
}
/drivers/devman/acpica/events/evgpe.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
134,26 → 134,26
 
/*******************************************************************************
*
* FUNCTION: AcpiEvUpdateGpeEnableMasks
* FUNCTION: AcpiEvUpdateGpeEnableMask
*
* PARAMETERS: GpeEventInfo - GPE to update
*
* RETURN: Status
*
* DESCRIPTION: Updates GPE register enable masks based upon whether there are
* references (either wake or run) to this GPE
* DESCRIPTION: Updates GPE register enable mask based upon whether there are
* runtime references to this GPE
*
******************************************************************************/
 
ACPI_STATUS
AcpiEvUpdateGpeEnableMasks (
AcpiEvUpdateGpeEnableMask (
ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
UINT8 RegisterBit;
UINT32 RegisterBit;
 
 
ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMasks);
ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask);
 
 
GpeRegisterInfo = GpeEventInfo->RegisterInfo;
162,26 → 162,19
return_ACPI_STATUS (AE_NOT_EXIST);
}
 
RegisterBit = (UINT8)
(1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
 
/* Clear the wake/run bits up front */
/* Clear the run bit up front */
 
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
 
/* Set the mask bits only if there are references to this GPE */
/* Set the mask bit only if there are references to this GPE */
 
if (GpeEventInfo->RuntimeCount)
{
ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit);
}
 
if (GpeEventInfo->WakeupCount)
{
ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
}
 
return_ACPI_STATUS (AE_OK);
}
 
194,11 → 187,8
*
* RETURN: Status
*
* DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
* of type or number of references.
* DESCRIPTION: Clear a GPE of stale events and enable it.
*
* Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
 
ACPI_STATUS
212,24 → 202,17
 
 
/*
* 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);
}
 
/* Ensure the HW enable masks are current */
 
Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
 
/* Clear the GPE (of stale events) */
 
Status = AcpiHwClearGpe (GpeEventInfo);
240,7 → 223,7
 
/* Enable the requested GPE */
 
Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
return_ACPI_STATUS (Status);
}
 
247,52 → 230,98
 
/*******************************************************************************
*
* FUNCTION: AcpiEvDisableGpe
* FUNCTION: AcpiEvAddGpeReference
*
* PARAMETERS: GpeEventInfo - GPE to disable
* PARAMETERS: GpeEventInfo - Add a reference to this GPE
*
* RETURN: Status
*
* DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
* regardless of the type or number of references.
* DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
* hardware-enabled.
*
* Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
 
ACPI_STATUS
AcpiEvDisableGpe (
AcpiEvAddGpeReference (
ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_STATUS Status;
ACPI_STATUS Status = AE_OK;
 
 
ACPI_FUNCTION_TRACE (EvDisableGpe);
ACPI_FUNCTION_TRACE (EvAddGpeReference);
 
 
/*
* Note: Always disable the GPE, even if we think that that it is already
* disabled. It is possible that the AML or some other code has enabled
* the GPE behind our back.
*/
if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
{
return_ACPI_STATUS (AE_LIMIT);
}
 
/* Ensure the HW enable masks are current */
GpeEventInfo->RuntimeCount++;
if (GpeEventInfo->RuntimeCount == 1)
{
/* Enable on first reference */
 
Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
if (ACPI_SUCCESS (Status))
{
Status = AcpiEvEnableGpe (GpeEventInfo);
}
 
if (ACPI_FAILURE (Status))
{
GpeEventInfo->RuntimeCount--;
}
}
 
return_ACPI_STATUS (Status);
}
 
/*
* Always H/W disable this GPE, even if we don't know the GPE type.
* Simply clear the enable bit for this particular GPE, but do not
* write out the current GPE enable mask since this may inadvertently
* enable GPEs too early. An example is a rogue GPE that has arrived
* during ACPICA initialization - possibly because AML or other code
* has enabled the GPE.
*/
Status = AcpiHwLowDisableGpe (GpeEventInfo);
 
/*******************************************************************************
*
* 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);
}
 
465,6 → 494,16
 
GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
 
/*
* Optimization: If there are no GPEs enabled within this
* register, we can safely ignore the entire register.
*/
if (!(GpeRegisterInfo->EnableForRun |
GpeRegisterInfo->EnableForWake))
{
continue;
}
 
/* Read the Status Register */
 
Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress);
482,7 → 521,7
}
 
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 */
507,7 → 546,7
* 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);
578,10 → 617,6
return_VOID;
}
 
/* Update the GPE register masks for return to enabled state */
 
(void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
 
/*
* Take a snapshot of the GPE info for this level - we copy the info to
* prevent a race condition with RemoveHandler/RemoveBlock.
595,13 → 630,27
return_VOID;
}
 
/* Do the correct dispatch - normal method or implicit notify */
 
switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
{
case ACPI_GPE_DISPATCH_NOTIFY:
 
/*
* Must check for control method type dispatch one more time to avoid a
* race with EvGpeInstallHandler
* 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.
*/
if ((LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_METHOD)
{
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));
612,8 → 661,8
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;
628,6 → 677,11
"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 */
647,6 → 701,7
* FUNCTION: AcpiEvAsynchEnableGpe
*
* PARAMETERS: Context (GpeEventInfo) - Info for this GPE
* Callback from AcpiOsExecute
*
* RETURN: None
*
660,6 → 715,32
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;
 
 
667,23 → 748,23
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 */
 
(void) AcpiHwWriteGpeEnableReg (GpeEventInfo);
 
Exit:
ACPI_FREE (GpeEventInfo);
return;
/*
* 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);
return (AE_OK);
}
 
 
691,7 → 772,8
*
* FUNCTION: AcpiEvGpeDispatch
*
* PARAMETERS: GpeEventInfo - Info for this GPE
* 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
705,16 → 787,25
 
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
727,60 → 818,57
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 (
/* Invoke the installed handler (at interrupt level) */
 
ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
GpeDevice, GpeNumber,
GpeEventInfo->Dispatch.Handler->Context);
 
/* It is now safe to clear level-triggered events. */
/* If requested, clear (if level-triggered) and reenable the GPE */
 
if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
ACPI_GPE_LEVEL_TRIGGERED)
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:
case ACPI_GPE_DISPATCH_NOTIFY:
 
/*
* Disable the GPE, so it doesn't keep firing before the method has a
* chance to run (it runs asynchronously with interrupts enabled).
*/
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Unable to disable GPE[0x%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
 
/*
* Execute the method associated with the GPE
* NOTE: Level-triggered GPEs are cleared after the method completes.
*/
789,7 → 877,7
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;
802,20 → 890,8
* 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 a handler
* is installed or ACPICA is restarted.
*/
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Unable to disable GPE[0x%2X]", GpeNumber));
return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
}
break;
}
 
/drivers/devman/acpica/events/evgpeblk.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
467,6 → 467,7
 
GpeBlock->Node = GpeDevice;
GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
GpeBlock->Initialized = FALSE;
GpeBlock->RegisterCount = RegisterCount;
GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
 
493,11 → 494,12
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,14 → 531,12
*
* 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.
*
******************************************************************************/
543,16 → 543,14
 
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
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++)
614,33 → 583,23
GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
 
/* Ignore GPEs that can wake the system */
 
if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
/*
* Ignore GPEs that have no corresponding _Lxx/_Exx method
* and GPEs that are used to wake the system
*/
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))
{
WakeGpeCount++;
if (AcpiGbl_LeaveWakeGpesDisabled)
{
continue;
}
}
 
/* Ignore GPEs that have no corresponding _Lxx/_Exx method */
 
if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD))
{
continue;
}
 
/* Enable this GPE */
 
GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber;
Status = AcpiEnableGpe (GpeDevice, GpeNumber,
ACPI_GPE_TYPE_RUNTIME);
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;
}
 
648,13 → 607,13
}
}
 
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);
}
 
/drivers/devman/acpica/events/evgpeinit.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
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
*
* 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,50 → 316,14
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.
* Find any _Lxx/_Exx GPE methods that have just been loaded.
*
* 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.
* Any GPEs that correspond to new _Lxx/_Exx methods are immediately
* enabled.
*
* Any GPEs that correspond to new _Lxx/_Exx methods and are not
* marked as CAN_WAKE are immediately enabled.
*
* Examine the namespace underneath each GpeDevice within the
* GpeBlock lists.
*/
357,7 → 334,8
}
 
WalkInfo.Count = 0;
WalkInfo.EnableThisGpe = TRUE;
WalkInfo.OwnerId = TableOwnerId;
WalkInfo.ExecuteByOwnerId = TRUE;
 
/* Walk the interrupt level descriptor list */
 
388,11 → 366,9
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);
423,8 → 399,6
*
* 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)
*
******************************************************************************/
 
438,8 → 412,6
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
/*
* 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,213 → 520,12
* 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,
ACPI_GPE_TYPE_RUNTIME);
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);
}
 
/drivers/devman/acpica/events/evgpeutil.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
241,6 → 241,51
 
/*******************************************************************************
*
* 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
/drivers/devman/acpica/events/evmisc.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
117,7 → 117,6
#include "accommon.h"
#include "acevents.h"
#include "acnamesp.h"
#include "acinterp.h"
 
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME ("evmisc")
129,15 → 128,7
AcpiEvNotifyDispatch (
void *Context);
 
static UINT32
AcpiEvGlobalLockHandler (
void *Context);
 
static ACPI_STATUS
AcpiEvRemoveGlobalLockHandler (
void);
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvIsNotifyObject
372,294 → 363,8
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvGlobalLockHandler
*
* PARAMETERS: Context - From thread interface, not used
*
* RETURN: ACPI_INTERRUPT_HANDLED
*
* DESCRIPTION: Invoked directly from the SCI handler when a global lock
* release interrupt occurs. Attempt to acquire the global lock,
* if successful, signal the thread waiting for the lock.
*
* NOTE: Assumes that the semaphore can be signaled from interrupt level. If
* this is not possible for some reason, a separate thread will have to be
* scheduled to do this.
*
******************************************************************************/
 
static UINT32
AcpiEvGlobalLockHandler (
void *Context)
{
BOOLEAN Acquired = FALSE;
ACPI_STATUS Status;
 
 
/*
* Attempt to get the lock.
*
* If we don't get it now, it will be marked pending and we will
* take another interrupt when it becomes free.
*/
ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
if (Acquired)
{
/* Got the lock, now wake the thread waiting for it */
 
AcpiGbl_GlobalLockAcquired = TRUE;
 
/* Send a unit to the semaphore */
 
Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 1);
if (ACPI_FAILURE (Status))
{
ACPI_ERROR ((AE_INFO, "Could not signal Global Lock semaphore"));
}
}
 
return (ACPI_INTERRUPT_HANDLED);
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvInitGlobalLockHandler
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Install a handler for the global lock release event
*
******************************************************************************/
 
ACPI_STATUS
AcpiEvInitGlobalLockHandler (
void)
{
ACPI_STATUS Status;
 
 
ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler);
 
 
/* Attempt installation of the global lock handler */
 
Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL,
AcpiEvGlobalLockHandler, NULL);
 
/*
* If the global lock does not exist on this platform, the attempt to
* enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
* Map to AE_OK, but mark global lock as not present. Any attempt to
* actually use the global lock will be flagged with an error.
*/
if (Status == AE_NO_HARDWARE_RESPONSE)
{
ACPI_ERROR ((AE_INFO,
"No response from Global Lock hardware, disabling lock"));
 
AcpiGbl_GlobalLockPresent = FALSE;
return_ACPI_STATUS (AE_OK);
}
 
AcpiGbl_GlobalLockPresent = TRUE;
return_ACPI_STATUS (Status);
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvRemoveGlobalLockHandler
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Remove the handler for the Global Lock
*
******************************************************************************/
 
static ACPI_STATUS
AcpiEvRemoveGlobalLockHandler (
void)
{
ACPI_STATUS Status;
 
 
ACPI_FUNCTION_TRACE (EvRemoveGlobalLockHandler);
 
AcpiGbl_GlobalLockPresent = FALSE;
Status = AcpiRemoveFixedEventHandler (ACPI_EVENT_GLOBAL,
AcpiEvGlobalLockHandler);
 
return_ACPI_STATUS (Status);
}
 
 
/******************************************************************************
*
* FUNCTION: AcpiEvAcquireGlobalLock
*
* PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
*
* RETURN: Status
*
* DESCRIPTION: Attempt to gain ownership of the Global Lock.
*
* MUTEX: Interpreter must be locked
*
* Note: The original implementation allowed multiple threads to "acquire" the
* Global Lock, and the OS would hold the lock until the last thread had
* released it. However, this could potentially starve the BIOS out of the
* lock, especially in the case where there is a tight handshake between the
* Embedded Controller driver and the BIOS. Therefore, this implementation
* allows only one thread to acquire the HW Global Lock at a time, and makes
* the global lock appear as a standard mutex on the OS side.
*
*****************************************************************************/
 
ACPI_STATUS
AcpiEvAcquireGlobalLock (
UINT16 Timeout)
{
ACPI_STATUS Status = AE_OK;
BOOLEAN Acquired = FALSE;
 
 
ACPI_FUNCTION_TRACE (EvAcquireGlobalLock);
 
 
/*
* Only one thread can acquire the GL at a time, the GlobalLockMutex
* enforces this. This interface releases the interpreter if we must wait.
*/
Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex,
Timeout);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
 
/*
* Update the global lock handle and check for wraparound. The handle is
* only used for the external global lock interfaces, but it is updated
* here to properly handle the case where a single thread may acquire the
* lock via both the AML and the AcpiAcquireGlobalLock interfaces. The
* handle is therefore updated on the first acquire from a given thread
* regardless of where the acquisition request originated.
*/
AcpiGbl_GlobalLockHandle++;
if (AcpiGbl_GlobalLockHandle == 0)
{
AcpiGbl_GlobalLockHandle = 1;
}
 
/*
* Make sure that a global lock actually exists. If not, just treat the
* lock as a standard mutex.
*/
if (!AcpiGbl_GlobalLockPresent)
{
AcpiGbl_GlobalLockAcquired = TRUE;
return_ACPI_STATUS (AE_OK);
}
 
/* Attempt to acquire the actual hardware lock */
 
ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired);
if (Acquired)
{
/* We got the lock */
 
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Acquired hardware Global Lock\n"));
 
AcpiGbl_GlobalLockAcquired = TRUE;
return_ACPI_STATUS (AE_OK);
}
 
/*
* Did not get the lock. The pending bit was set above, and we must now
* wait until we get the global lock released interrupt.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
 
/*
* Wait for handshake with the global lock interrupt handler.
* This interface releases the interpreter if we must wait.
*/
Status = AcpiExSystemWaitSemaphore (AcpiGbl_GlobalLockSemaphore,
ACPI_WAIT_FOREVER);
 
return_ACPI_STATUS (Status);
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvReleaseGlobalLock
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Releases ownership of the Global Lock.
*
******************************************************************************/
 
ACPI_STATUS
AcpiEvReleaseGlobalLock (
void)
{
BOOLEAN Pending = FALSE;
ACPI_STATUS Status = AE_OK;
 
 
ACPI_FUNCTION_TRACE (EvReleaseGlobalLock);
 
 
/* Lock must be already acquired */
 
if (!AcpiGbl_GlobalLockAcquired)
{
ACPI_WARNING ((AE_INFO,
"Cannot release the ACPI Global Lock, it has not been acquired"));
return_ACPI_STATUS (AE_NOT_ACQUIRED);
}
 
if (AcpiGbl_GlobalLockPresent)
{
/* Allow any thread to release the lock */
 
ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_FACS, Pending);
 
/*
* If the pending bit was set, we must write GBL_RLS to the control
* register
*/
if (Pending)
{
Status = AcpiWriteBitRegister (
ACPI_BITREG_GLOBAL_LOCK_RELEASE, ACPI_ENABLE_EVENT);
}
 
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Released hardware Global Lock\n"));
}
 
AcpiGbl_GlobalLockAcquired = FALSE;
 
/* Release the local GL mutex */
 
AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex);
return_ACPI_STATUS (Status);
}
 
 
/******************************************************************************
*
* FUNCTION: AcpiEvTerminate
*
* PARAMETERS: none
737,4 → 442,3
}
return_VOID;
}
 
/drivers/devman/acpica/events/evregion.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
133,6 → 133,10
ACPI_NAMESPACE_NODE *Node,
ACPI_ADR_SPACE_TYPE SpaceId);
 
static void
AcpiEvOrphanEcRegMethod (
void);
 
static ACPI_STATUS
AcpiEvRegRun (
ACPI_HANDLE ObjHandle,
334,6 → 338,8
}
}
 
AcpiGbl_RegMethodsExecuted = TRUE;
 
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
return_ACPI_STATUS (Status);
}
681,7 → 687,7
 
/* Now stop region accesses by executing the _REG method */
 
Status = AcpiEvExecuteRegMethod (RegionObj, 0);
Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]",
1212,6 → 1218,13
ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL,
&SpaceId, NULL);
 
/* Special case for EC: handle "orphan" _REG methods with no region */
 
if (SpaceId == ACPI_ADR_SPACE_EC)
{
AcpiEvOrphanEcRegMethod ();
}
 
return_ACPI_STATUS (Status);
}
 
1278,7 → 1291,122
return (AE_OK);
}
 
Status = AcpiEvExecuteRegMethod (ObjDesc, 1);
Status = AcpiEvExecuteRegMethod (ObjDesc, ACPI_REG_CONNECT);
return (Status);
}
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEvOrphanEcRegMethod
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
* device. This is a _REG method that has no corresponding region
* within the EC device scope. The orphan _REG method appears to
* have been enabled by the description of the ECDT in the ACPI
* specification: "The availability of the region space can be
* detected by providing a _REG method object underneath the
* Embedded Controller device."
*
* To quickly access the EC device, we use the EC_ID that appears
* within the ECDT. Otherwise, we would need to perform a time-
* consuming namespace walk, executing _HID methods to find the
* EC device.
*
******************************************************************************/
 
static void
AcpiEvOrphanEcRegMethod (
void)
{
ACPI_TABLE_ECDT *Table;
ACPI_STATUS Status;
ACPI_OBJECT_LIST Args;
ACPI_OBJECT Objects[2];
ACPI_NAMESPACE_NODE *EcDeviceNode;
ACPI_NAMESPACE_NODE *RegMethod;
ACPI_NAMESPACE_NODE *NextNode;
 
 
ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod);
 
 
/* Get the ECDT (if present in system) */
 
Status = AcpiGetTable (ACPI_SIG_ECDT, 0,
ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Table));
if (ACPI_FAILURE (Status))
{
return_VOID;
}
 
/* We need a valid EC_ID string */
 
if (!(*Table->Id))
{
return_VOID;
}
 
/* Namespace is currently locked, must release */
 
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
 
/* Get a handle to the EC device referenced in the ECDT */
 
Status = AcpiGetHandle (NULL,
ACPI_CAST_PTR (char, Table->Id),
ACPI_CAST_PTR (ACPI_HANDLE, &EcDeviceNode));
if (ACPI_FAILURE (Status))
{
goto Exit;
}
 
/* Get a handle to a _REG method immediately under the EC device */
 
Status = AcpiGetHandle (EcDeviceNode,
METHOD_NAME__REG, ACPI_CAST_PTR (ACPI_HANDLE, &RegMethod));
if (ACPI_FAILURE (Status))
{
goto Exit;
}
 
/*
* Execute the _REG method only if there is no Operation Region in
* this scope with the Embedded Controller space ID. Otherwise, it
* will already have been executed. Note, this allows for Regions
* with other space IDs to be present; but the code below will then
* execute the _REG method with the EC space ID argument.
*/
NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL);
while (NextNode)
{
if ((NextNode->Type == ACPI_TYPE_REGION) &&
(NextNode->Object) &&
(NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC))
{
goto Exit; /* Do not execute _REG */
}
NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode);
}
 
/* Evaluate the _REG(EC,Connect) method */
 
Args.Count = 2;
Args.Pointer = Objects;
Objects[0].Type = ACPI_TYPE_INTEGER;
Objects[0].Integer.Value = ACPI_ADR_SPACE_EC;
Objects[1].Type = ACPI_TYPE_INTEGER;
Objects[1].Integer.Value = ACPI_REG_CONNECT;
 
Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL);
 
Exit:
/* We ignore all errors from above, don't care */
 
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
return_VOID;
}
/drivers/devman/acpica/events/evrgnini.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
395,8 → 395,8
}
 
/*
* Get the PCI device and function numbers from the _ADR object contained
* in the parent's scope.
* Get the PCI device and function numbers from the _ADR object
* contained in the parent's scope.
*/
Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
PciDeviceNode, &PciValue);
429,9 → 429,14
PciId->Bus = ACPI_LOWORD (PciValue);
}
 
/* Complete this device's PciId */
/* Complete/update the PCI ID for this device */
 
AcpiOsDerivePciId (PciRootNode, RegionObj->Region.Node, &PciId);
Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node);
if (ACPI_FAILURE (Status))
{
ACPI_FREE (PciId);
return_ACPI_STATUS (Status);
}
 
*RegionContext = PciId;
return_ACPI_STATUS (AE_OK);
724,9 → 729,9
*
* See AcpiNsExecModuleCode
*/
if (ObjDesc->Method.Flags & AOPOBJ_MODULE_LEVEL)
if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
{
HandlerObj = ObjDesc->Method.Extra.Handler;
HandlerObj = ObjDesc->Method.Dispatch.Handler;
}
break;
 
763,7 → 768,7
}
}
 
Status = AcpiEvExecuteRegMethod (RegionObj, 1);
Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT);
 
if (AcpiNsLocked)
{
/drivers/devman/acpica/events/evsci.c
9,7 → 9,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
/drivers/devman/acpica/events/evxface.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
177,6 → 177,66
 
/*******************************************************************************
*
* 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
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,6 → 776,17
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);
722,7 → 793,7
if (!GpeEventInfo)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
goto FreeAndExit;
}
 
/* Make sure that there isn't a handler there already */
731,36 → 802,40
ACPI_GPE_DISPATCH_HANDLER)
{
Status = AE_ALREADY_EXISTS;
goto UnlockAndExit;
goto FreeAndExit;
}
 
/* Allocate and init handler object */
 
Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_HANDLER_INFO));
if (!Handler)
{
Status = AE_NO_MEMORY;
goto UnlockAndExit;
}
 
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));
 
/* Disable the GPE before installing the 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)
{
Handler->OriginallyEnabled = TRUE;
(void) AcpiEvRemoveGpeReference (GpeEventInfo);
 
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
/* Sanity check of original type against new type */
 
if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
{
goto UnlockAndExit;
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);
771,6 → 846,11
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (Status);
 
FreeAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
ACPI_FREE (Handler);
goto UnlockAndExit;
}
 
ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
795,10 → 875,10
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;
 
819,6 → 899,8
return_ACPI_STATUS (Status);
}
 
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
 
/* Ensure that we have a valid GPE number */
 
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
845,28 → 927,27
goto UnlockAndExit;
}
 
/* Disable the GPE before removing the handler */
 
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
goto UnlockAndExit;
}
 
/* 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 */
 
874,6 → 955,7
 
 
UnlockAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (Status);
}
/drivers/devman/acpica/events/evxfevnt.c
8,7 → 8,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
118,22 → 118,12
 
#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);
 
 
/*******************************************************************************
*
* FUNCTION: AcpiEnable
307,283 → 297,9
 
/*******************************************************************************
*
* FUNCTION: AcpiEnableGpe
*
* PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
* GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
* or both
*
* RETURN: Status
*
* DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
* hardware-enabled (for runtime GPEs), or the GPE register mask
* is updated (for wake GPEs).
*
******************************************************************************/
 
ACPI_STATUS
AcpiEnableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT8 GpeType)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_CPU_FLAGS Flags;
 
 
ACPI_FUNCTION_TRACE (AcpiEnableGpe);
 
 
/* Parameter validation */
 
if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
 
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 (GpeType & ACPI_GPE_TYPE_RUNTIME)
{
if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
{
Status = AE_LIMIT; /* Too many references */
goto UnlockAndExit;
}
 
GpeEventInfo->RuntimeCount++;
if (GpeEventInfo->RuntimeCount == 1)
{
Status = AcpiEvEnableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
GpeEventInfo->RuntimeCount--;
goto UnlockAndExit;
}
}
}
 
if (GpeType & ACPI_GPE_TYPE_WAKE)
{
/* The GPE must have the ability to wake the system */
 
if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
{
Status = AE_TYPE;
goto UnlockAndExit;
}
 
if (GpeEventInfo->WakeupCount == ACPI_UINT8_MAX)
{
Status = AE_LIMIT; /* Too many references */
goto UnlockAndExit;
}
 
/*
* Update the enable mask on the first wakeup reference. Wake GPEs
* are only hardware-enabled just before sleeping.
*/
GpeEventInfo->WakeupCount++;
if (GpeEventInfo->WakeupCount == 1)
{
(void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
}
}
 
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
* GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
* or both
*
* 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,
UINT8 GpeType)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_CPU_FLAGS Flags;
 
 
ACPI_FUNCTION_TRACE (AcpiDisableGpe);
 
 
/* Parameter validation */
 
if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
 
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 (GpeType & ACPI_GPE_TYPE_RUNTIME)
{
if (!GpeEventInfo->RuntimeCount)
{
Status = AE_LIMIT; /* There are no references to remove */
goto UnlockAndExit;
}
 
GpeEventInfo->RuntimeCount--;
if (!GpeEventInfo->RuntimeCount)
{
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
GpeEventInfo->RuntimeCount++;
goto UnlockAndExit;
}
}
}
 
/*
* Update masks for wake GPE on removal of the last reference.
* No need to hardware-disable wake GPEs here, they are not currently
* enabled.
*/
if (GpeType & ACPI_GPE_TYPE_WAKE)
{
if (!GpeEventInfo->WakeupCount)
{
Status = AE_LIMIT; /* There are no references to remove */
goto UnlockAndExit;
}
 
GpeEventInfo->WakeupCount--;
if (!GpeEventInfo->WakeupCount)
{
(void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
}
}
 
 
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 = AcpiEvDisableGpe (GpeEventInfo);
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
688,53 → 404,6
 
/*******************************************************************************
*
* 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
781,400 → 450,3
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);
}
 
 
/drivers/devman/acpica/events/evxfgpe.c
0,0 → 1,972
/******************************************************************************
*
* Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
*
*****************************************************************************/
 
/******************************************************************************
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2011, 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);
}
 
/* Handle root object case */
 
if (WakeDevice == ACPI_ROOT_OBJECT)
{
DeviceNode = AcpiGbl_RootNode;
}
else
{
DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
}
 
/* Validate WakeDevice is of type Device */
 
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)
/drivers/devman/acpica/events/evxfregn.c
9,7 → 9,7
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
* Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
* All rights reserved.
*
* 2. License
139,6 → 139,12
*
* DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
*
* NOTE: This function should only be called after AcpiEnableSubsystem has
* been called. This is because any _REG methods associated with the Space ID
* are executed here, and these methods can only be safely executed after
* the default handlers have been installed and the hardware has been
* initialized (via AcpiEnableSubsystem.)
*
******************************************************************************/
 
ACPI_STATUS
186,10 → 192,43
goto UnlockAndExit;
}
 
/*
* For the default SpaceIDs, (the IDs for which there are default region handlers
* installed) Only execute the _REG methods if the global initialization _REG
* methods have already been run (via AcpiInitializeObjects). In other words,
* we will defer the execution of the _REG methods for these SpaceIDs until
* execution of AcpiInitializeObjects. This is done because we need the handlers
* for the default spaces (mem/io/pci/table) to be installed before we can run
* any control methods (or _REG methods). There is known BIOS code that depends
* on this.
*
* For all other SpaceIDs, we can safely execute the _REG methods immediately.
* This means that for IDs like EmbeddedController, this function should be called
* only after AcpiEnableSubsystem has been called.
*/
switch (SpaceId)
{
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
case ACPI_ADR_SPACE_SYSTEM_IO:
case ACPI_ADR_SPACE_PCI_CONFIG:
case ACPI_ADR_SPACE_DATA_TABLE:
 
if (!AcpiGbl_RegMethodsExecuted)
{
/* We will defer execution of the _REG methods for this space */
goto UnlockAndExit;
}
break;
 
default:
break;
}
 
/* Run all _REG methods for this address space */
 
Status = AcpiEvExecuteRegMethods (Node, SpaceId);
 
 
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
return_ACPI_STATUS (Status);