diff options
| author | Jung-uk Kim <jkim@FreeBSD.org> | 2015-02-05 00:09:52 +0000 |
|---|---|---|
| committer | Jung-uk Kim <jkim@FreeBSD.org> | 2015-02-05 00:09:52 +0000 |
| commit | 2872953d4a9c9c4e0fc0b9ab37d0e962909625a0 (patch) | |
| tree | d125aa97a34ea51a7841c57256f738956bc3de3d /source/components/events | |
| parent | e8991236d498c9646c20a8acf0236cf3342dad6f (diff) | |
Notes
Diffstat (limited to 'source/components/events')
| -rw-r--r-- | source/components/events/evevent.c | 2 | ||||
| -rw-r--r-- | source/components/events/evglock.c | 2 | ||||
| -rw-r--r-- | source/components/events/evgpe.c | 158 | ||||
| -rw-r--r-- | source/components/events/evgpeblk.c | 7 | ||||
| -rw-r--r-- | source/components/events/evgpeinit.c | 10 | ||||
| -rw-r--r-- | source/components/events/evgpeutil.c | 64 | ||||
| -rw-r--r-- | source/components/events/evhandler.c | 2 | ||||
| -rw-r--r-- | source/components/events/evmisc.c | 2 | ||||
| -rw-r--r-- | source/components/events/evregion.c | 2 | ||||
| -rw-r--r-- | source/components/events/evrgnini.c | 2 | ||||
| -rw-r--r-- | source/components/events/evsci.c | 2 | ||||
| -rw-r--r-- | source/components/events/evxface.c | 139 | ||||
| -rw-r--r-- | source/components/events/evxfevnt.c | 2 | ||||
| -rw-r--r-- | source/components/events/evxfgpe.c | 67 | ||||
| -rw-r--r-- | source/components/events/evxfregn.c | 2 |
15 files changed, 279 insertions, 184 deletions
diff --git a/source/components/events/evevent.c b/source/components/events/evevent.c index 9a410c4700f5..96e4682c0ec9 100644 --- a/source/components/events/evevent.c +++ b/source/components/events/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evglock.c b/source/components/events/evglock.c index fb127882267a..7617d5cefeb0 100644 --- a/source/components/events/evglock.c +++ b/source/components/events/evglock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evgpe.c b/source/components/events/evgpe.c index 939402559e0b..4e635ce77e2b 100644 --- a/source/components/events/evgpe.c +++ b/source/components/events/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -131,18 +131,6 @@ AcpiEvEnableGpe ( ACPI_FUNCTION_TRACE (EvEnableGpe); - /* - * 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) == - ACPI_GPE_DISPATCH_NONE) - { - return_ACPI_STATUS (AE_NO_HANDLER); - } - /* Clear the GPE (of stale events) */ Status = AcpiHwClearGpe (GpeEventInfo); @@ -153,7 +141,7 @@ AcpiEvEnableGpe ( /* Enable the requested GPE */ - Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); + Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE_SAVE); return_ACPI_STATUS (Status); } @@ -243,7 +231,7 @@ AcpiEvRemoveGpeReference ( Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); if (ACPI_SUCCESS (Status)) { - Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); + Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE_SAVE); } if (ACPI_FAILURE (Status)) @@ -383,7 +371,11 @@ AcpiEvGpeDetect ( { ACPI_STATUS Status; ACPI_GPE_BLOCK_INFO *GpeBlock; + ACPI_NAMESPACE_NODE *GpeDevice; ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + UINT32 GpeNumber; + ACPI_GPE_HANDLER_INFO *GpeHandlerInfo; UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; UINT8 EnabledStatusByte; UINT32 StatusReg; @@ -414,6 +406,8 @@ AcpiEvGpeDetect ( GpeBlock = GpeXruptList->GpeBlockListHead; while (GpeBlock) { + GpeDevice = GpeBlock->Node; + /* * Read all of the 8-bit GPE status and enable registers in this GPE * block, saving all of them. Find all currently active GP events. @@ -482,16 +476,55 @@ AcpiEvGpeDetect ( { /* Examine one GPE bit */ + GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i * + ACPI_GPE_REGISTER_WIDTH) + j]; + GpeNumber = j + GpeRegisterInfo->BaseGpeNumber; + if (EnabledStatusByte & (1 << j)) { - /* - * Found an active GPE. Dispatch the event to a handler - * or method. - */ - IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node, - &GpeBlock->EventInfo[((ACPI_SIZE) i * - ACPI_GPE_REGISTER_WIDTH) + j], - j + GpeRegisterInfo->BaseGpeNumber); + /* Invoke global event handler if present */ + + AcpiGpeCount++; + if (AcpiGbl_GlobalEventHandler) + { + AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, + GpeDevice, GpeNumber, + AcpiGbl_GlobalEventHandlerContext); + } + + /* Found an active GPE */ + + if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_RAW_HANDLER) + { + /* Dispatch the event to a raw handler */ + + GpeHandlerInfo = GpeEventInfo->Dispatch.Handler; + + /* + * There is no protection around the namespace node + * and the GPE handler to ensure a safe destruction + * because: + * 1. The namespace node is expected to always + * exist after loading a table. + * 2. The GPE handler is expected to be flushed by + * AcpiOsWaitEventsComplete() before the + * destruction. + */ + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + IntStatus |= GpeHandlerInfo->Address ( + GpeDevice, GpeNumber, GpeHandlerInfo->Context); + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + } + else + { + /* + * Dispatch the event to a standard handler or + * method. + */ + IntStatus |= AcpiEvGpeDispatch (GpeDevice, + GpeEventInfo, GpeNumber); + } } } } @@ -527,8 +560,7 @@ AcpiEvAsynchExecuteGpeMethod ( void *Context) { ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; - ACPI_STATUS Status; - ACPI_GPE_EVENT_INFO *LocalGpeEventInfo; + ACPI_STATUS Status = AE_OK; ACPI_EVALUATE_INFO *Info; ACPI_GPE_NOTIFY_INFO *Notify; @@ -536,49 +568,9 @@ AcpiEvAsynchExecuteGpeMethod ( ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); - /* Allocate a local GPE block */ - - LocalGpeEventInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_EVENT_INFO)); - if (!LocalGpeEventInfo) - { - ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, - "while handling a GPE")); - return_VOID; - } - - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - ACPI_FREE (LocalGpeEventInfo); - return_VOID; - } - - /* Must revalidate the GpeNumber/GpeBlock */ - - if (!AcpiEvValidGpeEvent (GpeEventInfo)) - { - Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - ACPI_FREE (LocalGpeEventInfo); - return_VOID; - } - - /* - * Take a snapshot of the GPE info for this level - we copy the info to - * prevent a race condition with RemoveHandler/RemoveBlock. - */ - ACPI_MEMCPY (LocalGpeEventInfo, GpeEventInfo, - sizeof (ACPI_GPE_EVENT_INFO)); - - Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - ACPI_FREE (LocalGpeEventInfo); - return_VOID; - } - /* Do the correct dispatch - normal method or implicit notify */ - switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) + switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags)) { case ACPI_GPE_DISPATCH_NOTIFY: /* @@ -592,7 +584,7 @@ AcpiEvAsynchExecuteGpeMethod ( * June 2012: Expand implicit notify mechanism to support * notifies on multiple device objects. */ - Notify = LocalGpeEventInfo->Dispatch.NotifyList; + Notify = GpeEventInfo->Dispatch.NotifyList; while (ACPI_SUCCESS (Status) && Notify) { Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode, @@ -617,7 +609,7 @@ AcpiEvAsynchExecuteGpeMethod ( * 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->PrefixNode = GpeEventInfo->Dispatch.MethodNode; Info->Flags = ACPI_IGNORE_RETURN_VALUE; Status = AcpiNsEvaluate (Info); @@ -628,23 +620,26 @@ AcpiEvAsynchExecuteGpeMethod ( { ACPI_EXCEPTION ((AE_INFO, Status, "while evaluating GPE method [%4.4s]", - AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode))); + AcpiUtGetNodeName (GpeEventInfo->Dispatch.MethodNode))); } break; default: - return_VOID; /* Should never happen */ + goto ErrorExit; /* Should never happen */ } /* Defer enabling of GPE until all notify handlers are done */ Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, - AcpiEvAsynchEnableGpe, LocalGpeEventInfo); - if (ACPI_FAILURE (Status)) + AcpiEvAsynchEnableGpe, GpeEventInfo); + if (ACPI_SUCCESS (Status)) { - ACPI_FREE (LocalGpeEventInfo); + return_VOID; } + +ErrorExit: + AcpiEvAsynchEnableGpe (GpeEventInfo); return_VOID; } @@ -668,11 +663,13 @@ AcpiEvAsynchEnableGpe ( void *Context) { ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; + ACPI_CPU_FLAGS Flags; + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); (void) AcpiEvFinishGpe (GpeEventInfo); + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - ACPI_FREE (GpeEventInfo); return; } @@ -713,7 +710,7 @@ AcpiEvFinishGpe ( /* * Enable this GPE, conditionally. This means that the GPE will - * only be physically enabled if the EnableForRun bit is set + * only be physically enabled if the EnableMask bit is set * in the EventInfo. */ (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); @@ -751,15 +748,6 @@ AcpiEvGpeDispatch ( ACPI_FUNCTION_TRACE (EvGpeDispatch); - /* Invoke global event handler if present */ - - AcpiGpeCount++; - if (AcpiGbl_GlobalEventHandler) - { - AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice, - GpeNumber, AcpiGbl_GlobalEventHandlerContext); - } - /* * Always disable the GPE so that it does not keep firing before * any asynchronous activity completes (either from the execution @@ -802,7 +790,7 @@ AcpiEvGpeDispatch ( * If there is neither a handler nor a method, leave the GPE * disabled. */ - switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) + switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags)) { case ACPI_GPE_DISPATCH_HANDLER: diff --git a/source/components/events/evgpeblk.c b/source/components/events/evgpeblk.c index f0db7eed8ba3..d3342a5b0f6b 100644 --- a/source/components/events/evgpeblk.c +++ b/source/components/events/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -518,8 +518,9 @@ AcpiEvInitializeGpeBlock ( * 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) || + if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_NONE) || + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_HANDLER) || + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_RAW_HANDLER) || (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) { continue; diff --git a/source/components/events/evgpeinit.c b/source/components/events/evgpeinit.c index ac54f000f507..1943d23ea431 100644 --- a/source/components/events/evgpeinit.c +++ b/source/components/events/evgpeinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -419,15 +419,17 @@ AcpiEvMatchGpeMethod ( return_ACPI_STATUS (AE_OK); } - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_HANDLER) + if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_HANDLER) || + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_RAW_HANDLER)) { /* If there is already a handler, ignore this GPE method */ return_ACPI_STATUS (AE_OK); } - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_METHOD) { /* diff --git a/source/components/events/evgpeutil.c b/source/components/events/evgpeutil.c index c23858967f3b..18cbbf7cc706 100644 --- a/source/components/events/evgpeutil.c +++ b/source/components/events/evgpeutil.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -115,60 +115,6 @@ UnlockAndExit: /******************************************************************************* * - * FUNCTION: AcpiEvValidGpeEvent - * - * PARAMETERS: GpeEventInfo - Info for this GPE - * - * RETURN: TRUE if the GpeEvent is valid - * - * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. - * Should be called only when the GPE lists are semaphore locked - * and not subject to change. - * - ******************************************************************************/ - -BOOLEAN -AcpiEvValidGpeEvent ( - ACPI_GPE_EVENT_INFO *GpeEventInfo) -{ - ACPI_GPE_XRUPT_INFO *GpeXruptBlock; - ACPI_GPE_BLOCK_INFO *GpeBlock; - - - ACPI_FUNCTION_ENTRY (); - - - /* No need for spin lock since we are not changing any list elements */ - - /* Walk the GPE interrupt levels */ - - GpeXruptBlock = AcpiGbl_GpeXruptListHead; - while (GpeXruptBlock) - { - GpeBlock = GpeXruptBlock->GpeBlockListHead; - - /* Walk the GPE blocks on this interrupt level */ - - while (GpeBlock) - { - if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) && - (&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo)) - { - return (TRUE); - } - - GpeBlock = GpeBlock->Next; - } - - GpeXruptBlock = GpeXruptBlock->Next; - } - - return (FALSE); -} - - -/******************************************************************************* - * * FUNCTION: AcpiEvGetGpeDevice * * PARAMETERS: GPE_WALK_CALLBACK @@ -416,8 +362,10 @@ AcpiEvDeleteGpeHandlers ( GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i * ACPI_GPE_REGISTER_WIDTH) + j]; - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_HANDLER) + if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_HANDLER) || + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_RAW_HANDLER)) { /* Delete an installed handler block */ @@ -425,7 +373,7 @@ AcpiEvDeleteGpeHandlers ( GpeEventInfo->Dispatch.Handler = NULL; GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; } - else if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + else if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_NOTIFY) { /* Delete the implicit notification device list */ diff --git a/source/components/events/evhandler.c b/source/components/events/evhandler.c index b5138e9f29d5..c797abe1f7d7 100644 --- a/source/components/events/evhandler.c +++ b/source/components/events/evhandler.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evmisc.c b/source/components/events/evmisc.c index 72f671845e00..accf22298b92 100644 --- a/source/components/events/evmisc.c +++ b/source/components/events/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evregion.c b/source/components/events/evregion.c index 14ac452b0108..e578fb41390a 100644 --- a/source/components/events/evregion.c +++ b/source/components/events/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evrgnini.c b/source/components/events/evrgnini.c index 78c8868b35f8..6cf1b031fbfa 100644 --- a/source/components/events/evrgnini.c +++ b/source/components/events/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evsci.c b/source/components/events/evsci.c index 664b40858ea4..93b307e4c1b5 100644 --- a/source/components/events/evsci.c +++ b/source/components/events/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evxface.c b/source/components/events/evxface.c index 4e25f615b5cf..0a3b6c831168 100644 --- a/source/components/events/evxface.c +++ b/source/components/events/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,21 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evxface") +#if (!ACPI_REDUCED_HARDWARE) + +/* Local prototypes */ + +static ACPI_STATUS +AcpiEvInstallGpeHandler ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT32 Type, + BOOLEAN IsRawHandler, + ACPI_GPE_HANDLER Address, + void *Context); + +#endif + /******************************************************************************* * @@ -822,27 +837,31 @@ ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) /******************************************************************************* * - * FUNCTION: AcpiInstallGpeHandler + * FUNCTION: AcpiEvInstallGpeHandler * * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT * defined GPEs) * GpeNumber - The GPE number within the GPE block * Type - Whether this GPE should be treated as an * edge- or level-triggered interrupt. + * IsRawHandler - Whether this GPE should be handled using + * the special GPE handler mode. * Address - Address of the handler * Context - Value passed to the handler on each GPE * * RETURN: Status * - * DESCRIPTION: Install a handler for a General Purpose Event. + * DESCRIPTION: Internal function to install a handler for a General Purpose + * Event. * ******************************************************************************/ -ACPI_STATUS -AcpiInstallGpeHandler ( +static ACPI_STATUS +AcpiEvInstallGpeHandler ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, UINT32 Type, + BOOLEAN IsRawHandler, ACPI_GPE_HANDLER Address, void *Context) { @@ -852,7 +871,7 @@ AcpiInstallGpeHandler ( ACPI_CPU_FLAGS Flags; - ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); + ACPI_FUNCTION_TRACE (EvInstallGpeHandler); /* Parameter validation */ @@ -890,8 +909,10 @@ AcpiInstallGpeHandler ( /* Make sure that there isn't a handler there already */ - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_HANDLER) + if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_HANDLER) || + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == + ACPI_GPE_DISPATCH_RAW_HANDLER)) { Status = AE_ALREADY_EXISTS; goto FreeAndExit; @@ -908,8 +929,10 @@ AcpiInstallGpeHandler ( * 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)) && + if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == + ACPI_GPE_DISPATCH_METHOD) || + (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == + ACPI_GPE_DISPATCH_NOTIFY)) && GpeEventInfo->RuntimeCount) { Handler->OriginallyEnabled = TRUE; @@ -930,7 +953,8 @@ AcpiInstallGpeHandler ( /* 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); + GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ? + ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER)); AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); @@ -945,11 +969,91 @@ FreeAndExit: goto UnlockAndExit; } + +/******************************************************************************* + * + * FUNCTION: AcpiInstallGpeHandler + * + * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT + * defined GPEs) + * GpeNumber - The GPE number within the GPE block + * Type - Whether this GPE should be treated as an + * edge- or level-triggered interrupt. + * Address - Address of the handler + * Context - Value passed to the handler on each GPE + * + * RETURN: Status + * + * DESCRIPTION: Install a handler for a General Purpose Event. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiInstallGpeHandler ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT32 Type, + ACPI_GPE_HANDLER Address, + void *Context) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); + + + Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, FALSE, + Address, Context); + + return_ACPI_STATUS (Status); +} + ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) /******************************************************************************* * + * FUNCTION: AcpiInstallGpeRawHandler + * + * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT + * defined GPEs) + * GpeNumber - The GPE number within the GPE block + * Type - Whether this GPE should be treated as an + * edge- or level-triggered interrupt. + * Address - Address of the handler + * Context - Value passed to the handler on each GPE + * + * RETURN: Status + * + * DESCRIPTION: Install a handler for a General Purpose Event. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiInstallGpeRawHandler ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT32 Type, + ACPI_GPE_HANDLER Address, + void *Context) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler); + + + Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, TRUE, + Address, Context); + + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler) + + +/******************************************************************************* + * * FUNCTION: AcpiRemoveGpeHandler * * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT @@ -1004,8 +1108,10 @@ AcpiRemoveGpeHandler ( /* Make sure that a handler is indeed installed */ - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != - ACPI_GPE_DISPATCH_HANDLER) + if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != + ACPI_GPE_DISPATCH_HANDLER) && + (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != + ACPI_GPE_DISPATCH_RAW_HANDLER)) { Status = AE_NOT_EXIST; goto UnlockAndExit; @@ -1022,6 +1128,7 @@ AcpiRemoveGpeHandler ( /* Remove the handler */ Handler = GpeEventInfo->Dispatch.Handler; + GpeEventInfo->Dispatch.Handler = NULL; /* Restore Method node (if any), set dispatch flags */ @@ -1035,8 +1142,10 @@ AcpiRemoveGpeHandler ( * enabled, it should be enabled at this point to restore the * post-initialization configuration. */ - if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) || - (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) && + if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == + ACPI_GPE_DISPATCH_METHOD) || + (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == + ACPI_GPE_DISPATCH_NOTIFY)) && Handler->OriginallyEnabled) { (void) AcpiEvAddGpeReference (GpeEventInfo); diff --git a/source/components/events/evxfevnt.c b/source/components/events/evxfevnt.c index e007541dbc89..81675ed2b6f3 100644 --- a/source/components/events/evxfevnt.c +++ b/source/components/events/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/source/components/events/evxfgpe.c b/source/components/events/evxfgpe.c index 56f54f347418..79a055c833c4 100644 --- a/source/components/events/evxfgpe.c +++ b/source/components/events/evxfgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -147,7 +147,7 @@ AcpiEnableGpe ( GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); if (GpeEventInfo) { - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != + if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != ACPI_GPE_DISPATCH_NONE) { Status = AcpiEvAddGpeReference (GpeEventInfo); @@ -221,12 +221,21 @@ ACPI_EXPORT_SYMBOL (AcpiDisableGpe) * 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. + * the reference count mechanism used in the AcpiEnableGpe(), + * AcpiDisableGpe() interfaces. + * This API is typically used by the GPE raw handler mode driver + * to switch between the polling mode and the interrupt mode after + * the driver has enabled the GPE. + * The APIs should be invoked in this order: + * AcpiEnableGpe() <- Ensure the reference count > 0 + * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode + * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode + * AcpiDisableGpe() <- Decrease the reference count * - * 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. + * Note: If a GPE is shared by 2 silicon components, then both the drivers + * should support GPE polling mode or disabling the GPE for long period + * for one driver may break the other. So use it with care since all + * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. * ******************************************************************************/ @@ -261,7 +270,7 @@ AcpiSetGpe ( { case ACPI_GPE_ENABLE: - Status = AcpiEvEnableGpe (GpeEventInfo); + Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); break; case ACPI_GPE_DISABLE: @@ -430,7 +439,7 @@ AcpiSetupGpeForWake ( * known as an "implicit notify". Note: The GPE is assumed to be * level-triggered (for windows compatibility). */ - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_NONE) { /* @@ -445,7 +454,7 @@ AcpiSetupGpeForWake ( * If we already have an implicit notify on this GPE, add * this device to the notify list. */ - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == ACPI_GPE_DISPATCH_NOTIFY) { /* Ensure that the device is not already in the list */ @@ -802,6 +811,44 @@ AcpiEnableAllRuntimeGpes ( ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) +/****************************************************************************** + * + * FUNCTION: AcpiEnableAllWakeupGpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in + * all GPE blocks. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEnableAllWakeupGpes ( + void) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes); + + + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + Status = AcpiHwEnableAllWakeupGpes (); + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes) + + /******************************************************************************* * * FUNCTION: AcpiInstallGpeBlock diff --git a/source/components/events/evxfregn.c b/source/components/events/evxfregn.c index 3a44b3fe55d0..1126bbe53b78 100644 --- a/source/components/events/evxfregn.c +++ b/source/components/events/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2014, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without |
