diff options
Diffstat (limited to 'sys/contrib/dev/acpica/evxfevnt.c')
-rw-r--r-- | sys/contrib/dev/acpica/evxfevnt.c | 619 |
1 files changed, 450 insertions, 169 deletions
diff --git a/sys/contrib/dev/acpica/evxfevnt.c b/sys/contrib/dev/acpica/evxfevnt.c index 753c6d0..668ecfd 100644 --- a/sys/contrib/dev/acpica/evxfevnt.c +++ b/sys/contrib/dev/acpica/evxfevnt.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable - * $Revision: 62 $ + * $Revision: 73 $ * *****************************************************************************/ @@ -119,6 +119,7 @@ #include "acpi.h" #include "acevents.h" +#include "acnamesp.h" #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evxfevnt") @@ -195,6 +196,7 @@ AcpiDisable (void) ACPI_FUNCTION_TRACE ("AcpiDisable"); + if (!AcpiGbl_FADT) { ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n")); @@ -228,102 +230,131 @@ AcpiDisable (void) * * FUNCTION: AcpiEnableEvent * - * PARAMETERS: Event - The fixed event or GPE to be enabled - * Type - The type of event - * Flags - Just enable, or also wake enable? + * PARAMETERS: Event - The fixed eventto be enabled + * Flags - Reserved * * RETURN: Status * - * DESCRIPTION: Enable an ACPI event (fixed and general purpose) + * DESCRIPTION: Enable an ACPI event (fixed) * ******************************************************************************/ ACPI_STATUS AcpiEnableEvent ( UINT32 Event, - UINT32 Type, UINT32 Flags) { ACPI_STATUS Status = AE_OK; UINT32 Value; - ACPI_GPE_EVENT_INFO *GpeEventInfo; ACPI_FUNCTION_TRACE ("AcpiEnableEvent"); - /* The Type must be either Fixed Event or GPE */ + /* Decode the Fixed Event */ - switch (Type) + if (Event > ACPI_EVENT_MAX) { - case ACPI_EVENT_FIXED: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - /* Decode the Fixed Event */ + /* + * Enable the requested fixed event (by writing a one to the + * enable register bit) + */ + Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, + 1, ACPI_MTX_LOCK); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } - if (Event > ACPI_EVENT_MAX) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + /* Make sure that the hardware responded */ - /* - * Enable the requested fixed event (by writing a one to the - * enable register bit) - */ - Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, - 1, ACPI_MTX_LOCK); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, + &Value, ACPI_MTX_LOCK); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } - /* Make sure that the hardware responded */ + if (Value != 1) + { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not enable %s event\n", AcpiUtGetEventName (Event))); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); + } - Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, - &Value, ACPI_MTX_LOCK); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + return_ACPI_STATUS (Status); +} - if (Value != 1) - { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Could not enable %s event\n", AcpiUtGetEventName (Event))); - return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); - } - break; +/******************************************************************************* + * + * FUNCTION: AcpiEnableGpe + * + * PARAMETERS: GpeDevice - Parent GPE Device + * GpeNumber - GPE level within the GPE block + * Flags - Just enable, or also wake enable? + * Called from ISR or not + * + * RETURN: Status + * + * DESCRIPTION: Enable an ACPI event (general purpose) + * + ******************************************************************************/ - case ACPI_EVENT_GPE: +ACPI_STATUS +AcpiEnableGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT32 Flags) +{ + ACPI_STATUS Status = AE_OK; + ACPI_GPE_EVENT_INFO *GpeEventInfo; - /* Ensure that we have a valid GPE number */ - GpeEventInfo = AcpiEvGetGpeEventInfo (Event); - if (!GpeEventInfo) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + ACPI_FUNCTION_TRACE ("AcpiEnableGpe"); - /* Enable the requested GPE number */ - Status = AcpiHwEnableGpe (GpeEventInfo); + /* Use semaphore lock if not executing at interrupt level */ + + if (Flags & ACPI_NOT_ISR) + { + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } + } - if (Flags & ACPI_EVENT_WAKE_ENABLE) - { - AcpiHwEnableGpeForWakeup (GpeEventInfo); - } - break; + /* Ensure that we have a valid GPE number */ + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } - default: + /* Enable the requested GPE number */ - Status = AE_BAD_PARAMETER; + Status = AcpiHwEnableGpe (GpeEventInfo); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + + if (Flags & ACPI_EVENT_WAKE_ENABLE) + { + AcpiHwEnableGpeForWakeup (GpeEventInfo); } +UnlockAndExit: + if (Flags & ACPI_NOT_ISR) + { + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + } return_ACPI_STATUS (Status); } @@ -332,100 +363,129 @@ AcpiEnableEvent ( * * FUNCTION: AcpiDisableEvent * - * PARAMETERS: Event - The fixed event or GPE to be enabled - * Type - The type of event, fixed or general purpose - * Flags - Wake disable vs. non-wake disable + * PARAMETERS: Event - The fixed eventto be enabled + * Flags - Reserved * * RETURN: Status * - * DESCRIPTION: Disable an ACPI event (fixed and general purpose) + * DESCRIPTION: Disable an ACPI event (fixed) * ******************************************************************************/ ACPI_STATUS AcpiDisableEvent ( UINT32 Event, - UINT32 Type, UINT32 Flags) { ACPI_STATUS Status = AE_OK; UINT32 Value; - ACPI_GPE_EVENT_INFO *GpeEventInfo; ACPI_FUNCTION_TRACE ("AcpiDisableEvent"); - /* The Type must be either Fixed Event or GPE */ + /* Decode the Fixed Event */ - switch (Type) + if (Event > ACPI_EVENT_MAX) { - case ACPI_EVENT_FIXED: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - /* Decode the Fixed Event */ + /* + * Disable the requested fixed event (by writing a zero to the + * enable register bit) + */ + Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, + 0, ACPI_MTX_LOCK); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } - if (Event > ACPI_EVENT_MAX) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, + &Value, ACPI_MTX_LOCK); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } - /* - * Disable the requested fixed event (by writing a zero to the - * enable register bit) - */ - Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, - 0, ACPI_MTX_LOCK); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + if (Value != 0) + { + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not disable %s events\n", AcpiUtGetEventName (Event))); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); + } - Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].EnableRegisterId, - &Value, ACPI_MTX_LOCK); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + return_ACPI_STATUS (Status); +} - if (Value != 0) - { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Could not disable %s events\n", AcpiUtGetEventName (Event))); - return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); - } - break; +/******************************************************************************* + * + * FUNCTION: AcpiDisableGpe + * + * PARAMETERS: GpeDevice - Parent GPE Device + * GpeNumber - GPE level within the GPE block + * Flags - Just enable, or also wake enable? + * Called from ISR or not + * + * RETURN: Status + * + * DESCRIPTION: Disable an ACPI event (general purpose) + * + ******************************************************************************/ + +ACPI_STATUS +AcpiDisableGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT32 Flags) +{ + ACPI_STATUS Status = AE_OK; + ACPI_GPE_EVENT_INFO *GpeEventInfo; - case ACPI_EVENT_GPE: - /* Ensure that we have a valid GPE number */ + ACPI_FUNCTION_TRACE ("AcpiDisableGpe"); - GpeEventInfo = AcpiEvGetGpeEventInfo (Event); - if (!GpeEventInfo) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - /* - * Only disable the requested GPE number for wake if specified. - * Otherwise, turn it totally off - */ + /* Use semaphore lock if not executing at interrupt level */ - if (Flags & ACPI_EVENT_WAKE_DISABLE) - { - AcpiHwDisableGpeForWakeup (GpeEventInfo); - } - else + if (Flags & ACPI_NOT_ISR) + { + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) { - Status = AcpiHwDisableGpe (GpeEventInfo); + return_ACPI_STATUS (Status); } - break; + } + /* Ensure that we have a valid GPE number */ - default: + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { Status = AE_BAD_PARAMETER; + goto UnlockAndExit; } + /* + * Only disable the requested GPE number for wake if specified. + * Otherwise, turn it totally off + */ + if (Flags & ACPI_EVENT_WAKE_DISABLE) + { + AcpiHwDisableGpeForWakeup (GpeEventInfo); + } + else + { + Status = AcpiHwDisableGpe (GpeEventInfo); + } + +UnlockAndExit: + if (Flags & ACPI_NOT_ISR) + { + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + } return_ACPI_STATUS (Status); } @@ -434,68 +494,96 @@ AcpiDisableEvent ( * * FUNCTION: AcpiClearEvent * - * PARAMETERS: Event - The fixed event or GPE to be cleared - * Type - The type of event + * PARAMETERS: Event - The fixed event to be cleared * * RETURN: Status * - * DESCRIPTION: Clear an ACPI event (fixed and general purpose) + * DESCRIPTION: Clear an ACPI event (fixed) * ******************************************************************************/ ACPI_STATUS AcpiClearEvent ( - UINT32 Event, - UINT32 Type) + UINT32 Event) { ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; ACPI_FUNCTION_TRACE ("AcpiClearEvent"); - /* The Type must be either Fixed Event or GPE */ + /* Decode the Fixed Event */ - switch (Type) + if (Event > ACPI_EVENT_MAX) { - case ACPI_EVENT_FIXED: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - /* Decode the Fixed Event */ + /* + * Clear the requested fixed event (By writing a one to the + * status register bit) + */ + Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].StatusRegisterId, + 1, ACPI_MTX_LOCK); - if (Event > ACPI_EVENT_MAX) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + return_ACPI_STATUS (Status); +} - /* - * Clear the requested fixed event (By writing a one to the - * status register bit) - */ - Status = AcpiSetRegister (AcpiGbl_FixedEventInfo[Event].StatusRegisterId, - 1, ACPI_MTX_LOCK); - break; +/******************************************************************************* + * + * FUNCTION: AcpiClearGpe + * + * PARAMETERS: GpeDevice - Parent GPE Device + * GpeNumber - GPE level within the GPE block + * Flags - Called from an ISR or not + * + * RETURN: Status + * + * DESCRIPTION: Clear an ACPI event (general purpose) + * + ******************************************************************************/ - case ACPI_EVENT_GPE: +ACPI_STATUS +AcpiClearGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT32 Flags) +{ + ACPI_STATUS Status = AE_OK; + ACPI_GPE_EVENT_INFO *GpeEventInfo; - /* Ensure that we have a valid GPE number */ - GpeEventInfo = AcpiEvGetGpeEventInfo (Event); - if (!GpeEventInfo) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } + ACPI_FUNCTION_TRACE ("AcpiClearGpe"); - Status = AcpiHwClearGpe (GpeEventInfo); - break; + /* Use semaphore lock if not executing at interrupt level */ - default: + if (Flags & ACPI_NOT_ISR) + { + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + } + + /* Ensure that we have a valid GPE number */ + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { Status = AE_BAD_PARAMETER; + goto UnlockAndExit; } + Status = AcpiHwClearGpe (GpeEventInfo); + +UnlockAndExit: + if (Flags & ACPI_NOT_ISR) + { + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + } return_ACPI_STATUS (Status); } @@ -504,9 +592,8 @@ AcpiClearEvent ( * * FUNCTION: AcpiGetEventStatus * - * PARAMETERS: Event - The fixed event or GPE - * Type - The type of event - * Status - Where the current status of the event will + * PARAMETERS: Event - The fixed event + * Event Status - Where the current status of the event will * be returned * * RETURN: Status @@ -515,15 +602,12 @@ AcpiClearEvent ( * ******************************************************************************/ - ACPI_STATUS AcpiGetEventStatus ( UINT32 Event, - UINT32 Type, ACPI_EVENT_STATUS *EventStatus) { ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; ACPI_FUNCTION_TRACE ("AcpiGetEventStatus"); @@ -534,48 +618,245 @@ AcpiGetEventStatus ( return_ACPI_STATUS (AE_BAD_PARAMETER); } + /* Decode the Fixed Event */ - /* The Type must be either Fixed Event or GPE */ - - switch (Type) + if (Event > ACPI_EVENT_MAX) { - case ACPI_EVENT_FIXED: + return_ACPI_STATUS (AE_BAD_PARAMETER); + } - /* Decode the Fixed Event */ + /* Get the status of the requested fixed event */ - if (Event > ACPI_EVENT_MAX) + Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].StatusRegisterId, + EventStatus, ACPI_MTX_LOCK); + + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiGetGpeStatus + * + * PARAMETERS: GpeDevice - Parent GPE Device + * GpeNumber - GPE level within the GPE block + * Flags - Called from an ISR or not + * Event Status - 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, + UINT32 Flags, + ACPI_EVENT_STATUS *EventStatus) +{ + ACPI_STATUS Status = AE_OK; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + + + ACPI_FUNCTION_TRACE ("AcpiGetGpeStatus"); + + + /* Use semaphore lock if not executing at interrupt level */ + + if (Flags & ACPI_NOT_ISR) + { + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + return_ACPI_STATUS (Status); } + } - /* Get the status of the requested fixed event */ + /* Ensure that we have a valid GPE number */ - Status = AcpiGetRegister (AcpiGbl_FixedEventInfo[Event].StatusRegisterId, - EventStatus, ACPI_MTX_LOCK); - break; + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + /* Obtain status on the requested GPE number */ + Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); + +UnlockAndExit: + if (Flags & ACPI_NOT_ISR) + { + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + } + return_ACPI_STATUS (Status); +} - case ACPI_EVENT_GPE: - /* Ensure that we have a valid GPE number */ +/******************************************************************************* + * + * FUNCTION: AcpiInstallGpeBlock + * + * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device + * GpeBlockAddress - Address and SpaceID + * RegisterCount - Number of GPE register pairs in the block + * InterruptLevel - H/W interrupt for the block + * + * RETURN: Status + * + * DESCRIPTION: Create and Install a block of GPE registers + * + ******************************************************************************/ - GpeEventInfo = AcpiEvGetGpeEventInfo (Event); - if (!GpeEventInfo) +ACPI_STATUS +AcpiInstallGpeBlock ( + ACPI_HANDLE GpeDevice, + ACPI_GENERIC_ADDRESS *GpeBlockAddress, + UINT32 RegisterCount, + UINT32 InterruptLevel) +{ + 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 = AcpiNsMapHandleToNode (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, InterruptLevel, &GpeBlock); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + + /* Get the DeviceObject attached to the node */ + + ObjDesc = AcpiNsGetAttachedObject (Node); + if (!ObjDesc) + { + /* No object, create a new one */ + + ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); + if (!ObjDesc) { - return_ACPI_STATUS (AE_BAD_PARAMETER); + Status = AE_NO_MEMORY; + goto UnlockAndExit; } - /* Obtain status on the requested GPE number */ + Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); - Status = AcpiHwGetGpeStatus (Event, EventStatus); - break; + /* Remove local reference to the object */ + AcpiUtRemoveReference (ObjDesc); - default: - Status = AE_BAD_PARAMETER; + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } } + /* Install the GPE block in the DeviceObject */ + + ObjDesc->Device.GpeBlock = GpeBlock; + + +UnlockAndExit: + (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (Status); } +/******************************************************************************* + * + * 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 = AcpiNsMapHandleToNode (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); +} + |