aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/exfield.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/exfield.c')
-rw-r--r--drivers/acpi/acpica/exfield.c74
1 files changed, 42 insertions, 32 deletions
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index c95fd186ded2..ad7080ba65e2 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -167,10 +167,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
167 || obj_desc->field.region_obj->region.space_id == 167 || obj_desc->field.region_obj->region.space_id ==
168 ACPI_ADR_SPACE_IPMI)) { 168 ACPI_ADR_SPACE_IPMI)) {
169 /* 169 /*
170 * This is an SMBus, GSBus or IPMI read. We must create a buffer to hold 170 * This is an SMBus, GSBus or IPMI read. We must create a buffer to
171 * the data and then directly access the region handler. 171 * hold the data and then directly access the region handler.
172 * 172 *
173 * Note: SMBus and GSBus protocol value is passed in upper 16-bits of Function 173 * Note: SMBus and GSBus protocol value is passed in upper 16-bits
174 * of Function
174 */ 175 */
175 if (obj_desc->field.region_obj->region.space_id == 176 if (obj_desc->field.region_obj->region.space_id ==
176 ACPI_ADR_SPACE_SMBUS) { 177 ACPI_ADR_SPACE_SMBUS) {
@@ -180,17 +181,17 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
180 } else if (obj_desc->field.region_obj->region.space_id == 181 } else if (obj_desc->field.region_obj->region.space_id ==
181 ACPI_ADR_SPACE_GSBUS) { 182 ACPI_ADR_SPACE_GSBUS) {
182 accessor_type = obj_desc->field.attribute; 183 accessor_type = obj_desc->field.attribute;
183 length = acpi_ex_get_serial_access_length(accessor_type, 184 length =
184 obj_desc-> 185 acpi_ex_get_serial_access_length(accessor_type,
185 field. 186 obj_desc->field.
186 access_length); 187 access_length);
187 188
188 /* 189 /*
189 * Add additional 2 bytes for the generic_serial_bus data buffer: 190 * Add additional 2 bytes for the generic_serial_bus data buffer:
190 * 191 *
191 * Status; (Byte 0 of the data buffer) 192 * Status; (Byte 0 of the data buffer)
192 * Length; (Byte 1 of the data buffer) 193 * Length; (Byte 1 of the data buffer)
193 * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer) 194 * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer)
194 */ 195 */
195 length += 2; 196 length += 2;
196 function = ACPI_READ | (accessor_type << 16); 197 function = ACPI_READ | (accessor_type << 16);
@@ -216,6 +217,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
216 buffer_desc-> 217 buffer_desc->
217 buffer.pointer), 218 buffer.pointer),
218 function); 219 function);
220
219 acpi_ex_release_global_lock(obj_desc->common_field.field_flags); 221 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
220 goto exit; 222 goto exit;
221 } 223 }
@@ -232,6 +234,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
232 */ 234 */
233 length = 235 length =
234 (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length); 236 (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length);
237
235 if (length > acpi_gbl_integer_byte_width) { 238 if (length > acpi_gbl_integer_byte_width) {
236 239
237 /* Field is too large for an Integer, create a Buffer instead */ 240 /* Field is too large for an Integer, create a Buffer instead */
@@ -273,8 +276,10 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
273 276
274 /* Perform the write */ 277 /* Perform the write */
275 278
276 status = acpi_ex_access_region(obj_desc, 0, 279 status =
277 (u64 *)buffer, ACPI_READ); 280 acpi_ex_access_region(obj_desc, 0, (u64 *)buffer,
281 ACPI_READ);
282
278 acpi_ex_release_global_lock(obj_desc->common_field.field_flags); 283 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
279 if (ACPI_FAILURE(status)) { 284 if (ACPI_FAILURE(status)) {
280 acpi_ut_remove_reference(buffer_desc); 285 acpi_ut_remove_reference(buffer_desc);
@@ -366,19 +371,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
366 || obj_desc->field.region_obj->region.space_id == 371 || obj_desc->field.region_obj->region.space_id ==
367 ACPI_ADR_SPACE_IPMI)) { 372 ACPI_ADR_SPACE_IPMI)) {
368 /* 373 /*
369 * This is an SMBus, GSBus or IPMI write. We will bypass the entire field 374 * This is an SMBus, GSBus or IPMI write. We will bypass the entire
370 * mechanism and handoff the buffer directly to the handler. For 375 * field mechanism and handoff the buffer directly to the handler.
371 * these address spaces, the buffer is bi-directional; on a write, 376 * For these address spaces, the buffer is bi-directional; on a
372 * return data is returned in the same buffer. 377 * write, return data is returned in the same buffer.
373 * 378 *
374 * Source must be a buffer of sufficient size: 379 * Source must be a buffer of sufficient size:
375 * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE. 380 * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or
381 * ACPI_IPMI_BUFFER_SIZE.
376 * 382 *
377 * Note: SMBus and GSBus protocol type is passed in upper 16-bits of Function 383 * Note: SMBus and GSBus protocol type is passed in upper 16-bits
384 * of Function
378 */ 385 */
379 if (source_desc->common.type != ACPI_TYPE_BUFFER) { 386 if (source_desc->common.type != ACPI_TYPE_BUFFER) {
380 ACPI_ERROR((AE_INFO, 387 ACPI_ERROR((AE_INFO,
381 "SMBus/IPMI/GenericSerialBus write requires Buffer, found type %s", 388 "SMBus/IPMI/GenericSerialBus write requires "
389 "Buffer, found type %s",
382 acpi_ut_get_object_type_name(source_desc))); 390 acpi_ut_get_object_type_name(source_desc)));
383 391
384 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 392 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -392,17 +400,17 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
392 } else if (obj_desc->field.region_obj->region.space_id == 400 } else if (obj_desc->field.region_obj->region.space_id ==
393 ACPI_ADR_SPACE_GSBUS) { 401 ACPI_ADR_SPACE_GSBUS) {
394 accessor_type = obj_desc->field.attribute; 402 accessor_type = obj_desc->field.attribute;
395 length = acpi_ex_get_serial_access_length(accessor_type, 403 length =
396 obj_desc-> 404 acpi_ex_get_serial_access_length(accessor_type,
397 field. 405 obj_desc->field.
398 access_length); 406 access_length);
399 407
400 /* 408 /*
401 * Add additional 2 bytes for the generic_serial_bus data buffer: 409 * Add additional 2 bytes for the generic_serial_bus data buffer:
402 * 410 *
403 * Status; (Byte 0 of the data buffer) 411 * Status; (Byte 0 of the data buffer)
404 * Length; (Byte 1 of the data buffer) 412 * Length; (Byte 1 of the data buffer)
405 * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer) 413 * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer)
406 */ 414 */
407 length += 2; 415 length += 2;
408 function = ACPI_WRITE | (accessor_type << 16); 416 function = ACPI_WRITE | (accessor_type << 16);
@@ -414,7 +422,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
414 422
415 if (source_desc->buffer.length < length) { 423 if (source_desc->buffer.length < length) {
416 ACPI_ERROR((AE_INFO, 424 ACPI_ERROR((AE_INFO,
417 "SMBus/IPMI/GenericSerialBus write requires Buffer of length %u, found length %u", 425 "SMBus/IPMI/GenericSerialBus write requires "
426 "Buffer of length %u, found length %u",
418 length, source_desc->buffer.length)); 427 length, source_desc->buffer.length));
419 428
420 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); 429 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
@@ -438,8 +447,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
438 * Perform the write (returns status and perhaps data in the 447 * Perform the write (returns status and perhaps data in the
439 * same buffer) 448 * same buffer)
440 */ 449 */
441 status = acpi_ex_access_region(obj_desc, 0, 450 status =
442 (u64 *)buffer, function); 451 acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, function);
443 acpi_ex_release_global_lock(obj_desc->common_field.field_flags); 452 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
444 453
445 *result_desc = buffer_desc; 454 *result_desc = buffer_desc;
@@ -460,7 +469,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
460 } 469 }
461 470
462 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, 471 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
463 "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n", 472 "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n",
464 acpi_ut_get_type_name(source_desc->common. 473 acpi_ut_get_type_name(source_desc->common.
465 type), 474 type),
466 source_desc->common.type, 475 source_desc->common.type,
@@ -476,8 +485,9 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
476 485
477 /* Perform the write */ 486 /* Perform the write */
478 487
479 status = acpi_ex_access_region(obj_desc, 0, 488 status =
480 (u64 *)buffer, ACPI_WRITE); 489 acpi_ex_access_region(obj_desc, 0, (u64 *)buffer,
490 ACPI_WRITE);
481 acpi_ex_release_global_lock(obj_desc->common_field.field_flags); 491 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
482 return_ACPI_STATUS(status); 492 return_ACPI_STATUS(status);
483 } 493 }