diff options
author | Lv Zheng <lv.zheng@intel.com> | 2017-09-19 22:00:11 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-10-03 19:43:05 -0400 |
commit | 8381c54fc0b40e727086a7f61399ae3e09ca7a95 (patch) | |
tree | d169fb31658ee1900bf02ccb409f5cadb2c48d91 | |
parent | 9e66317d3c92ddaab330c125dfe9d06eee268aff (diff) |
ACPICA: Hardware: Enable 64-bit support of hardware accesses
ACPICA commit 6b0a604d171334f61a18bc92b44ec0437b11bf98
This patch enable 64-bit support for acpi_hw_read()/acpi_hw_write() and
then convert acpi_read()/acpi_write() to invoke them. BZ 1287, fixed by
Lv Zheng.
Link: https://github.com/acpica/acpica/commit/6b0a604d1713
Link: https://bugs.acpica.org/show_bug.cgi?id=1287
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/acpica/achware.h | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpe.c | 6 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwgpe.c | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwregs.c | 72 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwxface.c | 118 |
5 files changed, 49 insertions, 155 deletions
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index fd4f3cacb356..cd722d8edacb 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -66,9 +66,9 @@ acpi_status | |||
66 | acpi_hw_validate_register(struct acpi_generic_address *reg, | 66 | acpi_hw_validate_register(struct acpi_generic_address *reg, |
67 | u8 max_bit_width, u64 *address); | 67 | u8 max_bit_width, u64 *address); |
68 | 68 | ||
69 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg); | 69 | acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg); |
70 | 70 | ||
71 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg); | 71 | acpi_status acpi_hw_write(u64 value, struct acpi_generic_address *reg); |
72 | 72 | ||
73 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); | 73 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); |
74 | 74 | ||
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 229382035550..263d8fc4a9e2 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -390,8 +390,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) | |||
390 | struct acpi_gpe_handler_info *gpe_handler_info; | 390 | struct acpi_gpe_handler_info *gpe_handler_info; |
391 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; | 391 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; |
392 | u8 enabled_status_byte; | 392 | u8 enabled_status_byte; |
393 | u32 status_reg; | 393 | u64 status_reg; |
394 | u32 enable_reg; | 394 | u64 enable_reg; |
395 | acpi_cpu_flags flags; | 395 | acpi_cpu_flags flags; |
396 | u32 i; | 396 | u32 i; |
397 | u32 j; | 397 | u32 j; |
@@ -472,7 +472,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) | |||
472 | gpe_register_info->base_gpe_number, | 472 | gpe_register_info->base_gpe_number, |
473 | gpe_register_info->base_gpe_number + | 473 | gpe_register_info->base_gpe_number + |
474 | (ACPI_GPE_REGISTER_WIDTH - 1), | 474 | (ACPI_GPE_REGISTER_WIDTH - 1), |
475 | status_reg, enable_reg, | 475 | (u32)status_reg, (u32)enable_reg, |
476 | gpe_register_info->enable_for_run, | 476 | gpe_register_info->enable_for_run, |
477 | gpe_register_info->enable_for_wake)); | 477 | gpe_register_info->enable_for_wake)); |
478 | 478 | ||
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 5eb11b30a79e..09b6822aa5cc 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -99,7 +99,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | |||
99 | { | 99 | { |
100 | struct acpi_gpe_register_info *gpe_register_info; | 100 | struct acpi_gpe_register_info *gpe_register_info; |
101 | acpi_status status = AE_OK; | 101 | acpi_status status = AE_OK; |
102 | u32 enable_mask; | 102 | u64 enable_mask; |
103 | u32 register_bit; | 103 | u32 register_bit; |
104 | 104 | ||
105 | ACPI_FUNCTION_ENTRY(); | 105 | ACPI_FUNCTION_ENTRY(); |
@@ -214,7 +214,7 @@ acpi_status | |||
214 | acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, | 214 | acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, |
215 | acpi_event_status *event_status) | 215 | acpi_event_status *event_status) |
216 | { | 216 | { |
217 | u32 in_byte; | 217 | u64 in_byte; |
218 | u32 register_bit; | 218 | u32 register_bit; |
219 | struct acpi_gpe_register_info *gpe_register_info; | 219 | struct acpi_gpe_register_info *gpe_register_info; |
220 | acpi_event_status local_event_status = 0; | 220 | acpi_event_status local_event_status = 0; |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index acb417b58bbb..aa6e00081915 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -220,16 +220,15 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, | |||
220 | * | 220 | * |
221 | * RETURN: Status | 221 | * RETURN: Status |
222 | * | 222 | * |
223 | * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max | 223 | * DESCRIPTION: Read from either memory or IO space. This is a 64-bit max |
224 | * version of acpi_read, used internally since the overhead of | 224 | * version of acpi_read. |
225 | * 64-bit values is not needed. | ||
226 | * | 225 | * |
227 | * LIMITATIONS: <These limitations also apply to acpi_hw_write> | 226 | * LIMITATIONS: <These limitations also apply to acpi_hw_write> |
228 | * space_ID must be system_memory or system_IO. | 227 | * space_ID must be system_memory or system_IO. |
229 | * | 228 | * |
230 | ******************************************************************************/ | 229 | ******************************************************************************/ |
231 | 230 | ||
232 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | 231 | acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg) |
233 | { | 232 | { |
234 | u64 address; | 233 | u64 address; |
235 | u8 access_width; | 234 | u8 access_width; |
@@ -244,17 +243,17 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
244 | 243 | ||
245 | /* Validate contents of the GAS register */ | 244 | /* Validate contents of the GAS register */ |
246 | 245 | ||
247 | status = acpi_hw_validate_register(reg, 32, &address); | 246 | status = acpi_hw_validate_register(reg, 64, &address); |
248 | if (ACPI_FAILURE(status)) { | 247 | if (ACPI_FAILURE(status)) { |
249 | return (status); | 248 | return (status); |
250 | } | 249 | } |
251 | 250 | ||
252 | /* | 251 | /* |
253 | * Initialize entire 32-bit return value to zero, convert access_width | 252 | * Initialize entire 64-bit return value to zero, convert access_width |
254 | * into number of bits based | 253 | * into number of bits based |
255 | */ | 254 | */ |
256 | *value = 0; | 255 | *value = 0; |
257 | access_width = acpi_hw_get_access_bit_width(address, reg, 32); | 256 | access_width = acpi_hw_get_access_bit_width(address, reg, 64); |
258 | bit_width = reg->bit_offset + reg->bit_width; | 257 | bit_width = reg->bit_offset + reg->bit_width; |
259 | bit_offset = reg->bit_offset; | 258 | bit_offset = reg->bit_offset; |
260 | 259 | ||
@@ -265,7 +264,7 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
265 | index = 0; | 264 | index = 0; |
266 | while (bit_width) { | 265 | while (bit_width) { |
267 | if (bit_offset >= access_width) { | 266 | if (bit_offset >= access_width) { |
268 | value32 = 0; | 267 | value64 = 0; |
269 | bit_offset -= access_width; | 268 | bit_offset -= access_width; |
270 | } else { | 269 | } else { |
271 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 270 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
@@ -276,7 +275,6 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
276 | ACPI_DIV_8 | 275 | ACPI_DIV_8 |
277 | (access_width), | 276 | (access_width), |
278 | &value64, access_width); | 277 | &value64, access_width); |
279 | value32 = (u32)value64; | ||
280 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 278 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
281 | 279 | ||
282 | status = acpi_hw_read_port((acpi_io_address) | 280 | status = acpi_hw_read_port((acpi_io_address) |
@@ -286,15 +284,16 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
286 | (access_width), | 284 | (access_width), |
287 | &value32, | 285 | &value32, |
288 | access_width); | 286 | access_width); |
287 | value64 = (u64)value32; | ||
289 | } | 288 | } |
290 | } | 289 | } |
291 | 290 | ||
292 | /* | 291 | /* |
293 | * Use offset style bit writes because "Index * AccessWidth" is | 292 | * Use offset style bit writes because "Index * AccessWidth" is |
294 | * ensured to be less than 32-bits by acpi_hw_validate_register(). | 293 | * ensured to be less than 64-bits by acpi_hw_validate_register(). |
295 | */ | 294 | */ |
296 | ACPI_SET_BITS(value, index * access_width, | 295 | ACPI_SET_BITS(value, index * access_width, |
297 | ACPI_MASK_BITS_ABOVE_32(access_width), value32); | 296 | ACPI_MASK_BITS_ABOVE_64(access_width), value64); |
298 | 297 | ||
299 | bit_width -= | 298 | bit_width -= |
300 | bit_width > access_width ? access_width : bit_width; | 299 | bit_width > access_width ? access_width : bit_width; |
@@ -302,8 +301,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
302 | } | 301 | } |
303 | 302 | ||
304 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 303 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
305 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 304 | "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", |
306 | *value, access_width, ACPI_FORMAT_UINT64(address), | 305 | ACPI_FORMAT_UINT64(*value), access_width, |
306 | ACPI_FORMAT_UINT64(address), | ||
307 | acpi_ut_get_region_name(reg->space_id))); | 307 | acpi_ut_get_region_name(reg->space_id))); |
308 | 308 | ||
309 | return (status); | 309 | return (status); |
@@ -318,20 +318,18 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
318 | * | 318 | * |
319 | * RETURN: Status | 319 | * RETURN: Status |
320 | * | 320 | * |
321 | * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max | 321 | * DESCRIPTION: Write to either memory or IO space. This is a 64-bit max |
322 | * version of acpi_write, used internally since the overhead of | 322 | * version of acpi_write. |
323 | * 64-bit values is not needed. | ||
324 | * | 323 | * |
325 | ******************************************************************************/ | 324 | ******************************************************************************/ |
326 | 325 | ||
327 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | 326 | acpi_status acpi_hw_write(u64 value, struct acpi_generic_address *reg) |
328 | { | 327 | { |
329 | u64 address; | 328 | u64 address; |
330 | u8 access_width; | 329 | u8 access_width; |
331 | u32 bit_width; | 330 | u32 bit_width; |
332 | u8 bit_offset; | 331 | u8 bit_offset; |
333 | u64 value64; | 332 | u64 value64; |
334 | u32 value32; | ||
335 | u8 index; | 333 | u8 index; |
336 | acpi_status status; | 334 | acpi_status status; |
337 | 335 | ||
@@ -339,14 +337,14 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
339 | 337 | ||
340 | /* Validate contents of the GAS register */ | 338 | /* Validate contents of the GAS register */ |
341 | 339 | ||
342 | status = acpi_hw_validate_register(reg, 32, &address); | 340 | status = acpi_hw_validate_register(reg, 64, &address); |
343 | if (ACPI_FAILURE(status)) { | 341 | if (ACPI_FAILURE(status)) { |
344 | return (status); | 342 | return (status); |
345 | } | 343 | } |
346 | 344 | ||
347 | /* Convert access_width into number of bits based */ | 345 | /* Convert access_width into number of bits based */ |
348 | 346 | ||
349 | access_width = acpi_hw_get_access_bit_width(address, reg, 32); | 347 | access_width = acpi_hw_get_access_bit_width(address, reg, 64); |
350 | bit_width = reg->bit_offset + reg->bit_width; | 348 | bit_width = reg->bit_offset + reg->bit_width; |
351 | bit_offset = reg->bit_offset; | 349 | bit_offset = reg->bit_offset; |
352 | 350 | ||
@@ -358,16 +356,15 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
358 | while (bit_width) { | 356 | while (bit_width) { |
359 | /* | 357 | /* |
360 | * Use offset style bit reads because "Index * AccessWidth" is | 358 | * Use offset style bit reads because "Index * AccessWidth" is |
361 | * ensured to be less than 32-bits by acpi_hw_validate_register(). | 359 | * ensured to be less than 64-bits by acpi_hw_validate_register(). |
362 | */ | 360 | */ |
363 | value32 = ACPI_GET_BITS(&value, index * access_width, | 361 | value64 = ACPI_GET_BITS(&value, index * access_width, |
364 | ACPI_MASK_BITS_ABOVE_32(access_width)); | 362 | ACPI_MASK_BITS_ABOVE_64(access_width)); |
365 | 363 | ||
366 | if (bit_offset >= access_width) { | 364 | if (bit_offset >= access_width) { |
367 | bit_offset -= access_width; | 365 | bit_offset -= access_width; |
368 | } else { | 366 | } else { |
369 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 367 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
370 | value64 = (u64)value32; | ||
371 | status = | 368 | status = |
372 | acpi_os_write_memory((acpi_physical_address) | 369 | acpi_os_write_memory((acpi_physical_address) |
373 | address + | 370 | address + |
@@ -382,7 +379,7 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
382 | index * | 379 | index * |
383 | ACPI_DIV_8 | 380 | ACPI_DIV_8 |
384 | (access_width), | 381 | (access_width), |
385 | value32, | 382 | (u32)value64, |
386 | access_width); | 383 | access_width); |
387 | } | 384 | } |
388 | } | 385 | } |
@@ -397,8 +394,9 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
397 | } | 394 | } |
398 | 395 | ||
399 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 396 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
400 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | 397 | "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", |
401 | value, access_width, ACPI_FORMAT_UINT64(address), | 398 | ACPI_FORMAT_UINT64(value), access_width, |
399 | ACPI_FORMAT_UINT64(address), | ||
402 | acpi_ut_get_region_name(reg->space_id))); | 400 | acpi_ut_get_region_name(reg->space_id))); |
403 | 401 | ||
404 | return (status); | 402 | return (status); |
@@ -526,6 +524,7 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) | |||
526 | acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) | 524 | acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) |
527 | { | 525 | { |
528 | u32 value = 0; | 526 | u32 value = 0; |
527 | u64 value64; | ||
529 | acpi_status status; | 528 | acpi_status status; |
530 | 529 | ||
531 | ACPI_FUNCTION_TRACE(hw_register_read); | 530 | ACPI_FUNCTION_TRACE(hw_register_read); |
@@ -564,12 +563,14 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) | |||
564 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 563 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
565 | 564 | ||
566 | status = | 565 | status = |
567 | acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); | 566 | acpi_hw_read(&value64, &acpi_gbl_FADT.xpm2_control_block); |
567 | value = (u32)value64; | ||
568 | break; | 568 | break; |
569 | 569 | ||
570 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 570 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
571 | 571 | ||
572 | status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); | 572 | status = acpi_hw_read(&value64, &acpi_gbl_FADT.xpm_timer_block); |
573 | value = (u32)value64; | ||
573 | break; | 574 | break; |
574 | 575 | ||
575 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 576 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
@@ -586,7 +587,7 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) | |||
586 | } | 587 | } |
587 | 588 | ||
588 | if (ACPI_SUCCESS(status)) { | 589 | if (ACPI_SUCCESS(status)) { |
589 | *return_value = value; | 590 | *return_value = (u32)value; |
590 | } | 591 | } |
591 | 592 | ||
592 | return_ACPI_STATUS(status); | 593 | return_ACPI_STATUS(status); |
@@ -622,6 +623,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
622 | { | 623 | { |
623 | acpi_status status; | 624 | acpi_status status; |
624 | u32 read_value; | 625 | u32 read_value; |
626 | u64 read_value64; | ||
625 | 627 | ||
626 | ACPI_FUNCTION_TRACE(hw_register_write); | 628 | ACPI_FUNCTION_TRACE(hw_register_write); |
627 | 629 | ||
@@ -685,11 +687,12 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
685 | * as per the ACPI spec. | 687 | * as per the ACPI spec. |
686 | */ | 688 | */ |
687 | status = | 689 | status = |
688 | acpi_hw_read(&read_value, | 690 | acpi_hw_read(&read_value64, |
689 | &acpi_gbl_FADT.xpm2_control_block); | 691 | &acpi_gbl_FADT.xpm2_control_block); |
690 | if (ACPI_FAILURE(status)) { | 692 | if (ACPI_FAILURE(status)) { |
691 | goto exit; | 693 | goto exit; |
692 | } | 694 | } |
695 | read_value = (u32)read_value64; | ||
693 | 696 | ||
694 | /* Insert the bits to be preserved */ | 697 | /* Insert the bits to be preserved */ |
695 | 698 | ||
@@ -745,22 +748,25 @@ acpi_hw_read_multiple(u32 *value, | |||
745 | { | 748 | { |
746 | u32 value_a = 0; | 749 | u32 value_a = 0; |
747 | u32 value_b = 0; | 750 | u32 value_b = 0; |
751 | u64 value64; | ||
748 | acpi_status status; | 752 | acpi_status status; |
749 | 753 | ||
750 | /* The first register is always required */ | 754 | /* The first register is always required */ |
751 | 755 | ||
752 | status = acpi_hw_read(&value_a, register_a); | 756 | status = acpi_hw_read(&value64, register_a); |
753 | if (ACPI_FAILURE(status)) { | 757 | if (ACPI_FAILURE(status)) { |
754 | return (status); | 758 | return (status); |
755 | } | 759 | } |
760 | value_a = (u32)value64; | ||
756 | 761 | ||
757 | /* Second register is optional */ | 762 | /* Second register is optional */ |
758 | 763 | ||
759 | if (register_b->address) { | 764 | if (register_b->address) { |
760 | status = acpi_hw_read(&value_b, register_b); | 765 | status = acpi_hw_read(&value64, register_b); |
761 | if (ACPI_FAILURE(status)) { | 766 | if (ACPI_FAILURE(status)) { |
762 | return (status); | 767 | return (status); |
763 | } | 768 | } |
769 | value_b = (u32)value64; | ||
764 | } | 770 | } |
765 | 771 | ||
766 | /* | 772 | /* |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 34684ae89981..b3c6e439933c 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -125,76 +125,12 @@ ACPI_EXPORT_SYMBOL(acpi_reset) | |||
125 | ******************************************************************************/ | 125 | ******************************************************************************/ |
126 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | 126 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) |
127 | { | 127 | { |
128 | u32 value_lo; | ||
129 | u32 value_hi; | ||
130 | u32 width; | ||
131 | u64 address; | ||
132 | acpi_status status; | 128 | acpi_status status; |
133 | 129 | ||
134 | ACPI_FUNCTION_NAME(acpi_read); | 130 | ACPI_FUNCTION_NAME(acpi_read); |
135 | 131 | ||
136 | if (!return_value) { | 132 | status = acpi_hw_read(return_value, reg); |
137 | return (AE_BAD_PARAMETER); | 133 | return (status); |
138 | } | ||
139 | |||
140 | /* Validate contents of the GAS register. Allow 64-bit transfers */ | ||
141 | |||
142 | status = acpi_hw_validate_register(reg, 64, &address); | ||
143 | if (ACPI_FAILURE(status)) { | ||
144 | return (status); | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Two address spaces supported: Memory or I/O. PCI_Config is | ||
149 | * not supported here because the GAS structure is insufficient | ||
150 | */ | ||
151 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
152 | status = acpi_os_read_memory((acpi_physical_address) | ||
153 | address, return_value, | ||
154 | reg->bit_width); | ||
155 | if (ACPI_FAILURE(status)) { | ||
156 | return (status); | ||
157 | } | ||
158 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
159 | |||
160 | value_lo = 0; | ||
161 | value_hi = 0; | ||
162 | |||
163 | width = reg->bit_width; | ||
164 | if (width == 64) { | ||
165 | width = 32; /* Break into two 32-bit transfers */ | ||
166 | } | ||
167 | |||
168 | status = acpi_hw_read_port((acpi_io_address) | ||
169 | address, &value_lo, width); | ||
170 | if (ACPI_FAILURE(status)) { | ||
171 | return (status); | ||
172 | } | ||
173 | |||
174 | if (reg->bit_width == 64) { | ||
175 | |||
176 | /* Read the top 32 bits */ | ||
177 | |||
178 | status = acpi_hw_read_port((acpi_io_address) | ||
179 | (address + 4), &value_hi, | ||
180 | 32); | ||
181 | if (ACPI_FAILURE(status)) { | ||
182 | return (status); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | /* Set the return value only if status is AE_OK */ | ||
187 | |||
188 | *return_value = (value_lo | ((u64)value_hi << 32)); | ||
189 | } | ||
190 | |||
191 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
192 | "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", | ||
193 | ACPI_FORMAT_UINT64(*return_value), reg->bit_width, | ||
194 | ACPI_FORMAT_UINT64(address), | ||
195 | acpi_ut_get_region_name(reg->space_id))); | ||
196 | |||
197 | return (AE_OK); | ||
198 | } | 134 | } |
199 | 135 | ||
200 | ACPI_EXPORT_SYMBOL(acpi_read) | 136 | ACPI_EXPORT_SYMBOL(acpi_read) |
@@ -213,59 +149,11 @@ ACPI_EXPORT_SYMBOL(acpi_read) | |||
213 | ******************************************************************************/ | 149 | ******************************************************************************/ |
214 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) | 150 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) |
215 | { | 151 | { |
216 | u32 width; | ||
217 | u64 address; | ||
218 | acpi_status status; | 152 | acpi_status status; |
219 | 153 | ||
220 | ACPI_FUNCTION_NAME(acpi_write); | 154 | ACPI_FUNCTION_NAME(acpi_write); |
221 | 155 | ||
222 | /* Validate contents of the GAS register. Allow 64-bit transfers */ | 156 | status = acpi_hw_write(value, reg); |
223 | |||
224 | status = acpi_hw_validate_register(reg, 64, &address); | ||
225 | if (ACPI_FAILURE(status)) { | ||
226 | return (status); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Two address spaces supported: Memory or IO. PCI_Config is | ||
231 | * not supported here because the GAS structure is insufficient | ||
232 | */ | ||
233 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
234 | status = acpi_os_write_memory((acpi_physical_address) | ||
235 | address, value, reg->bit_width); | ||
236 | if (ACPI_FAILURE(status)) { | ||
237 | return (status); | ||
238 | } | ||
239 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
240 | |||
241 | width = reg->bit_width; | ||
242 | if (width == 64) { | ||
243 | width = 32; /* Break into two 32-bit transfers */ | ||
244 | } | ||
245 | |||
246 | status = acpi_hw_write_port((acpi_io_address) | ||
247 | address, ACPI_LODWORD(value), | ||
248 | width); | ||
249 | if (ACPI_FAILURE(status)) { | ||
250 | return (status); | ||
251 | } | ||
252 | |||
253 | if (reg->bit_width == 64) { | ||
254 | status = acpi_hw_write_port((acpi_io_address) | ||
255 | (address + 4), | ||
256 | ACPI_HIDWORD(value), 32); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | return (status); | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | |||
263 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
264 | "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", | ||
265 | ACPI_FORMAT_UINT64(value), reg->bit_width, | ||
266 | ACPI_FORMAT_UINT64(address), | ||
267 | acpi_ut_get_region_name(reg->space_id))); | ||
268 | |||
269 | return (status); | 157 | return (status); |
270 | } | 158 | } |
271 | 159 | ||