diff options
author | Bob Moore <robert.moore@intel.com> | 2012-02-14 05:29:55 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-03-22 01:44:54 -0400 |
commit | 653f4b538f66d37db560e0f56af08117136d29b7 (patch) | |
tree | 1728249946368a4befa5ade048bafeba9d9fddce /drivers/acpi | |
parent | 33620c5419e8a11814dd11e02a80e6ef77a43407 (diff) |
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>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpica/hwregs.c | 8 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwxface.c | 44 | ||||
-rw-r--r-- | drivers/acpi/apei/apei-base.c | 4 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 86 |
4 files changed, 21 insertions, 121 deletions
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 17a78e5ef175..6b6c83b87b52 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -157,6 +157,7 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, | |||
157 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | 157 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) |
158 | { | 158 | { |
159 | u64 address; | 159 | u64 address; |
160 | u64 value64; | ||
160 | acpi_status status; | 161 | acpi_status status; |
161 | 162 | ||
162 | ACPI_FUNCTION_NAME(hw_read); | 163 | ACPI_FUNCTION_NAME(hw_read); |
@@ -178,7 +179,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
178 | */ | 179 | */ |
179 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 180 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
180 | status = acpi_os_read_memory((acpi_physical_address) | 181 | status = acpi_os_read_memory((acpi_physical_address) |
181 | address, value, reg->bit_width); | 182 | address, &value64, reg->bit_width); |
183 | |||
184 | *value = (u32)value64; | ||
182 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 185 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
183 | 186 | ||
184 | status = acpi_hw_read_port((acpi_io_address) | 187 | 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 | */ | 231 | */ |
229 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 232 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
230 | status = acpi_os_write_memory((acpi_physical_address) | 233 | status = acpi_os_write_memory((acpi_physical_address) |
231 | address, value, reg->bit_width); | 234 | address, (u64)value, |
235 | reg->bit_width); | ||
232 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 236 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
233 | 237 | ||
234 | status = acpi_hw_write_port((acpi_io_address) | 238 | status = acpi_hw_write_port((acpi_io_address) |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index bb8dba612212..a716fede4f25 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -138,11 +138,6 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
138 | return (status); | 138 | return (status); |
139 | } | 139 | } |
140 | 140 | ||
141 | width = reg->bit_width; | ||
142 | if (width == 64) { | ||
143 | width = 32; /* Break into two 32-bit transfers */ | ||
144 | } | ||
145 | |||
146 | /* Initialize entire 64-bit return value to zero */ | 141 | /* Initialize entire 64-bit return value to zero */ |
147 | 142 | ||
148 | *return_value = 0; | 143 | *return_value = 0; |
@@ -154,24 +149,17 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
154 | */ | 149 | */ |
155 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 150 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
156 | status = acpi_os_read_memory((acpi_physical_address) | 151 | status = acpi_os_read_memory((acpi_physical_address) |
157 | address, &value, width); | 152 | address, return_value, |
153 | reg->bit_width); | ||
158 | if (ACPI_FAILURE(status)) { | 154 | if (ACPI_FAILURE(status)) { |
159 | return (status); | 155 | return (status); |
160 | } | 156 | } |
161 | *return_value = value; | 157 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
162 | |||
163 | if (reg->bit_width == 64) { | ||
164 | |||
165 | /* Read the top 32 bits */ | ||
166 | 158 | ||
167 | status = acpi_os_read_memory((acpi_physical_address) | 159 | width = reg->bit_width; |
168 | (address + 4), &value, 32); | 160 | if (width == 64) { |
169 | if (ACPI_FAILURE(status)) { | 161 | width = 32; /* Break into two 32-bit transfers */ |
170 | return (status); | ||
171 | } | ||
172 | *return_value |= ((u64)value << 32); | ||
173 | } | 162 | } |
174 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
175 | 163 | ||
176 | status = acpi_hw_read_port((acpi_io_address) | 164 | status = acpi_hw_read_port((acpi_io_address) |
177 | address, &value, width); | 165 | address, &value, width); |
@@ -231,32 +219,22 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) | |||
231 | return (status); | 219 | return (status); |
232 | } | 220 | } |
233 | 221 | ||
234 | width = reg->bit_width; | ||
235 | if (width == 64) { | ||
236 | width = 32; /* Break into two 32-bit transfers */ | ||
237 | } | ||
238 | |||
239 | /* | 222 | /* |
240 | * Two address spaces supported: Memory or IO. PCI_Config is | 223 | * Two address spaces supported: Memory or IO. PCI_Config is |
241 | * not supported here because the GAS structure is insufficient | 224 | * not supported here because the GAS structure is insufficient |
242 | */ | 225 | */ |
243 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 226 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
244 | status = acpi_os_write_memory((acpi_physical_address) | 227 | status = acpi_os_write_memory((acpi_physical_address) |
245 | address, ACPI_LODWORD(value), | 228 | address, value, reg->bit_width); |
246 | width); | ||
247 | if (ACPI_FAILURE(status)) { | 229 | if (ACPI_FAILURE(status)) { |
248 | return (status); | 230 | return (status); |
249 | } | 231 | } |
232 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
250 | 233 | ||
251 | if (reg->bit_width == 64) { | 234 | width = reg->bit_width; |
252 | status = acpi_os_write_memory((acpi_physical_address) | 235 | if (width == 64) { |
253 | (address + 4), | 236 | width = 32; /* Break into two 32-bit transfers */ |
254 | ACPI_HIDWORD(value), 32); | ||
255 | if (ACPI_FAILURE(status)) { | ||
256 | return (status); | ||
257 | } | ||
258 | } | 237 | } |
259 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
260 | 238 | ||
261 | status = acpi_hw_write_port((acpi_io_address) | 239 | status = acpi_hw_write_port((acpi_io_address) |
262 | address, ACPI_LODWORD(value), | 240 | address, ACPI_LODWORD(value), |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index e5d53b7ddc7e..ca773683d87e 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -605,7 +605,7 @@ int apei_read(u64 *val, struct acpi_generic_address *reg) | |||
605 | *val = 0; | 605 | *val = 0; |
606 | switch(reg->space_id) { | 606 | switch(reg->space_id) { |
607 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 607 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
608 | status = acpi_os_read_memory64((acpi_physical_address) | 608 | status = acpi_os_read_memory((acpi_physical_address) |
609 | address, val, reg->bit_width); | 609 | address, val, reg->bit_width); |
610 | if (ACPI_FAILURE(status)) | 610 | if (ACPI_FAILURE(status)) |
611 | return -EIO; | 611 | return -EIO; |
@@ -636,7 +636,7 @@ int apei_write(u64 val, struct acpi_generic_address *reg) | |||
636 | 636 | ||
637 | switch (reg->space_id) { | 637 | switch (reg->space_id) { |
638 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 638 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
639 | status = acpi_os_write_memory64((acpi_physical_address) | 639 | status = acpi_os_write_memory((acpi_physical_address) |
640 | address, val, reg->bit_width); | 640 | address, val, reg->bit_width); |
641 | if (ACPI_FAILURE(status)) | 641 | if (ACPI_FAILURE(status)) |
642 | return -EIO; | 642 | return -EIO; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 412a1e04a922..1dea025e4e98 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -699,49 +699,6 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) | |||
699 | 699 | ||
700 | EXPORT_SYMBOL(acpi_os_write_port); | 700 | EXPORT_SYMBOL(acpi_os_write_port); |
701 | 701 | ||
702 | acpi_status | ||
703 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | ||
704 | { | ||
705 | void __iomem *virt_addr; | ||
706 | unsigned int size = width / 8; | ||
707 | bool unmap = false; | ||
708 | u32 dummy; | ||
709 | |||
710 | rcu_read_lock(); | ||
711 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | ||
712 | if (!virt_addr) { | ||
713 | rcu_read_unlock(); | ||
714 | virt_addr = acpi_os_ioremap(phys_addr, size); | ||
715 | if (!virt_addr) | ||
716 | return AE_BAD_ADDRESS; | ||
717 | unmap = true; | ||
718 | } | ||
719 | |||
720 | if (!value) | ||
721 | value = &dummy; | ||
722 | |||
723 | switch (width) { | ||
724 | case 8: | ||
725 | *(u8 *) value = readb(virt_addr); | ||
726 | break; | ||
727 | case 16: | ||
728 | *(u16 *) value = readw(virt_addr); | ||
729 | break; | ||
730 | case 32: | ||
731 | *(u32 *) value = readl(virt_addr); | ||
732 | break; | ||
733 | default: | ||
734 | BUG(); | ||
735 | } | ||
736 | |||
737 | if (unmap) | ||
738 | iounmap(virt_addr); | ||
739 | else | ||
740 | rcu_read_unlock(); | ||
741 | |||
742 | return AE_OK; | ||
743 | } | ||
744 | |||
745 | #ifdef readq | 702 | #ifdef readq |
746 | static inline u64 read64(const volatile void __iomem *addr) | 703 | static inline u64 read64(const volatile void __iomem *addr) |
747 | { | 704 | { |
@@ -758,7 +715,7 @@ static inline u64 read64(const volatile void __iomem *addr) | |||
758 | #endif | 715 | #endif |
759 | 716 | ||
760 | acpi_status | 717 | acpi_status |
761 | acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) | 718 | acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) |
762 | { | 719 | { |
763 | void __iomem *virt_addr; | 720 | void __iomem *virt_addr; |
764 | unsigned int size = width / 8; | 721 | unsigned int size = width / 8; |
@@ -803,45 +760,6 @@ acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) | |||
803 | return AE_OK; | 760 | return AE_OK; |
804 | } | 761 | } |
805 | 762 | ||
806 | acpi_status | ||
807 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | ||
808 | { | ||
809 | void __iomem *virt_addr; | ||
810 | unsigned int size = width / 8; | ||
811 | bool unmap = false; | ||
812 | |||
813 | rcu_read_lock(); | ||
814 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | ||
815 | if (!virt_addr) { | ||
816 | rcu_read_unlock(); | ||
817 | virt_addr = acpi_os_ioremap(phys_addr, size); | ||
818 | if (!virt_addr) | ||
819 | return AE_BAD_ADDRESS; | ||
820 | unmap = true; | ||
821 | } | ||
822 | |||
823 | switch (width) { | ||
824 | case 8: | ||
825 | writeb(value, virt_addr); | ||
826 | break; | ||
827 | case 16: | ||
828 | writew(value, virt_addr); | ||
829 | break; | ||
830 | case 32: | ||
831 | writel(value, virt_addr); | ||
832 | break; | ||
833 | default: | ||
834 | BUG(); | ||
835 | } | ||
836 | |||
837 | if (unmap) | ||
838 | iounmap(virt_addr); | ||
839 | else | ||
840 | rcu_read_unlock(); | ||
841 | |||
842 | return AE_OK; | ||
843 | } | ||
844 | |||
845 | #ifdef writeq | 763 | #ifdef writeq |
846 | static inline void write64(u64 val, volatile void __iomem *addr) | 764 | static inline void write64(u64 val, volatile void __iomem *addr) |
847 | { | 765 | { |
@@ -856,7 +774,7 @@ static inline void write64(u64 val, volatile void __iomem *addr) | |||
856 | #endif | 774 | #endif |
857 | 775 | ||
858 | acpi_status | 776 | acpi_status |
859 | acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width) | 777 | acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width) |
860 | { | 778 | { |
861 | void __iomem *virt_addr; | 779 | void __iomem *virt_addr; |
862 | unsigned int size = width / 8; | 780 | unsigned int size = width / 8; |