ACPI fix for v4.7-rc4
Revert a recent ACPICA commit that introduced a suspend-to-RAM regression on one system due to incorrect information in its ACPI tables that had not been taken into consideration at all before (and everything worked), but the commit in question started to use it. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJXZJTwAAoJEILEb/54YlRxXGUQALQCxZeFRjYrCeP5uwN0Kcxs 21JpnflvhEdi5VDjTdcyFHXNwEyb21IyDvmh4nMuuvARHJbmmfemVquVQiS0vF7M +SX64qPW7YndnlqkLevBSozZMgF65epRTetyh+wE6WHfEayobA+vFE7nILvtz6b7 H2cNjeDMP8oG94DpRgevD9IJCZJolaSNSJzJXOCWsPYOmvTDgH+ow9R5eHed/2/K Ms3yDgQV7G67H6Bu/42mVQtg+dXOs1B4I3VI5/yu3vpuNS86qdNdqfIFpAkZDIIm Twf05slrsUU+ZVTTNLbcJZMuqBvnUEl5P7LHwjO/r5kdHgRpdjNXxJ051bZfh34C f3wBK8Hl6qFONIArMKQd75sRfEHmZsig1iPmJKcFjdEfRxuKJeFqHfYIky2ONNLA 53uZhIaHvTDf8lO4X1jR61veF4VJJGMp0rM5a688iSPT4PprhN2/b6ayIXLLyLtI KJ/joiv/kI9wua5rPZFg9kEX4n/E0zylIaZGtmsUGDIa5y5BJnVsylRIRsEjEeoJ QwB00uTP28+bREopgnSWL3fQvwEDrhNn7t6ZKEcvv4VdKsdlRjnWF29nMmap9hmw PcvAUts/8dH7xLjmb9CVW+2X0O6mYI5eWiVNKjjN5wtx5fSGj7V5z7s7WKULt1YU DNk5/QvVjYHavZ8/Gwli =OaOr -----END PGP SIGNATURE----- Merge tag 'acpi-4.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI fix from Rafael Wysocki: "Revert a recent ACPICA commit that introduced a suspend-to-RAM regression on one system due to incorrect information in its ACPI tables that had not been taken into consideration at all before (and everything worked), but the commit in question started to use it" * tag 'acpi-4.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Revert "ACPICA: ACPI 2.0, Hardware: Add access_width/bit_offset support for acpi_hw_write()"
This commit is contained in:
commit
d9e66146c1
|
@ -306,12 +306,6 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
|
|||
acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
|
||||
{
|
||||
u64 address;
|
||||
u8 access_width;
|
||||
u32 bit_width;
|
||||
u8 bit_offset;
|
||||
u64 value64;
|
||||
u32 new_value32, old_value32;
|
||||
u8 index;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_NAME(hw_write);
|
||||
|
@ -323,145 +317,23 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
|
|||
return (status);
|
||||
}
|
||||
|
||||
/* Convert access_width into number of bits based */
|
||||
|
||||
access_width = acpi_hw_get_access_bit_width(reg, 32);
|
||||
bit_width = reg->bit_offset + reg->bit_width;
|
||||
bit_offset = reg->bit_offset;
|
||||
|
||||
/*
|
||||
* Two address spaces supported: Memory or IO. PCI_Config is
|
||||
* not supported here because the GAS structure is insufficient
|
||||
*/
|
||||
index = 0;
|
||||
while (bit_width) {
|
||||
/*
|
||||
* Use offset style bit reads because "Index * AccessWidth" is
|
||||
* ensured to be less than 32-bits by acpi_hw_validate_register().
|
||||
*/
|
||||
new_value32 = ACPI_GET_BITS(&value, index * access_width,
|
||||
ACPI_MASK_BITS_ABOVE_32
|
||||
(access_width));
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
status = acpi_os_write_memory((acpi_physical_address)
|
||||
address, (u64)value,
|
||||
reg->bit_width);
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
|
||||
if (bit_offset >= access_width) {
|
||||
bit_offset -= access_width;
|
||||
} else {
|
||||
/*
|
||||
* Use offset style bit masks because access_width is ensured
|
||||
* to be less than 32-bits by acpi_hw_validate_register() and
|
||||
* bit_offset/bit_width is less than access_width here.
|
||||
*/
|
||||
if (bit_offset) {
|
||||
new_value32 &= ACPI_MASK_BITS_BELOW(bit_offset);
|
||||
}
|
||||
if (bit_width < access_width) {
|
||||
new_value32 &= ACPI_MASK_BITS_ABOVE(bit_width);
|
||||
}
|
||||
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
if (bit_offset || bit_width < access_width) {
|
||||
/*
|
||||
* Read old values in order not to modify the bits that
|
||||
* are beyond the register bit_width/bit_offset setting.
|
||||
*/
|
||||
status =
|
||||
acpi_os_read_memory((acpi_physical_address)
|
||||
address +
|
||||
index *
|
||||
ACPI_DIV_8
|
||||
(access_width),
|
||||
&value64,
|
||||
access_width);
|
||||
old_value32 = (u32)value64;
|
||||
|
||||
/*
|
||||
* Use offset style bit masks because access_width is
|
||||
* ensured to be less than 32-bits by
|
||||
* acpi_hw_validate_register() and bit_offset/bit_width is
|
||||
* less than access_width here.
|
||||
*/
|
||||
if (bit_offset) {
|
||||
old_value32 &=
|
||||
ACPI_MASK_BITS_ABOVE
|
||||
(bit_offset);
|
||||
bit_offset = 0;
|
||||
}
|
||||
if (bit_width < access_width) {
|
||||
old_value32 &=
|
||||
ACPI_MASK_BITS_BELOW
|
||||
(bit_width);
|
||||
}
|
||||
|
||||
new_value32 |= old_value32;
|
||||
}
|
||||
|
||||
value64 = (u64)new_value32;
|
||||
status =
|
||||
acpi_os_write_memory((acpi_physical_address)
|
||||
address +
|
||||
index *
|
||||
ACPI_DIV_8
|
||||
(access_width),
|
||||
value64, access_width);
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
|
||||
if (bit_offset || bit_width < access_width) {
|
||||
/*
|
||||
* Read old values in order not to modify the bits that
|
||||
* are beyond the register bit_width/bit_offset setting.
|
||||
*/
|
||||
status =
|
||||
acpi_hw_read_port((acpi_io_address)
|
||||
address +
|
||||
index *
|
||||
ACPI_DIV_8
|
||||
(access_width),
|
||||
&old_value32,
|
||||
access_width);
|
||||
|
||||
/*
|
||||
* Use offset style bit masks because access_width is
|
||||
* ensured to be less than 32-bits by
|
||||
* acpi_hw_validate_register() and bit_offset/bit_width is
|
||||
* less than access_width here.
|
||||
*/
|
||||
if (bit_offset) {
|
||||
old_value32 &=
|
||||
ACPI_MASK_BITS_ABOVE
|
||||
(bit_offset);
|
||||
bit_offset = 0;
|
||||
}
|
||||
if (bit_width < access_width) {
|
||||
old_value32 &=
|
||||
ACPI_MASK_BITS_BELOW
|
||||
(bit_width);
|
||||
}
|
||||
|
||||
new_value32 |= old_value32;
|
||||
}
|
||||
|
||||
status = acpi_hw_write_port((acpi_io_address)
|
||||
address +
|
||||
index *
|
||||
ACPI_DIV_8
|
||||
(access_width),
|
||||
new_value32,
|
||||
access_width);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Index * access_width is ensured to be less than 32-bits by
|
||||
* acpi_hw_validate_register().
|
||||
*/
|
||||
bit_width -=
|
||||
bit_width > access_width ? access_width : bit_width;
|
||||
index++;
|
||||
status = acpi_hw_write_port((acpi_io_address)
|
||||
address, value, reg->bit_width);
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_IO,
|
||||
"Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
|
||||
value, access_width, ACPI_FORMAT_UINT64(address),
|
||||
value, reg->bit_width, ACPI_FORMAT_UINT64(address),
|
||||
acpi_ut_get_region_name(reg->space_id)));
|
||||
|
||||
return (status);
|
||||
|
|
Loading…
Reference in New Issue