Loading drivers/acpi/acpica/acobject.h +1 −0 Original line number Diff line number Diff line Loading @@ -284,6 +284,7 @@ struct acpi_object_addr_handler { acpi_adr_space_handler handler; struct acpi_namespace_node *node; /* Parent device */ void *context; acpi_mutex context_mutex; acpi_adr_space_setup setup; union acpi_operand_object *region_list; /* Regions using this handler */ union acpi_operand_object *next; Loading drivers/acpi/acpica/evhandler.c +7 −0 Original line number Diff line number Diff line Loading @@ -489,6 +489,13 @@ acpi_ev_install_space_handler(struct acpi_namespace_node *node, /* Init handler obj */ status = acpi_os_create_mutex(&handler_obj->address_space.context_mutex); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(handler_obj); goto unlock_and_exit; } handler_obj->address_space.space_id = (u8)space_id; handler_obj->address_space.handler_flags = flags; handler_obj->address_space.region_list = NULL; Loading drivers/acpi/acpica/evregion.c +43 −26 Original line number Diff line number Diff line Loading @@ -112,6 +112,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, union acpi_operand_object *region_obj2; void *region_context = NULL; struct acpi_connection_info *context; acpi_mutex context_mutex; u8 context_locked; acpi_physical_address address; ACPI_FUNCTION_TRACE(ev_address_space_dispatch); Loading @@ -136,6 +138,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } context = handler_desc->address_space.context; context_mutex = handler_desc->address_space.context_mutex; context_locked = FALSE; /* * It may be the case that the region has never been initialized. Loading Loading @@ -204,6 +208,23 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, handler = handler_desc->address_space.handler; address = (region_obj->region.address + region_offset); ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(region_obj->region. space_id))); if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the interpreter. */ acpi_ex_exit_interpreter(); } /* * Special handling for generic_serial_bus and general_purpose_io: * There are three extra parameters that must be passed to the Loading @@ -212,48 +233,39 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * 2) Length of the above buffer * 3) Actual access length from the access_as() op * * Since we pass these extra parameters via the context, which is * shared between threads, we must lock the context to avoid these * parameters being changed from another thread before the handler * has completed running. * * In addition, for general_purpose_io, the Address and bit_width fields * are defined as follows: * 1) Address is the pin number index of the field (bit offset from * the previous Connection) * 2) bit_width is the actual bit length of the field (number of pins) */ if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS || region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && context && field_obj) { /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; context->length = field_obj->field.resource_length; context->access_length = field_obj->field.access_length; status = acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); if (ACPI_FAILURE(status)) { goto re_enter_interpreter; } if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && context && field_obj) { context_locked = TRUE; /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; context->length = field_obj->field.resource_length; context->access_length = field_obj->field.access_length; if (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) { address = field_obj->field.pin_number_index; bit_width = field_obj->field.bit_length; } ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(region_obj->region. space_id))); if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the interpreter. */ acpi_ex_exit_interpreter(); } /* Call the handler */ Loading @@ -261,6 +273,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, status = handler(function, address, bit_width, value, context, region_obj2->extra.region_context); if (context_locked) { acpi_os_release_mutex(context_mutex); } if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", acpi_ut_get_region_name(region_obj->region. Loading @@ -277,6 +293,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } } re_enter_interpreter: if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* Loading drivers/acpi/acpica/evxfregn.c +2 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,8 @@ acpi_remove_address_space_handler(acpi_handle device, /* Now we can delete the handler object */ acpi_os_release_mutex(handler_obj->address_space. context_mutex); acpi_ut_remove_reference(handler_obj); goto unlock_and_exit; } Loading Loading
drivers/acpi/acpica/acobject.h +1 −0 Original line number Diff line number Diff line Loading @@ -284,6 +284,7 @@ struct acpi_object_addr_handler { acpi_adr_space_handler handler; struct acpi_namespace_node *node; /* Parent device */ void *context; acpi_mutex context_mutex; acpi_adr_space_setup setup; union acpi_operand_object *region_list; /* Regions using this handler */ union acpi_operand_object *next; Loading
drivers/acpi/acpica/evhandler.c +7 −0 Original line number Diff line number Diff line Loading @@ -489,6 +489,13 @@ acpi_ev_install_space_handler(struct acpi_namespace_node *node, /* Init handler obj */ status = acpi_os_create_mutex(&handler_obj->address_space.context_mutex); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(handler_obj); goto unlock_and_exit; } handler_obj->address_space.space_id = (u8)space_id; handler_obj->address_space.handler_flags = flags; handler_obj->address_space.region_list = NULL; Loading
drivers/acpi/acpica/evregion.c +43 −26 Original line number Diff line number Diff line Loading @@ -112,6 +112,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, union acpi_operand_object *region_obj2; void *region_context = NULL; struct acpi_connection_info *context; acpi_mutex context_mutex; u8 context_locked; acpi_physical_address address; ACPI_FUNCTION_TRACE(ev_address_space_dispatch); Loading @@ -136,6 +138,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } context = handler_desc->address_space.context; context_mutex = handler_desc->address_space.context_mutex; context_locked = FALSE; /* * It may be the case that the region has never been initialized. Loading Loading @@ -204,6 +208,23 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, handler = handler_desc->address_space.handler; address = (region_obj->region.address + region_offset); ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(region_obj->region. space_id))); if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the interpreter. */ acpi_ex_exit_interpreter(); } /* * Special handling for generic_serial_bus and general_purpose_io: * There are three extra parameters that must be passed to the Loading @@ -212,48 +233,39 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * 2) Length of the above buffer * 3) Actual access length from the access_as() op * * Since we pass these extra parameters via the context, which is * shared between threads, we must lock the context to avoid these * parameters being changed from another thread before the handler * has completed running. * * In addition, for general_purpose_io, the Address and bit_width fields * are defined as follows: * 1) Address is the pin number index of the field (bit offset from * the previous Connection) * 2) bit_width is the actual bit length of the field (number of pins) */ if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS || region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && context && field_obj) { /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; context->length = field_obj->field.resource_length; context->access_length = field_obj->field.access_length; status = acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); if (ACPI_FAILURE(status)) { goto re_enter_interpreter; } if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && context && field_obj) { context_locked = TRUE; /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; context->length = field_obj->field.resource_length; context->access_length = field_obj->field.access_length; if (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) { address = field_obj->field.pin_number_index; bit_width = field_obj->field.bit_length; } ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(region_obj->region. space_id))); if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * For handlers other than the default (supplied) handlers, we must * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the interpreter. */ acpi_ex_exit_interpreter(); } /* Call the handler */ Loading @@ -261,6 +273,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, status = handler(function, address, bit_width, value, context, region_obj2->extra.region_context); if (context_locked) { acpi_os_release_mutex(context_mutex); } if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", acpi_ut_get_region_name(region_obj->region. Loading @@ -277,6 +293,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } } re_enter_interpreter: if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* Loading
drivers/acpi/acpica/evxfregn.c +2 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,8 @@ acpi_remove_address_space_handler(acpi_handle device, /* Now we can delete the handler object */ acpi_os_release_mutex(handler_obj->address_space. context_mutex); acpi_ut_remove_reference(handler_obj); goto unlock_and_exit; } Loading