forked from luck/tmp_suning_uos_patched
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: 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>
This commit is contained in:
parent
33620c5419
commit
653f4b538f
@ -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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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,25 +149,18 @@ 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;
|
|
||||||
|
|
||||||
if (reg->bit_width == 64) {
|
|
||||||
|
|
||||||
/* Read the top 32 bits */
|
|
||||||
|
|
||||||
status = acpi_os_read_memory((acpi_physical_address)
|
|
||||||
(address + 4), &value, 32);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
*return_value |= ((u64)value << 32);
|
|
||||||
}
|
|
||||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||||
|
|
||||||
|
width = reg->bit_width;
|
||||||
|
if (width == 64) {
|
||||||
|
width = 32; /* Break into two 32-bit transfers */
|
||||||
|
}
|
||||||
|
|
||||||
status = acpi_hw_read_port((acpi_io_address)
|
status = acpi_hw_read_port((acpi_io_address)
|
||||||
address, &value, width);
|
address, &value, width);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
@ -231,33 +219,23 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg->bit_width == 64) {
|
|
||||||
status = acpi_os_write_memory((acpi_physical_address)
|
|
||||||
(address + 4),
|
|
||||||
ACPI_HIDWORD(value), 32);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||||
|
|
||||||
|
width = reg->bit_width;
|
||||||
|
if (width == 64) {
|
||||||
|
width = 32; /* Break into two 32-bit transfers */
|
||||||
|
}
|
||||||
|
|
||||||
status = acpi_hw_write_port((acpi_io_address)
|
status = acpi_hw_write_port((acpi_io_address)
|
||||||
address, ACPI_LODWORD(value),
|
address, ACPI_LODWORD(value),
|
||||||
width);
|
width);
|
||||||
|
@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
#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)
|
|||||||
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)
|
|||||||
#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);
|
|||||||
* 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
|
||||||
|
Loading…
Reference in New Issue
Block a user