diff options
| author | Jung-uk Kim <jkim@FreeBSD.org> | 2012-06-20 17:51:04 +0000 |
|---|---|---|
| committer | Jung-uk Kim <jkim@FreeBSD.org> | 2012-06-20 17:51:04 +0000 |
| commit | 705c538931446b23ef7f028f71c9da55c78bbf23 (patch) | |
| tree | f634c2ad6dfa6f49c5aaabc64f8bb79b74dda5a7 /source/components/events | |
| parent | fa948a817cf9dae39dc632f9bf48a8af37244a0e (diff) | |
Notes
Diffstat (limited to 'source/components/events')
| -rw-r--r-- | source/components/events/evgpe.c | 15 | ||||
| -rw-r--r-- | source/components/events/evgpeutil.c | 19 | ||||
| -rw-r--r-- | source/components/events/evxfgpe.c | 70 |
3 files changed, 88 insertions, 16 deletions
diff --git a/source/components/events/evgpe.c b/source/components/events/evgpe.c index a3781a55c66b..623795a83619 100644 --- a/source/components/events/evgpe.c +++ b/source/components/events/evgpe.c @@ -518,6 +518,7 @@ AcpiEvAsynchExecuteGpeMethod ( ACPI_STATUS Status; ACPI_GPE_EVENT_INFO *LocalGpeEventInfo; ACPI_EVALUATE_INFO *Info; + ACPI_GPE_NOTIFY_INFO *Notify; ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); @@ -573,10 +574,18 @@ AcpiEvAsynchExecuteGpeMethod ( * completes. The notify handlers are NOT invoked synchronously * from this thread -- because handlers may in turn run other * control methods. + * + * June 2012: Expand implicit notify mechanism to support + * notifies on multiple device objects. */ - Status = AcpiEvQueueNotifyRequest ( - LocalGpeEventInfo->Dispatch.DeviceNode, - ACPI_NOTIFY_DEVICE_WAKE); + Notify = LocalGpeEventInfo->Dispatch.NotifyList; + while (ACPI_SUCCESS (Status) && Notify) + { + Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode, + ACPI_NOTIFY_DEVICE_WAKE); + + Notify = Notify->Next; + } break; case ACPI_GPE_DISPATCH_METHOD: diff --git a/source/components/events/evgpeutil.c b/source/components/events/evgpeutil.c index 70580cd853c9..00057350c46a 100644 --- a/source/components/events/evgpeutil.c +++ b/source/components/events/evgpeutil.c @@ -391,6 +391,8 @@ AcpiEvDeleteGpeHandlers ( void *Context) { ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_GPE_NOTIFY_INFO *Notify; + ACPI_GPE_NOTIFY_INFO *Next; UINT32 i; UINT32 j; @@ -412,10 +414,27 @@ AcpiEvDeleteGpeHandlers ( if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) { + /* Delete an installed handler block */ + ACPI_FREE (GpeEventInfo->Dispatch.Handler); GpeEventInfo->Dispatch.Handler = NULL; GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; } + else if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + ACPI_GPE_DISPATCH_NOTIFY) + { + /* Delete the implicit notification device list */ + + Notify = GpeEventInfo->Dispatch.NotifyList; + while (Notify) + { + Next = Notify->Next; + ACPI_FREE (Notify); + Notify = Next; + } + GpeEventInfo->Dispatch.NotifyList = NULL; + GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; + } } } diff --git a/source/components/events/evxfgpe.c b/source/components/events/evxfgpe.c index c0dd88c77752..daea88804ddb 100644 --- a/source/components/events/evxfgpe.c +++ b/source/components/events/evxfgpe.c @@ -295,9 +295,10 @@ AcpiSetupGpeForWake ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber) { - ACPI_STATUS Status = AE_BAD_PARAMETER; + ACPI_STATUS Status; ACPI_GPE_EVENT_INFO *GpeEventInfo; ACPI_NAMESPACE_NODE *DeviceNode; + ACPI_GPE_NOTIFY_INFO *Notify; ACPI_CPU_FLAGS Flags; @@ -338,26 +339,69 @@ AcpiSetupGpeForWake ( /* Ensure that we have a valid GPE number */ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); - if (GpeEventInfo) + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + /* + * If there is no method or handler for this GPE, then the + * WakeDevice will be notified whenever this GPE fires. This is + * known as an "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) { /* - * 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). + * This is the first device for implicit notify on this GPE. + * Just set the flags here, and enter the NOTIFY block below. */ - if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_NONE) + GpeEventInfo->Flags = + (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); + } + + /* + * If we already have an implicit notify on this GPE, add + * this device to the notify list. + */ + if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + ACPI_GPE_DISPATCH_NOTIFY) + { + /* Ensure that the device is not already in the list */ + + Notify = GpeEventInfo->Dispatch.NotifyList; + while (Notify) { - GpeEventInfo->Flags = - (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); - GpeEventInfo->Dispatch.DeviceNode = DeviceNode; + if (Notify->DeviceNode == DeviceNode) + { + Status = AE_ALREADY_EXISTS; + goto UnlockAndExit; + } + Notify = Notify->Next; } - GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; - Status = AE_OK; + /* Add this device to the notify list for this GPE */ + + Notify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); + if (!Notify) + { + Status = AE_NO_MEMORY; + goto UnlockAndExit; + } + + Notify->DeviceNode = DeviceNode; + Notify->Next = GpeEventInfo->Dispatch.NotifyList; + GpeEventInfo->Dispatch.NotifyList = Notify; } + /* Mark the GPE as a possible wake event */ + + GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; + Status = AE_OK; + +UnlockAndExit: AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); return_ACPI_STATUS (Status); } |
