aboutsummaryrefslogtreecommitdiff
path: root/arch/arm64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/Kconfig5
-rw-r--r--arch/arm64/include/asm/io.h55
-rw-r--r--arch/arm64/include/asm/pci.h1
-rw-r--r--arch/arm64/kernel/setup.c18
4 files changed, 78 insertions, 1 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3dcd7ec69bca..8fb22826599f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -232,6 +232,11 @@ config KERNEL_MODE_NEON
config FIX_EARLYCON_MEM
def_bool y
+config ARM64_INDIRECT_PIO
+ bool
+ help
+ This enables support for arm64 indirect port io
+
config PGTABLE_LEVELS
int
default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 35b2e50f17fb..5c5fedd6155c 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -193,6 +193,61 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
#define iowrite64be(v,p) ({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+#define PCIBIOS_MIN_IO 0x1000
+
+#ifdef CONFIG_ARM64_INDIRECT_PIO
+typedef int (*arm64_isa_io)(unsigned long port, bool dir, u32 sz, void *data);
+extern arm64_isa_io arm64_isa_pio;
+extern int arm64_set_isa_pio(arm64_isa_io _arm64_isa_pio);
+
+#define DEF_ISA_PORT_IN(name, ret, port, df_func) \
+static inline ret name(unsigned long port)\
+{ \
+ u32 v; \
+ u32 size = sizeof(ret);\
+ if ((arm64_isa_pio) && port < PCIBIOS_MIN_IO) {\
+ (void)(*arm64_isa_pio)(port, 1, size, &v);\
+ return (ret)v;\
+ } else { \
+ return df_func(PCI_IOBASE + port);\
+ } \
+}
+
+#define DEF_ISA_PORT_OUT(name, type, val, port, df_func) \
+static inline void name(type val, unsigned long port)\
+{ \
+ if ((arm64_isa_pio) && port < PCIBIOS_MIN_IO) {\
+ (void)(*arm64_isa_pio)(port, 0, sizeof(type), &val);\
+ } else { \
+ df_func(val, PCI_IOBASE + port);\
+ } \
+}
+#define inb inb
+DEF_ISA_PORT_IN(inb, u8, port, readb);
+#define inw inw
+DEF_ISA_PORT_IN(inw, u16, port, readw);
+#define inl inl
+DEF_ISA_PORT_IN(inl, u32, port, readl);
+#define outb outb
+DEF_ISA_PORT_OUT(outb, u8, val, port, writeb);
+#define outw outw
+DEF_ISA_PORT_OUT(outw, u16, val, port, writew);
+#define outl outl
+DEF_ISA_PORT_OUT(outl, u32, val, port, writel);
+
+#endif
+
#include <asm-generic/io.h>
/*
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
index 1fc19744ffe9..c00e8202e173 100644
--- a/arch/arm64/include/asm/pci.h
+++ b/arch/arm64/include/asm/pci.h
@@ -8,7 +8,6 @@
#include <asm/io.h>
-#define PCIBIOS_MIN_IO 0x1000
#define PCIBIOS_MIN_MEM 0
/*
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 2c822ef94f34..3f9efe4d9f9d 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -237,6 +237,24 @@ static void __init request_standard_resources(void)
}
}
+#if defined(CONFIG_ARM64_INDIRECT_PIO)
+arm64_isa_io arm64_isa_pio;
+EXPORT_SYMBOL_GPL(arm64_isa_pio);
+
+int arm64_set_isa_pio(arm64_isa_io _arm64_isa_pio)
+{
+ if (arm64_isa_pio) {
+ pr_err("arm64 indirect port io have been hooked by others!\n");
+ return -EINVAL;
+ }
+
+ arm64_isa_pio = _arm64_isa_pio;
+
+ return 0;
+}
+
+#endif
+
u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
void __init setup_arch(char **cmdline_p)