diff options
Diffstat (limited to 'drivers/acpi/acpica/exprep.c')
| -rw-r--r-- | drivers/acpi/acpica/exprep.c | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 98a331d2249b..7aae29f73d3f 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c | |||
| @@ -355,12 +355,10 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, | |||
| 355 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); | 355 | return_ACPI_STATUS(AE_AML_OPERAND_VALUE); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | /* Setup width (access granularity) fields */ | 358 | /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */ |
| 359 | 359 | ||
| 360 | obj_desc->common_field.access_byte_width = (u8) | 360 | obj_desc->common_field.access_byte_width = (u8) |
| 361 | ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */ | 361 | ACPI_DIV_8(access_bit_width); |
| 362 | |||
| 363 | obj_desc->common_field.access_bit_width = (u8) access_bit_width; | ||
| 364 | 362 | ||
| 365 | /* | 363 | /* |
| 366 | * base_byte_offset is the address of the start of the field within the | 364 | * base_byte_offset is the address of the start of the field within the |
| @@ -405,8 +403,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
| 405 | { | 403 | { |
| 406 | union acpi_operand_object *obj_desc; | 404 | union acpi_operand_object *obj_desc; |
| 407 | union acpi_operand_object *second_desc = NULL; | 405 | union acpi_operand_object *second_desc = NULL; |
| 408 | u32 type; | ||
| 409 | acpi_status status; | 406 | acpi_status status; |
| 407 | u32 access_byte_width; | ||
| 408 | u32 type; | ||
| 410 | 409 | ||
| 411 | ACPI_FUNCTION_TRACE(ex_prep_field_value); | 410 | ACPI_FUNCTION_TRACE(ex_prep_field_value); |
| 412 | 411 | ||
| @@ -421,8 +420,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
| 421 | type = acpi_ns_get_type(info->region_node); | 420 | type = acpi_ns_get_type(info->region_node); |
| 422 | if (type != ACPI_TYPE_REGION) { | 421 | if (type != ACPI_TYPE_REGION) { |
| 423 | ACPI_ERROR((AE_INFO, | 422 | ACPI_ERROR((AE_INFO, |
| 424 | "Needed Region, found type 0x%X (%s)", | 423 | "Needed Region, found type 0x%X (%s)", type, |
| 425 | type, acpi_ut_get_type_name(type))); | 424 | acpi_ut_get_type_name(type))); |
| 426 | 425 | ||
| 427 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 426 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
| 428 | } | 427 | } |
| @@ -438,7 +437,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
| 438 | /* Initialize areas of the object that are common to all fields */ | 437 | /* Initialize areas of the object that are common to all fields */ |
| 439 | 438 | ||
| 440 | obj_desc->common_field.node = info->field_node; | 439 | obj_desc->common_field.node = info->field_node; |
| 441 | status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags, | 440 | status = acpi_ex_prep_common_field_object(obj_desc, |
| 441 | info->field_flags, | ||
| 442 | info->attribute, | 442 | info->attribute, |
| 443 | info->field_bit_position, | 443 | info->field_bit_position, |
| 444 | info->field_bit_length); | 444 | info->field_bit_length); |
| @@ -455,26 +455,25 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) | |||
| 455 | obj_desc->field.region_obj = | 455 | obj_desc->field.region_obj = |
| 456 | acpi_ns_get_attached_object(info->region_node); | 456 | acpi_ns_get_attached_object(info->region_node); |
| 457 | 457 | ||
| 458 | /* An additional reference for the container */ | 458 | /* Allow full data read from EC address space */ |
| 459 | 459 | ||
| 460 | acpi_ut_add_reference(obj_desc->field.region_obj); | 460 | if ((obj_desc->field.region_obj->region.space_id == |
| 461 | ACPI_ADR_SPACE_EC) | ||
| 462 | && (obj_desc->common_field.bit_length > 8)) { | ||
| 463 | access_byte_width = | ||
| 464 | ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field. | ||
| 465 | bit_length); | ||
| 466 | |||
| 467 | /* Maximum byte width supported is 255 */ | ||
| 461 | 468 | ||
| 462 | /* allow full data read from EC address space */ | 469 | if (access_byte_width < 256) { |
| 463 | if (obj_desc->field.region_obj->region.space_id == | ||
| 464 | ACPI_ADR_SPACE_EC) { | ||
| 465 | if (obj_desc->common_field.bit_length > 8) { | ||
| 466 | unsigned width = | ||
| 467 | ACPI_ROUND_BITS_UP_TO_BYTES( | ||
| 468 | obj_desc->common_field.bit_length); | ||
| 469 | // access_bit_width is u8, don't overflow it | ||
| 470 | if (width > 8) | ||
| 471 | width = 8; | ||
| 472 | obj_desc->common_field.access_byte_width = | 470 | obj_desc->common_field.access_byte_width = |
| 473 | width; | 471 | (u8)access_byte_width; |
| 474 | obj_desc->common_field.access_bit_width = | ||
| 475 | 8 * width; | ||
| 476 | } | 472 | } |
| 477 | } | 473 | } |
| 474 | /* An additional reference for the container */ | ||
| 475 | |||
| 476 | acpi_ut_add_reference(obj_desc->field.region_obj); | ||
| 478 | 477 | ||
| 479 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 478 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
| 480 | "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", | 479 | "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", |
