diff options
-rw-r--r-- | drivers/acpi/acpica/hwregs.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 9c8162128c2b..5a64e577975f 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -372,9 +372,17 @@ acpi_hw_read_multiple(u32 *value, | |||
372 | } | 372 | } |
373 | } | 373 | } |
374 | 374 | ||
375 | /* Shift the B bits above the A bits */ | 375 | /* |
376 | 376 | * OR the two return values together. No shifting or masking is necessary, | |
377 | *value = value_a | (value_b << register_a->bit_width); | 377 | * because of how the PM1 registers are defined in the ACPI specification: |
378 | * | ||
379 | * "Although the bits can be split between the two register blocks (each | ||
380 | * register block has a unique pointer within the FADT), the bit positions | ||
381 | * are maintained. The register block with unimplemented bits (that is, | ||
382 | * those implemented in the other register block) always returns zeros, | ||
383 | * and writes have no side effects" | ||
384 | */ | ||
385 | *value = (value_a | value_b); | ||
378 | return (AE_OK); | 386 | return (AE_OK); |
379 | } | 387 | } |
380 | 388 | ||
@@ -406,13 +414,20 @@ acpi_hw_write_multiple(u32 value, | |||
406 | return (status); | 414 | return (status); |
407 | } | 415 | } |
408 | 416 | ||
409 | /* Second register is optional */ | 417 | /* |
410 | 418 | * Second register is optional | |
419 | * | ||
420 | * No bit shifting or clearing is necessary, because of how the PM1 | ||
421 | * registers are defined in the ACPI specification: | ||
422 | * | ||
423 | * "Although the bits can be split between the two register blocks (each | ||
424 | * register block has a unique pointer within the FADT), the bit positions | ||
425 | * are maintained. The register block with unimplemented bits (that is, | ||
426 | * those implemented in the other register block) always returns zeros, | ||
427 | * and writes have no side effects" | ||
428 | */ | ||
411 | if (register_b->address) { | 429 | if (register_b->address) { |
412 | 430 | status = acpi_write(value, register_b); | |
413 | /* Normalize the B bits before write */ | ||
414 | |||
415 | status = acpi_write(value >> register_a->bit_width, register_b); | ||
416 | } | 431 | } |
417 | 432 | ||
418 | return (status); | 433 | return (status); |