aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2017-04-19 12:48:53 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-04-24 14:53:13 -0400
commitb9cdbe6e39351f0ba6cc0c5bc218443f0898e123 (patch)
tree602b8008f855067f4b13f72ff6d50f6b02059dbe
parentf1e209b7f80288a711268af9054a04d3f6900a6b (diff)
ARM: Implement pci_remap_cfgspace() interface
The PCI bus specification (rev 3.0, 3.2.5 "Transaction Ordering and Posting") defines rules for PCI configuration space transactions ordering and posting, that state that configuration writes have to be non-posted transactions. Current ioremap interface on ARM provides mapping functions that provide "bufferable" writes transactions (ie ioremap uses MT_DEVICE memory type) aka posted writes, so PCI host controller drivers have no arch interface to remap PCI configuration space with memory attributes that comply with the PCI specifications for configuration space. Implement an ARM specific pci_remap_cfgspace() interface that allows to map PCI config memory regions with MT_UNCACHED memory type (ie strongly ordered - non-posted writes), providing a remap function that complies with PCI specifications for config space transactions. Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Russell King <linux@armlinux.org.uk>
-rw-r--r--arch/arm/include/asm/io.h10
-rw-r--r--arch/arm/mm/ioremap.c7
-rw-r--r--arch/arm/mm/nommu.c12
3 files changed, 29 insertions, 0 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 42871fb8340e..2cfbc531f63b 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -187,6 +187,16 @@ static inline void pci_ioremap_set_mem_type(int mem_type) {}
187extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr); 187extern int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr);
188 188
189/* 189/*
190 * PCI configuration space mapping function.
191 *
192 * The PCI specification does not allow configuration write
193 * transactions to be posted. Add an arch specific
194 * pci_remap_cfgspace() definition that is implemented
195 * through strongly ordered memory mappings.
196 */
197#define pci_remap_cfgspace pci_remap_cfgspace
198void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size);
199/*
190 * Now, pick up the machine-defined IO definitions 200 * Now, pick up the machine-defined IO definitions
191 */ 201 */
192#ifdef CONFIG_NEED_MACH_IO_H 202#ifdef CONFIG_NEED_MACH_IO_H
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index ff0eed23ddf1..fc91205ff46c 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -481,6 +481,13 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
481 __pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte)); 481 __pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte));
482} 482}
483EXPORT_SYMBOL_GPL(pci_ioremap_io); 483EXPORT_SYMBOL_GPL(pci_ioremap_io);
484
485void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size)
486{
487 return arch_ioremap_caller(res_cookie, size, MT_UNCACHED,
488 __builtin_return_address(0));
489}
490EXPORT_SYMBOL_GPL(pci_remap_cfgspace);
484#endif 491#endif
485 492
486/* 493/*
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 3b5c7aaf9c76..2a3f6002efbc 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -433,6 +433,18 @@ void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size)
433} 433}
434EXPORT_SYMBOL(ioremap_wc); 434EXPORT_SYMBOL(ioremap_wc);
435 435
436#ifdef CONFIG_PCI
437
438#include <asm/mach/map.h>
439
440void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size)
441{
442 return arch_ioremap_caller(res_cookie, size, MT_UNCACHED,
443 __builtin_return_address(0));
444}
445EXPORT_SYMBOL_GPL(pci_remap_cfgspace);
446#endif
447
436void *arch_memremap_wb(phys_addr_t phys_addr, size_t size) 448void *arch_memremap_wb(phys_addr_t phys_addr, size_t size)
437{ 449{
438 return (void *)phys_addr; 450 return (void *)phys_addr;