diff options
author | jkim <jkim@FreeBSD.org> | 2013-08-23 23:25:58 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2013-08-23 23:25:58 +0000 |
commit | f2dafdee67fe5c7ef109890d8685b9a5cbebecf1 (patch) | |
tree | 7ada92196422cd8bffb5c7d81220d52437161bb0 /sys/contrib/dev/acpica/components/events | |
parent | 5017a032d282b2ecdd81495733cc73657ff2b8fb (diff) | |
download | FreeBSD-src-f2dafdee67fe5c7ef109890d8685b9a5cbebecf1.zip FreeBSD-src-f2dafdee67fe5c7ef109890d8685b9a5cbebecf1.tar.gz |
Merge ACPICA 20130823.
Diffstat (limited to 'sys/contrib/dev/acpica/components/events')
-rw-r--r-- | sys/contrib/dev/acpica/components/events/evgpeutil.c | 2 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/components/events/evmisc.c | 18 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/components/events/evregion.c | 26 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/components/events/evsci.c | 87 | ||||
-rw-r--r-- | sys/contrib/dev/acpica/components/events/evxface.c | 163 |
5 files changed, 267 insertions, 29 deletions
diff --git a/sys/contrib/dev/acpica/components/events/evgpeutil.c b/sys/contrib/dev/acpica/components/events/evgpeutil.c index 1841f9d..35caa5a 100644 --- a/sys/contrib/dev/acpica/components/events/evgpeutil.c +++ b/sys/contrib/dev/acpica/components/events/evgpeutil.c @@ -216,7 +216,7 @@ AcpiEvGetGpeDevice ( * * FUNCTION: AcpiEvGetGpeXruptBlock * - * PARAMETERS: InterruptNumber - Interrupt for a GPE block + * PARAMETERS: InterruptNumber - Interrupt for a GPE block * * RETURN: A GPE interrupt block * diff --git a/sys/contrib/dev/acpica/components/events/evmisc.c b/sys/contrib/dev/acpica/components/events/evmisc.c index 740eb28..547534b 100644 --- a/sys/contrib/dev/acpica/components/events/evmisc.c +++ b/sys/contrib/dev/acpica/components/events/evmisc.c @@ -292,15 +292,6 @@ AcpiEvTerminate ( Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL); - /* Remove SCI handler */ - - Status = AcpiEvRemoveSciHandler (); - if (ACPI_FAILURE(Status)) - { - ACPI_ERROR ((AE_INFO, - "Could not remove SCI handler")); - } - Status = AcpiEvRemoveGlobalLockHandler (); if (ACPI_FAILURE(Status)) { @@ -311,6 +302,15 @@ AcpiEvTerminate ( AcpiGbl_EventsInitialized = FALSE; } + /* Remove SCI handlers */ + + Status = AcpiEvRemoveAllSciHandlers (); + if (ACPI_FAILURE(Status)) + { + ACPI_ERROR ((AE_INFO, + "Could not remove SCI handler")); + } + /* Deallocate all handler objects installed within GPE info structs */ Status = AcpiEvWalkGpeList (AcpiEvDeleteGpeHandlers, NULL); diff --git a/sys/contrib/dev/acpica/components/events/evregion.c b/sys/contrib/dev/acpica/components/events/evregion.c index 43fe9b2..d469d6e 100644 --- a/sys/contrib/dev/acpica/components/events/evregion.c +++ b/sys/contrib/dev/acpica/components/events/evregion.c @@ -234,18 +234,12 @@ AcpiEvAddressSpaceDispatch ( { RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; - if (RegionObj2->Extra.RegionContext) - { - /* The handler for this region was already installed */ - - ACPI_FREE (RegionContext); - } - else + /* + * Save the returned context for use in all accesses to + * the handler for this particular region + */ + if (!(RegionObj2->Extra.RegionContext)) { - /* - * Save the returned context for use in all accesses to - * this particular region - */ RegionObj2->Extra.RegionContext = RegionContext; } } @@ -261,7 +255,6 @@ AcpiEvAddressSpaceDispatch ( ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset), AcpiUtGetRegionName (RegionObj->Region.SpaceId))); - /* * Special handling for GenericSerialBus and GeneralPurposeIo: * There are three extra parameters that must be passed to the @@ -424,6 +417,15 @@ AcpiEvDetachRegion( Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE, HandlerObj->AddressSpace.Context, RegionContext); + /* + * RegionContext should have been released by the deactivate + * operation. We don't need access to it anymore here. + */ + if (RegionContext) + { + *RegionContext = NULL; + } + /* Init routine may fail, Just ignore errors */ if (ACPI_FAILURE (Status)) diff --git a/sys/contrib/dev/acpica/components/events/evsci.c b/sys/contrib/dev/acpica/components/events/evsci.c index ed87c63..4fa84f3 100644 --- a/sys/contrib/dev/acpica/components/events/evsci.c +++ b/sys/contrib/dev/acpica/components/events/evsci.c @@ -61,6 +61,57 @@ AcpiEvSciXruptHandler ( /******************************************************************************* * + * FUNCTION: AcpiEvSciDispatch + * + * PARAMETERS: None + * + * RETURN: Status code indicates whether interrupt was handled. + * + * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers. + * + ******************************************************************************/ + +UINT32 +AcpiEvSciDispatch ( + void) +{ + ACPI_SCI_HANDLER_INFO *SciHandler; + ACPI_CPU_FLAGS Flags; + UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; + + + ACPI_FUNCTION_NAME (EvSciDispatch); + + + /* Are there any host-installed SCI handlers? */ + + if (!AcpiGbl_SciHandlerList) + { + return (IntStatus); + } + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Invoke all host-installed SCI handlers */ + + SciHandler = AcpiGbl_SciHandlerList; + while (SciHandler) + { + /* Invoke the installed handler (at interrupt level) */ + + IntStatus |= SciHandler->Address ( + SciHandler->Context); + + SciHandler = SciHandler->Next; + } + + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return (IntStatus); +} + + +/******************************************************************************* + * * FUNCTION: AcpiEvSciXruptHandler * * PARAMETERS: Context - Calling Context @@ -100,6 +151,10 @@ AcpiEvSciXruptHandler ( */ InterruptHandled |= AcpiEvGpeDetect (GpeXruptList); + /* Invoke all host-installed SCI handlers */ + + InterruptHandled |= AcpiEvSciDispatch (); + AcpiSciCount++; return_UINT32 (InterruptHandled); } @@ -129,14 +184,13 @@ AcpiEvGpeXruptHandler ( /* - * We are guaranteed by the ACPI CA initialization/shutdown code that + * We are guaranteed by the ACPICA initialization/shutdown code that * if this interrupt handler is installed, ACPI is enabled. */ /* GPEs: Check for and dispatch any GPEs that have occurred */ InterruptHandled |= AcpiEvGpeDetect (GpeXruptList); - return_UINT32 (InterruptHandled); } @@ -171,15 +225,15 @@ AcpiEvInstallSciHandler ( /****************************************************************************** * - * FUNCTION: AcpiEvRemoveSciHandler + * FUNCTION: AcpiEvRemoveAllSciHandlers * * PARAMETERS: none * - * RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not + * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not * installed to begin with * * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be - * taken. + * taken. Remove all host-installed SCI handlers. * * Note: It doesn't seem important to disable all events or set the event * enable registers to their original values. The OS should disable @@ -189,13 +243,15 @@ AcpiEvInstallSciHandler ( ******************************************************************************/ ACPI_STATUS -AcpiEvRemoveSciHandler ( +AcpiEvRemoveAllSciHandlers ( void) { + ACPI_SCI_HANDLER_INFO *SciHandler; + ACPI_CPU_FLAGS Flags; ACPI_STATUS Status; - ACPI_FUNCTION_TRACE (EvRemoveSciHandler); + ACPI_FUNCTION_TRACE (EvRemoveAllSciHandlers); /* Just let the OS remove the handler and disable the level */ @@ -203,6 +259,23 @@ AcpiEvRemoveSciHandler ( Status = AcpiOsRemoveInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt, AcpiEvSciXruptHandler); + if (!AcpiGbl_SciHandlerList) + { + return (Status); + } + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Free all host-installed SCI handlers */ + + while (AcpiGbl_SciHandlerList) + { + SciHandler = AcpiGbl_SciHandlerList; + AcpiGbl_SciHandlerList = SciHandler->Next; + ACPI_FREE (SciHandler); + } + + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); return_ACPI_STATUS (Status); } diff --git a/sys/contrib/dev/acpica/components/events/evxface.c b/sys/contrib/dev/acpica/components/events/evxface.c index cf5dbed..4ed3247 100644 --- a/sys/contrib/dev/acpica/components/events/evxface.c +++ b/sys/contrib/dev/acpica/components/events/evxface.c @@ -435,6 +435,169 @@ ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) #if (!ACPI_REDUCED_HARDWARE) /******************************************************************************* * + * FUNCTION: AcpiInstallSciHandler + * + * PARAMETERS: Address - Address of the handler + * Context - Value passed to the handler on each SCI + * + * RETURN: Status + * + * DESCRIPTION: Install a handler for a System Control Interrupt. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiInstallSciHandler ( + ACPI_SCI_HANDLER Address, + void *Context) +{ + ACPI_SCI_HANDLER_INFO *NewSciHandler; + ACPI_SCI_HANDLER_INFO *SciHandler; + ACPI_CPU_FLAGS Flags; + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiInstallSciHandler); + + + if (!Address) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* Allocate and init a handler object */ + + NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO)); + if (!NewSciHandler) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + NewSciHandler->Address = Address; + NewSciHandler->Context = Context; + + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + goto Exit; + } + + /* Lock list during installation */ + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + SciHandler = AcpiGbl_SciHandlerList; + + /* Ensure handler does not already exist */ + + while (SciHandler) + { + if (Address == SciHandler->Address) + { + Status = AE_ALREADY_EXISTS; + goto UnlockAndExit; + } + + SciHandler = SciHandler->Next; + } + + /* Install the new handler into the global list (at head) */ + + NewSciHandler->Next = AcpiGbl_SciHandlerList; + AcpiGbl_SciHandlerList = NewSciHandler; + + +UnlockAndExit: + + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + +Exit: + if (ACPI_FAILURE (Status)) + { + ACPI_FREE (NewSciHandler); + } + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiRemoveSciHandler + * + * PARAMETERS: Address - Address of the handler + * + * RETURN: Status + * + * DESCRIPTION: Remove a handler for a System Control Interrupt. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiRemoveSciHandler ( + ACPI_SCI_HANDLER Address) +{ + ACPI_SCI_HANDLER_INFO *PrevSciHandler; + ACPI_SCI_HANDLER_INFO *NextSciHandler; + ACPI_CPU_FLAGS Flags; + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler); + + + if (!Address) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* Remove the SCI handler with lock */ + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + PrevSciHandler = NULL; + NextSciHandler = AcpiGbl_SciHandlerList; + while (NextSciHandler) + { + if (NextSciHandler->Address == Address) + { + /* Unlink and free the SCI handler info block */ + + if (PrevSciHandler) + { + PrevSciHandler->Next = NextSciHandler->Next; + } + else + { + AcpiGbl_SciHandlerList = NextSciHandler->Next; + } + + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + ACPI_FREE (NextSciHandler); + goto UnlockAndExit; + } + + PrevSciHandler = NextSciHandler; + NextSciHandler = NextSciHandler->Next; + } + + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + Status = AE_NOT_EXIST; + + +UnlockAndExit: + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * * FUNCTION: AcpiInstallGlobalEventHandler * * PARAMETERS: Handler - Pointer to the global event handler function |