[PATCH 01/15] ARM: Add fixed PCI i/o mapping
Rob Herring
robherring2 at gmail.com
Fri Jul 6 14:40:26 EDT 2012
From: Rob Herring <rob.herring at calxeda.com>
This adds a fixed virtual mapping for PCI i/o addresses. The mapping is
located at the last 2MB of vmalloc region (0xfee00000-0xff000000).
Signed-off-by: Rob Herring <rob.herring at calxeda.com>
Cc: Russell King <linux at arm.linux.org.uk>
Acked-by: Nicolas Pitre <nico at linaro.org>
---
Documentation/arm/memory.txt | 3 +++
arch/arm/include/asm/io.h | 5 +++++
arch/arm/include/asm/mach/pci.h | 18 ++++++++++++++++++
arch/arm/kernel/bios32.c | 20 ++++++++++++++++++++
4 files changed, 46 insertions(+)
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index 208a2d4..4bfb9ff 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -51,6 +51,9 @@ ffc00000 ffefffff DMA memory mapping region. Memory returned
ff000000 ffbfffff Reserved for future expansion of DMA
mapping region.
+fee00000 feffffff Mapping of PCI I/O space. This is a static
+ mapping within the vmalloc space.
+
VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space.
Memory returned by vmalloc/ioremap will
be dynamically placed in this region.
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 815c669..e8bb4d2 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -113,11 +113,16 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
#define __iowmb() do { } while (0)
#endif
+#define PCI_IO_VIRT_BASE 0xfee00000
+
/*
* Now, pick up the machine-defined IO definitions
*/
#ifdef CONFIG_NEED_MACH_IO_H
#include <mach/io.h>
+#elif defined(CONFIG_PCI)
+#define IO_SPACE_LIMIT ((resource_size_t)0x1fffff)
+#define __io(a) __typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
#else
#define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT)
#endif
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 26c511f..20a04af 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -55,6 +55,24 @@ struct pci_sys_data {
void pci_common_init(struct hw_pci *);
/*
+ * Setup fixed I/O mapping. Must be called from .map_io function.
+ */
+#ifdef CONFIG_PCI
+extern void pci_map_io_pfn(unsigned long pfn[], int nr, int size);
+#else
+static inline void pci_map_io_pfn(unsigned long pfn[], int nr, int size) {}
+#endif
+static inline void __init pci_map_io_single_pfn(unsigned long pfn)
+{
+ pci_map_io_pfn(&pfn, 1, SZ_1M);
+}
+
+static inline void __init pci_map_io_single(unsigned long paddr)
+{
+ pci_map_io_single_pfn(__phys_to_pfn(paddr));
+}
+
+/*
* PCI controllers
*/
extern struct pci_ops iop3xx_ops;
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 2555250..0ea0135 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -13,6 +13,7 @@
#include <linux/io.h>
#include <asm/mach-types.h>
+#include <asm/mach/map.h>
#include <asm/mach/pci.h>
static int debug_pci;
@@ -627,3 +628,22 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return 0;
}
+
+static struct map_desc pci_io_desc __initdata = {
+ .virtual = PCI_IO_VIRT_BASE,
+ .type = MT_DEVICE,
+};
+
+void __init pci_map_io_pfn(unsigned long pfn[], int nr, int size)
+{
+ int i;
+
+ pci_io_desc.length = size;
+
+ for (i = 0; i < nr; i++) {
+ pci_io_desc.pfn = pfn[i];
+ iotable_init(&pci_io_desc, 1);
+
+ pci_io_desc.virtual += size;
+ }
+}
--
1.7.9.5
More information about the linux-arm-kernel
mailing list