aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpica/hwregs.c33
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);