Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -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)
+11 −33
Original line number Original line Diff line number Diff line
@@ -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)
	 */
	 */
	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)
		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),
+2 −2
Original line number Original line Diff line number Diff line
@@ -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;
+2 −84
Original line number Original line Diff line number Diff line
@@ -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;
+2 −6
Original line number Original line Diff line number Diff line
@@ -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