Commit 653f4b53 authored by Bob Moore's avatar Bob Moore Committed by Len Brown

ACPICA: Expand OSL memory read/write interfaces to 64 bits

This change expands acpi_os_read_memory and acpi_os_write_memory to a
full 64 bits. This allows 64 bit transfers via the acpi_read and
acpi_write interfaces. Note: The internal acpi_hw_read and acpi_hw_write
interfaces remain at 32 bits, because 64 bits is not needed to
access the standard ACPI registers.
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 33620c54
...@@ -157,6 +157,7 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, ...@@ -157,6 +157,7 @@ acpi_hw_validate_register(struct acpi_generic_address *reg,
acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
{ {
u64 address; u64 address;
u64 value64;
acpi_status status; acpi_status status;
ACPI_FUNCTION_NAME(hw_read); ACPI_FUNCTION_NAME(hw_read);
...@@ -178,7 +179,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) ...@@ -178,7 +179,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
*/ */
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
status = acpi_os_read_memory((acpi_physical_address) status = acpi_os_read_memory((acpi_physical_address)
address, value, reg->bit_width); address, &value64, reg->bit_width);
*value = (u32)value64;
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
status = acpi_hw_read_port((acpi_io_address) status = acpi_hw_read_port((acpi_io_address)
...@@ -228,7 +231,8 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) ...@@ -228,7 +231,8 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
*/ */
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
status = acpi_os_write_memory((acpi_physical_address) status = acpi_os_write_memory((acpi_physical_address)
address, value, reg->bit_width); address, (u64)value,
reg->bit_width);
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
status = acpi_hw_write_port((acpi_io_address) status = acpi_hw_write_port((acpi_io_address)
......
...@@ -138,11 +138,6 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) ...@@ -138,11 +138,6 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
return (status); return (status);
} }
width = reg->bit_width;
if (width == 64) {
width = 32; /* Break into two 32-bit transfers */
}
/* Initialize entire 64-bit return value to zero */ /* Initialize entire 64-bit return value to zero */
*return_value = 0; *return_value = 0;
...@@ -154,24 +149,17 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) ...@@ -154,24 +149,17 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
*/ */
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
status = acpi_os_read_memory((acpi_physical_address) status = acpi_os_read_memory((acpi_physical_address)
address, &value, width); address, return_value,
reg->bit_width);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
} }
*return_value = value; } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
if (reg->bit_width == 64) {
/* Read the top 32 bits */
status = acpi_os_read_memory((acpi_physical_address) width = reg->bit_width;
(address + 4), &value, 32); if (width == 64) {
if (ACPI_FAILURE(status)) { width = 32; /* Break into two 32-bit transfers */
return (status);
}
*return_value |= ((u64)value << 32);
} }
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
status = acpi_hw_read_port((acpi_io_address) status = acpi_hw_read_port((acpi_io_address)
address, &value, width); address, &value, width);
...@@ -231,32 +219,22 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) ...@@ -231,32 +219,22 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg)
return (status); return (status);
} }
width = reg->bit_width;
if (width == 64) {
width = 32; /* Break into two 32-bit transfers */
}
/* /*
* 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) { if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
status = acpi_os_write_memory((acpi_physical_address) status = acpi_os_write_memory((acpi_physical_address)
address, ACPI_LODWORD(value), address, value, reg->bit_width);
width);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return (status); return (status);
} }
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
if (reg->bit_width == 64) { width = reg->bit_width;
status = acpi_os_write_memory((acpi_physical_address) if (width == 64) {
(address + 4), width = 32; /* Break into two 32-bit transfers */
ACPI_HIDWORD(value), 32);
if (ACPI_FAILURE(status)) {
return (status);
}
} }
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
status = acpi_hw_write_port((acpi_io_address) status = acpi_hw_write_port((acpi_io_address)
address, ACPI_LODWORD(value), address, ACPI_LODWORD(value),
......
...@@ -605,7 +605,7 @@ int apei_read(u64 *val, struct acpi_generic_address *reg) ...@@ -605,7 +605,7 @@ int apei_read(u64 *val, struct acpi_generic_address *reg)
*val = 0; *val = 0;
switch(reg->space_id) { switch(reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_MEMORY:
status = acpi_os_read_memory64((acpi_physical_address) status = acpi_os_read_memory((acpi_physical_address)
address, val, reg->bit_width); address, val, reg->bit_width);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -EIO; return -EIO;
...@@ -636,7 +636,7 @@ int apei_write(u64 val, struct acpi_generic_address *reg) ...@@ -636,7 +636,7 @@ int apei_write(u64 val, struct acpi_generic_address *reg)
switch (reg->space_id) { switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_MEMORY:
status = acpi_os_write_memory64((acpi_physical_address) status = acpi_os_write_memory((acpi_physical_address)
address, val, reg->bit_width); address, val, reg->bit_width);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -EIO; return -EIO;
......
...@@ -699,49 +699,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) ...@@ -699,49 +699,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
EXPORT_SYMBOL(acpi_os_write_port); EXPORT_SYMBOL(acpi_os_write_port);
acpi_status
acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
{
void __iomem *virt_addr;
unsigned int size = width / 8;
bool unmap = false;
u32 dummy;
rcu_read_lock();
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
if (!virt_addr) {
rcu_read_unlock();
virt_addr = acpi_os_ioremap(phys_addr, size);
if (!virt_addr)
return AE_BAD_ADDRESS;
unmap = true;
}
if (!value)
value = &dummy;
switch (width) {
case 8:
*(u8 *) value = readb(virt_addr);
break;
case 16:
*(u16 *) value = readw(virt_addr);
break;
case 32:
*(u32 *) value = readl(virt_addr);
break;
default:
BUG();
}
if (unmap)
iounmap(virt_addr);
else
rcu_read_unlock();
return AE_OK;
}
#ifdef readq #ifdef readq
static inline u64 read64(const volatile void __iomem *addr) static inline u64 read64(const volatile void __iomem *addr)
{ {
...@@ -758,7 +715,7 @@ static inline u64 read64(const volatile void __iomem *addr) ...@@ -758,7 +715,7 @@ static inline u64 read64(const volatile void __iomem *addr)
#endif #endif
acpi_status acpi_status
acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
{ {
void __iomem *virt_addr; void __iomem *virt_addr;
unsigned int size = width / 8; unsigned int size = width / 8;
...@@ -803,45 +760,6 @@ acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) ...@@ -803,45 +760,6 @@ acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width)
return AE_OK; return AE_OK;
} }
acpi_status
acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
{
void __iomem *virt_addr;
unsigned int size = width / 8;
bool unmap = false;
rcu_read_lock();
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
if (!virt_addr) {
rcu_read_unlock();
virt_addr = acpi_os_ioremap(phys_addr, size);
if (!virt_addr)
return AE_BAD_ADDRESS;
unmap = true;
}
switch (width) {
case 8:
writeb(value, virt_addr);
break;
case 16:
writew(value, virt_addr);
break;
case 32:
writel(value, virt_addr);
break;
default:
BUG();
}
if (unmap)
iounmap(virt_addr);
else
rcu_read_unlock();
return AE_OK;
}
#ifdef writeq #ifdef writeq
static inline void write64(u64 val, volatile void __iomem *addr) static inline void write64(u64 val, volatile void __iomem *addr)
{ {
...@@ -856,7 +774,7 @@ static inline void write64(u64 val, volatile void __iomem *addr) ...@@ -856,7 +774,7 @@ static inline void write64(u64 val, volatile void __iomem *addr)
#endif #endif
acpi_status acpi_status
acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width) acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
{ {
void __iomem *virt_addr; void __iomem *virt_addr;
unsigned int size = width / 8; unsigned int size = width / 8;
......
...@@ -217,14 +217,10 @@ acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width); ...@@ -217,14 +217,10 @@ acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width);
* Platform and hardware-independent physical memory interfaces * Platform and hardware-independent physical memory interfaces
*/ */
acpi_status acpi_status
acpi_os_read_memory(acpi_physical_address address, u32 * value, u32 width); acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width);
acpi_status
acpi_os_read_memory64(acpi_physical_address address, u64 *value, u32 width);
acpi_status acpi_status
acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width); acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width);
acpi_status
acpi_os_write_memory64(acpi_physical_address address, u64 value, u32 width);
/* /*
* Platform and hardware-independent PCI configuration space access * Platform and hardware-independent PCI configuration space access
......
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