ARM64: Implement pci_remap_cfgspace() interface
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Wed, 19 Apr 2017 16:48:52 +0000 (17:48 +0100)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 24 Apr 2017 18:53:13 +0000 (13:53 -0500)
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 are non-posted
transactions.

This rule is reinforced by the ARM v8 architecture reference manual (issue
A.k, Early Write Acknowledgment) that explicitly recommends that No Early
Write Acknowledgment attribute should be used to map PCI configuration
(write) transactions.

Current ioremap interface on ARM64 implements mapping functions where the
Early Write Acknowledgment hint is enabled, so they cannot be used to map
PCI configuration space in a PCI specs compliant way.

Implement an ARM64 specific pci_remap_cfgspace() interface that allows to
map PCI config region with nGnRnE attributes, providing a remap function
that complies with PCI specifications and the ARMv8 architecture reference
manual recommendations.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
arch/arm64/include/asm/io.h

index 0c00c87..35b2e50 100644 (file)
@@ -173,6 +173,16 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 #define iounmap                                __iounmap
 
 /*
+ * PCI configuration space mapping function.
+ *
+ * The PCI specification disallows posted write configuration transactions.
+ * Add an arch specific pci_remap_cfgspace() definition that is implemented
+ * through nGnRnE device memory attribute as recommended by the ARM v8
+ * Architecture reference manual Issue A.k B2.8.2 "Device memory".
+ */
+#define pci_remap_cfgspace(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRnE))
+
+/*
  * io{read,write}{16,32,64}be() macros
  */
 #define ioread16be(p)          ({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })