aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2009-02-18 14:26:02 +0800
committerLen Brown <len.brown@intel.com>2009-03-26 16:38:25 -0400
commitaefc7f9a0220a40beff9b6b3b320cbeae128d0e3 (patch)
treee6b21c54c70871bbe4f32f0679f9533e3a9c1f4f
parent227243a04d645377d09eda0dc8501e0d9c26ab89 (diff)
ACPICA: For PM1B registers, do not shift value read or written
The PM1B registers are mirrors of the PM1A registers with different bits actually implemented. From the ACPI specification: "Although the bits can be split between the two register blocks (each register block has a unique pointer within the FADT), the bit positions are maintained. The register block with unimplemented bits (that is, those implemented in the other register block) always returns zeros, and writes have no side effects" Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-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 9c8162128c2..5a64e577975 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -372,9 +372,17 @@ acpi_hw_read_multiple(u32 *value,
}
}
- /* Shift the B bits above the A bits */
-
- *value = value_a | (value_b << register_a->bit_width);
+ /*
+ * OR the two return values together. No shifting or masking is necessary,
+ * because of how the PM1 registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ *value = (value_a | value_b);
return (AE_OK);
}
@@ -406,13 +414,20 @@ acpi_hw_write_multiple(u32 value,
return (status);
}
- /* Second register is optional */
-
+ /*
+ * Second register is optional
+ *
+ * No bit shifting or clearing is necessary, because of how the PM1
+ * registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
if (register_b->address) {
-
- /* Normalize the B bits before write */
-
- status = acpi_write(value >> register_a->bit_width, register_b);
+ status = acpi_write(value, register_b);
}
return (status);