Commit dc4c7376 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPICA: Hardware: Add access_width/bit_offset support in acpi_hw_write()

ACPICA commit 1ecab20bbe69a176dfb6da7210fe77aa6b3ad680

This patch adds access_width/bit_offset support in acpi_hw_write().

Link: https://github.com/acpica/acpica/commit/1ecab20bSigned-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 123a1577
...@@ -292,6 +292,12 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) ...@@ -292,6 +292,12 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
{ {
u64 address; u64 address;
u8 access_width;
u32 bit_width;
u8 bit_offset;
u64 value64;
u32 value32;
u8 index;
acpi_status status; acpi_status status;
ACPI_FUNCTION_NAME(hw_write); ACPI_FUNCTION_NAME(hw_write);
...@@ -303,23 +309,61 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) ...@@ -303,23 +309,61 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
return (status); 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 * Two address spaces supported: Memory or IO. PCI_Config is
* not supported here because the GAS structure is insufficient * not supported here because the GAS structure is insufficient
*/ */
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { index = 0;
status = acpi_os_write_memory((acpi_physical_address) while (bit_width) {
address, (u64)value, /*
reg->bit_width); * Use offset style bit reads because "Index * AccessWidth" is
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ * ensured to be less than 32-bits by acpi_hw_validate_register().
*/
status = acpi_hw_write_port((acpi_io_address) value32 = ACPI_GET_BITS(&value, index * access_width,
address, value, reg->bit_width); ACPI_MASK_BITS_ABOVE_32(access_width));
if (bit_offset >= access_width) {
bit_offset -= access_width;
} else {
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
value64 = (u64)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 */
status = acpi_hw_write_port((acpi_io_address)
address +
index *
ACPI_DIV_8
(access_width),
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++;
} }
ACPI_DEBUG_PRINT((ACPI_DB_IO, ACPI_DEBUG_PRINT((ACPI_DB_IO,
"Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
value, reg->bit_width, ACPI_FORMAT_UINT64(address), value, access_width, ACPI_FORMAT_UINT64(address),
acpi_ut_get_region_name(reg->space_id))); acpi_ut_get_region_name(reg->space_id)));
return (status); return (status);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment