diff options
| -rw-r--r-- | drivers/acpi/acpica/acglobal.h | 3 | ||||
| -rw-r--r-- | drivers/acpi/acpica/aclocal.h | 13 | ||||
| -rw-r--r-- | drivers/acpi/acpica/acobject.h | 9 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evmisc.c | 185 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evxface.c | 440 | ||||
| -rw-r--r-- | drivers/acpi/acpica/exdump.c | 25 | ||||
| -rw-r--r-- | drivers/acpi/acpica/utdelete.c | 24 | ||||
| -rw-r--r-- | drivers/acpi/acpica/utglobal.c | 4 | ||||
| -rw-r--r-- | include/acpi/actypes.h | 4 |
9 files changed, 266 insertions, 441 deletions
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 4f7d3f57d05c..dec7994d405c 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
| @@ -278,8 +278,7 @@ ACPI_EXTERN acpi_cache_t *acpi_gbl_operand_cache; | |||
| 278 | 278 | ||
| 279 | /* Global handlers */ | 279 | /* Global handlers */ |
| 280 | 280 | ||
| 281 | ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify; | 281 | ACPI_EXTERN struct acpi_global_notify_handler acpi_gbl_global_notify[2]; |
| 282 | ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify; | ||
| 283 | ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler; | 282 | ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler; |
| 284 | ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; | 283 | ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; |
| 285 | ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; | 284 | ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index e3922ca20e7f..28f677834bfd 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
| @@ -600,13 +600,22 @@ acpi_status(*acpi_parse_downwards) (struct acpi_walk_state * walk_state, | |||
| 600 | 600 | ||
| 601 | typedef acpi_status(*acpi_parse_upwards) (struct acpi_walk_state * walk_state); | 601 | typedef acpi_status(*acpi_parse_upwards) (struct acpi_walk_state * walk_state); |
| 602 | 602 | ||
| 603 | /* Global handlers for AML Notifies */ | ||
| 604 | |||
| 605 | struct acpi_global_notify_handler { | ||
| 606 | acpi_notify_handler handler; | ||
| 607 | void *context; | ||
| 608 | }; | ||
| 609 | |||
| 603 | /* | 610 | /* |
| 604 | * Notify info - used to pass info to the deferred notify | 611 | * Notify info - used to pass info to the deferred notify |
| 605 | * handler/dispatcher. | 612 | * handler/dispatcher. |
| 606 | */ | 613 | */ |
| 607 | struct acpi_notify_info { | 614 | struct acpi_notify_info { |
| 608 | ACPI_STATE_COMMON struct acpi_namespace_node *node; | 615 | ACPI_STATE_COMMON u8 handler_list_id; |
| 609 | union acpi_operand_object *handler_obj; | 616 | struct acpi_namespace_node *node; |
| 617 | union acpi_operand_object *handler_list_head; | ||
| 618 | struct acpi_global_notify_handler *global; | ||
| 610 | }; | 619 | }; |
| 611 | 620 | ||
| 612 | /* Generic state is union of structs above */ | 621 | /* Generic state is union of structs above */ |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index c065078ca83b..39a2b84120be 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
| @@ -206,8 +206,7 @@ struct acpi_object_method { | |||
| 206 | * Common fields for objects that support ASL notifications | 206 | * Common fields for objects that support ASL notifications |
| 207 | */ | 207 | */ |
| 208 | #define ACPI_COMMON_NOTIFY_INFO \ | 208 | #define ACPI_COMMON_NOTIFY_INFO \ |
| 209 | union acpi_operand_object *system_notify; /* Handler for system notifies */\ | 209 | union acpi_operand_object *notify_list[2]; /* Handlers for system/device notifies */\ |
| 210 | union acpi_operand_object *device_notify; /* Handler for driver notifies */\ | ||
| 211 | union acpi_operand_object *handler; /* Handler for Address space */ | 210 | union acpi_operand_object *handler; /* Handler for Address space */ |
| 212 | 211 | ||
| 213 | struct acpi_object_notify_common { /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */ | 212 | struct acpi_object_notify_common { /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */ |
| @@ -296,10 +295,10 @@ struct acpi_object_buffer_field { | |||
| 296 | 295 | ||
| 297 | struct acpi_object_notify_handler { | 296 | struct acpi_object_notify_handler { |
| 298 | ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */ | 297 | ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */ |
| 299 | u32 handler_type; | 298 | u32 handler_type; /* Type: Device/System/Both */ |
| 300 | acpi_notify_handler handler; | 299 | acpi_notify_handler handler; /* Handler address */ |
| 301 | void *context; | 300 | void *context; |
| 302 | struct acpi_object_notify_handler *next; | 301 | union acpi_operand_object *next[2]; /* Device and System handler lists */ |
| 303 | }; | 302 | }; |
| 304 | 303 | ||
| 305 | struct acpi_object_addr_handler { | 304 | struct acpi_object_addr_handler { |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 51ef9f5e002d..381fce93a561 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
| @@ -101,102 +101,77 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
| 101 | u32 notify_value) | 101 | u32 notify_value) |
| 102 | { | 102 | { |
| 103 | union acpi_operand_object *obj_desc; | 103 | union acpi_operand_object *obj_desc; |
| 104 | union acpi_operand_object *handler_obj = NULL; | 104 | union acpi_operand_object *handler_list_head = NULL; |
| 105 | union acpi_generic_state *notify_info; | 105 | union acpi_generic_state *info; |
| 106 | u8 handler_list_id = 0; | ||
| 106 | acpi_status status = AE_OK; | 107 | acpi_status status = AE_OK; |
| 107 | 108 | ||
| 108 | ACPI_FUNCTION_NAME(ev_queue_notify_request); | 109 | ACPI_FUNCTION_NAME(ev_queue_notify_request); |
| 109 | 110 | ||
| 110 | /* | 111 | /* Are Notifies allowed on this object? */ |
| 111 | * For value 0x03 (Ejection Request), may need to run a device method. | ||
| 112 | * For value 0x02 (Device Wake), if _PRW exists, may need to run | ||
| 113 | * the _PS0 method. | ||
| 114 | * For value 0x80 (Status Change) on the power button or sleep button, | ||
| 115 | * initiate soft-off or sleep operation. | ||
| 116 | * | ||
| 117 | * For all cases, simply dispatch the notify to the handler. | ||
| 118 | */ | ||
| 119 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| 120 | "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", | ||
| 121 | acpi_ut_get_node_name(node), | ||
| 122 | acpi_ut_get_type_name(node->type), notify_value, | ||
| 123 | acpi_ut_get_notify_name(notify_value), node)); | ||
| 124 | 112 | ||
| 125 | /* Get the notify object attached to the NS Node */ | 113 | if (!acpi_ev_is_notify_object(node)) { |
| 126 | 114 | return (AE_TYPE); | |
| 127 | obj_desc = acpi_ns_get_attached_object(node); | 115 | } |
| 128 | if (obj_desc) { | ||
| 129 | |||
| 130 | /* We have the notify object, Get the correct handler */ | ||
| 131 | |||
| 132 | switch (node->type) { | ||
| 133 | 116 | ||
| 134 | /* Notify is allowed only on these types */ | 117 | /* Get the correct notify list type (System or Device) */ |
| 135 | 118 | ||
| 136 | case ACPI_TYPE_DEVICE: | 119 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { |
| 137 | case ACPI_TYPE_THERMAL: | 120 | handler_list_id = ACPI_SYSTEM_HANDLER_LIST; |
| 138 | case ACPI_TYPE_PROCESSOR: | 121 | } else { |
| 122 | handler_list_id = ACPI_DEVICE_HANDLER_LIST; | ||
| 123 | } | ||
| 139 | 124 | ||
| 140 | if (notify_value <= ACPI_MAX_SYS_NOTIFY) { | 125 | /* Get the notify object attached to the namespace Node */ |
| 141 | handler_obj = | ||
| 142 | obj_desc->common_notify.system_notify; | ||
| 143 | } else { | ||
| 144 | handler_obj = | ||
| 145 | obj_desc->common_notify.device_notify; | ||
| 146 | } | ||
| 147 | break; | ||
| 148 | 126 | ||
| 149 | default: | 127 | obj_desc = acpi_ns_get_attached_object(node); |
| 128 | if (obj_desc) { | ||
| 150 | 129 | ||
| 151 | /* All other types are not supported */ | 130 | /* We have an attached object, Get the correct handler list */ |
| 152 | 131 | ||
| 153 | return (AE_TYPE); | 132 | handler_list_head = |
| 154 | } | 133 | obj_desc->common_notify.notify_list[handler_list_id]; |
| 155 | } | 134 | } |
| 156 | 135 | ||
| 157 | /* | 136 | /* |
| 158 | * If there is a handler to run, schedule the dispatcher. | 137 | * If there is no notify handler (Global or Local) |
| 159 | * Check for: | 138 | * for this object, just ignore the notify |
| 160 | * 1) Global system notify handler | ||
| 161 | * 2) Global device notify handler | ||
| 162 | * 3) Per-device notify handler | ||
| 163 | */ | 139 | */ |
| 164 | if ((acpi_gbl_system_notify.handler && | 140 | if (!acpi_gbl_global_notify[handler_list_id].handler |
| 165 | (notify_value <= ACPI_MAX_SYS_NOTIFY)) || | 141 | && !handler_list_head) { |
| 166 | (acpi_gbl_device_notify.handler && | 142 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 167 | (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) { | 143 | "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n", |
| 168 | notify_info = acpi_ut_create_generic_state(); | 144 | acpi_ut_get_node_name(node), notify_value, |
| 169 | if (!notify_info) { | 145 | node)); |
| 170 | return (AE_NO_MEMORY); | ||
