ACPICA: Implicit notify support
Subsystems (2)
PATCH 4/6 ACPICA: Implicit notify support
This feature provides an automatic device notification for wake devices when a wakeup GPE occurs and there is no corresponding GPE method or handler. Rather than ignoring such a GPE, an implicit AML Notify operation is performed on the parent device object.
This feature is not part of the ACPI specification and is provided for Windows compatibility only.
--- drivers/acpi/acpica/acevents.h | 2 + drivers/acpi/acpica/aclocal.h | 1 + drivers/acpi/acpica/evgpe.c | 242 ++++++++++++++++++++++++--------------- drivers/acpi/acpica/evgpeblk.c | 11 ++- drivers/acpi/acpica/evgpeinit.c | 1 + drivers/acpi/acpica/evxfgpe.c | 58 ++++++++-- drivers/acpi/scan.c | 3 +- include/acpi/acpixf.h | 6 +- include/acpi/actypes.h | 37 ++++--- 9 files changed, 237 insertions(+), 124 deletions(-)
drivers/acpi/acpica/acevents.h +2 -0
@@ -91,6 +91,8 @@ struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,struct acpi_gpe_block_info *gpe_block); +acpi_status acpi_ev_finish_gpe (struct acpi_gpe_event_info *gpe_event_info); +/* * evgpeblk - Upper-level GPE block support */
drivers/acpi/acpica/aclocal.h +1 -0
@@ -419,6 +419,7 @@ struct acpi_gpe_handler_info {union acpi_gpe_dispatch_info {struct acpi_namespace_node *method_node;/* Method node for this GPE level */ struct acpi_gpe_handler_info *handler;/* Installed GPE handler */ +struct acpi_namespace_node *device_node;/* Parent _PRW device for implicit notify */ };/*
drivers/acpi/acpica/evgpe.c +151 -91
330 lines not on this page · raw message
drivers/acpi/acpica/evgpeblk.c +8 -3
@@ -472,9 +472,14 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, gpe_index = (i *ACPI_GPE_REGISTER_WIDTH ) + j; gpe_event_info = &gpe_block->event_info[gpe_index]; -/* Ignore GPEs that have no corresponding _Lxx/_Exx method */ - -if (!(gpe_event_info->flags &ACPI_GPE_DISPATCH_METHOD ) +/* +* Ignore GPEs that have no corresponding _Lxx/_Exx method +* and GPEs that are used to wake the system +*/ +if (((gpe_event_info->flags &ACPI_GPE_DISPATCH_MASK ) == +ACPI_GPE_DISPATCH_NONE ) + || ((gpe_event_info->flags &ACPI_GPE_DISPATCH_MASK ) + ==ACPI_GPE_DISPATCH_HANDLER ) || (gpe_event_info->flags &ACPI_GPE_CAN_WAKE )) {continue ; }
drivers/acpi/acpica/evgpeinit.c +1 -0
@@ -412,6 +412,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,* Add the GPE information from above to the gpe_event_info block for * use during dispatch of this GPE. */ + gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK ); gpe_event_info->flags |= (u8)(type |ACPI_GPE_DISPATCH_METHOD ); gpe_event_info->dispatch.method_node = method_node;
drivers/acpi/acpica/evxfgpe.c +47 -11
86 lines not on this page · raw message
drivers/acpi/scan.c +2 -1
@@ -750,7 +750,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, device->wakeup.resources.handles[i] = element->reference.handle; } -acpi_setup_gpe_for_wake (device->wakeup.gpe_device, device->wakeup.gpe_number); +acpi_setup_gpe_for_wake (device->wakeup.gpe_device,NULL , + device->wakeup.gpe_number);return AE_OK ; }
include/acpi/acpixf.h +4 -2
@@ -292,10 +292,12 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number);acpi_status acpi_disable_gpe (acpi_handle gpe_device,u32 gpe_number); -acpi_status acpi_setup_gpe_for_wake (acpi_handle gpe_device,u32 gpe_number); -acpi_status acpi_clear_gpe (acpi_handle gpe_device,u32 gpe_number); +acpi_status +acpi_setup_gpe_for_wake (acpi_handle parent_device, +acpi_handle gpe_device,u32 gpe_number); +acpi_status acpi_set_gpe_wake_mask (acpi_handle gpe_device,u32 gpe_number,u8 action); acpi_status
include/acpi/actypes.h +21 -16
@@ -664,25 +664,26 @@ typedef u32 acpi_event_status;/* * GPE info flags - Per GPE -* +-------+---+-+-+ -* | 7:4 |3:2|1|0| -* +-------+---+-+-+ -* | | | | -* | | | +--- Interrupt type: edge or level triggered -* | | +----- GPE can wake the system -* | +-------- Type of dispatch:to method, handler, or none -* +-------------- <Reserved> +* +-------+-+-+---+ +* | 7:4 |3|2|1:0| +* +-------+-+-+---+ +* | | | | +* | | | +-- Type of dispatch:to method, handler, notify, or none +* | | +----- Interrupt type: edge or level triggered +* | +------- Is a Wake GPE +* +------------ <Reserved> */ -#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 -#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 -#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 +#define ACPI_GPE_DISPATCH_NONE (u8) 0x00 +#define ACPI_GPE_DISPATCH_METHOD (u8) 0x01 +#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x02 +#define ACPI_GPE_DISPATCH_NOTIFY (u8) 0x03 +#define ACPI_GPE_DISPATCH_MASK (u8) 0x03 -#define ACPI_GPE_CAN_WAKE (u8) 0x02 +#define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x04 +#define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 +#define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x04 -#define ACPI_GPE_DISPATCH_MASK (u8) 0x0C -#define ACPI_GPE_DISPATCH_HANDLER (u8) 0x04 -#define ACPI_GPE_DISPATCH_METHOD (u8) 0x08 -#define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 +#define ACPI_GPE_CAN_WAKE (u8) 0x08/* * Flags for GPE and Lock interfaces
@@ -954,6 +955,10 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);#define ACPI_INTERRUPT_NOT_HANDLED 0x00#define ACPI_INTERRUPT_HANDLED 0x01 +/* GPE handler return values */ + +#define ACPI_REENABLE_GPE 0x80 +/* Length of 32-bit EISAID values when converted back to a string */ #define ACPI_EISAID_STRING_SIZE 8/* Includes null terminator */
Signature · 1 line
1.5.3
Quoted 8 lines · Lin Ming
This feature provides an automatic device notification for wake devices when a wakeup GPE occurs and there is no corresponding GPE method or handler. Rather than ignoring such a GPE, an implicit AML Notify operation is performed on the parent device object.
This feature is not part of the ACPI specification and is provided for Windows compatibility only.Signed-off-by Lin Ming <[email protected]>
This patch does two things at a time, while only one is mentioned in the changelog. The second one is that you change the local variable in acpi_ev_asynch_execute_gpe_method() back into a pointer:
...
Quoted 25 lines
static void
ACPI_SYSTEM_XFACEacpi_ev_asynch_execute_gpe_method(void *context){drivers/acpi/acpica/evgpe.c +11
-2-struct acpi_gpe_event_info *gpe_event_info = (void *)context; +struct acpi_gpe_event_info *gpe_event_info = context;acpi_status status; -struct acpi_gpe_event_info local_gpe_event_info; +struct acpi_gpe_event_info *local_gpe_event_info;struct acpi_evaluate_info *info;ACPI_FUNCTION_TRACE (ev_asynch_execute_gpe_method); +/* Allocate a local GPE block */ + + local_gpe_event_info = +ACPI_ALLOCATE_ZEROED (sizeof (struct acpi_gpe_event_info )); +if (!local_gpe_event_info) { +ACPI_EXCEPTION ((AE_INFO ,AE_NO_MEMORY ,"while handling a GPE" )); + return_VOID; + } + status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS );if (ACPI_FAILURE (status)) { return_VOID;
drivers/acpi/acpica/evgpe.c static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) · line 484
Quoted 7 lines
drivers/acpi/acpica/evgpe.c +1
-1@@ -468,7 +479,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)* Take a snapshot of the GPE info for this level - we copy the info to * prevent a race condition with remove_handler/remove_block. */ -ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, +ACPI_MEMCPY (local_gpe_event_info, gpe_event_info,sizeof (struct acpi_gpe_event_info ));
etc. and that should go into a separate patch.
I mean, first fix this local variable mess and _then_ introdiuce the new feature. Doing both in one step is guaranteed to confuse people.
Thanks,
Rafael
Quoted 50 lines · Rafael J. Wysocki
Quoted 8 lines · Lin Ming
This feature provides an automatic device notification for wake devices when a wakeup GPE occurs and there is no corresponding GPE method or handler. Rather than ignoring such a GPE, an implicit AML Notify operation is performed on the parent device object.
This feature is not part of the ACPI specification and is provided for Windows compatibility only.Signed-off-by Lin Ming <[email protected]>This patch does two things at a time, while only one is mentioned in the changelog. The second one is that you change the local variable in
acpi_ev_asynch_execute_gpe_method()back into a pointer:...
Quoted 25 lines
static void
ACPI_SYSTEM_XFACEacpi_ev_asynch_execute_gpe_method(void *context){drivers/acpi/acpica/evgpe.c +11
-2-struct acpi_gpe_event_info *gpe_event_info = (void *)context; +struct acpi_gpe_event_info *gpe_event_info = context;acpi_status status; -struct acpi_gpe_event_info local_gpe_event_info; +struct acpi_gpe_event_info *local_gpe_event_info;struct acpi_evaluate_info *info;ACPI_FUNCTION_TRACE (ev_asynch_execute_gpe_method); +/* Allocate a local GPE block */ + + local_gpe_event_info = +ACPI_ALLOCATE_ZEROED (sizeof (struct acpi_gpe_event_info )); +if (!local_gpe_event_info) { +ACPI_EXCEPTION ((AE_INFO ,AE_NO_MEMORY ,"while handling a GPE" )); + return_VOID; + } + status =acpi_ut_acquire_mutex (ACPI_MTX_EVENTS );if (ACPI_FAILURE (status)) { return_VOID;drivers/acpi/acpica/evgpe.c static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) · line 484
Quoted 7 lines
drivers/acpi/acpica/evgpe.c +1
-1@@ -468,7 +479,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)* Take a snapshot of the GPE info for this level - we copy the info to * prevent a race condition with remove_handler/remove_block. */ -ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, +ACPI_MEMCPY (local_gpe_event_info, gpe_event_info,sizeof (struct acpi_gpe_event_info ));etc. and that should go into a separate patch.
Quoted 2 lines
I mean, first fix this local variable mess and _then_ introdiuce the new feature. Doing both in one step is guaranteed to confuse people.
OK, I'll separate it.
Thanks for review.