u8 sync_level;
union acpi_operand_object *mutex;
u8 *aml_start;
- ACPI_INTERNAL_METHOD implementation;
+ union {
+ ACPI_INTERNAL_METHOD implementation;
+ union acpi_operand_object *handler;
+ } extra;
+
u32 aml_length;
u8 thread_count;
acpi_owner_id owner_id;
/* Invoke an internal method if necessary */
if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
- status = obj_desc->method.implementation(next_walk_state);
+ status = obj_desc->method.extra.implementation(next_walk_state);
if (status == AE_OK) {
status = AE_CTRL_TERMINATE;
}
handler_obj = obj_desc->thermal_zone.handler;
break;
+ case ACPI_TYPE_METHOD:
+ /*
+ * If we are executing module level code, the original
+ * Node's object was replaced by this Method object and we
+ * saved the handler in the method object.
+ *
+ * See acpi_ns_exec_module_code
+ */
+ if (obj_desc->method.
+ flags & AOPOBJ_MODULE_LEVEL) {
+ handler_obj =
+ obj_desc->method.extra.handler;
+ }
+ break;
+
default:
/* Ignore other objects */
break;
obj_desc->method.method_flags =
AML_METHOD_INTERNAL_ONLY;
- obj_desc->method.implementation =
+ obj_desc->method.extra.implementation =
acpi_ut_osi_implementation;
#endif
break;
method_obj->method.next_object);
type = acpi_ns_get_type(parent_node);
+ /*
+ * Get the region handler and save it in the method object. We may need
+ * this if an operation region declaration causes a _REG method to be run.
+ *
+ * We can't do this in acpi_ps_link_module_code because
+ * acpi_gbl_root_node->Object is NULL at PASS1.
+ */
+ if ((type == ACPI_TYPE_DEVICE) && parent_node->object) {
+ method_obj->method.extra.handler =
+ parent_node->object->device.handler;
+ }
+
/* Must clear next_object (acpi_ns_attach_object needs the field) */
method_obj->method.next_object = NULL;
/* Invoke an internal method if necessary */
if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
- status = info->obj_desc->method.implementation(walk_state);
+ status =
+ info->obj_desc->method.extra.implementation(walk_state);
info->return_object = walk_state->return_desc;
/* Cleanup states */