diff options
author | RongrongZou <zourongrong@huawei.com> | 2016-10-18 12:52:56 +0800 |
---|---|---|
committer | Graeme Gregory <graeme.gregory@linaro.org> | 2017-06-06 10:00:41 +0100 |
commit | 3b9a01f7cd2eb37e6fc74e172b53394ba8460fcc (patch) | |
tree | 571de7750cf63ab60e4ac0f91ad5bc25d8749ff3 | |
parent | 3c2993b8c6143d8a5793746a54eba8f86f95240f (diff) | |
download | leg-kernel-3b9a01f7cd2eb37e6fc74e172b53394ba8460fcc.tar.gz |
ARM64 LPC: indirect ISA PORT IO introduced
Indirect ISA port I/O accessing introduced, vendors can hook
their own in/out function to general inb/outb. Drivers can access
legacy ISA I/O port by inb/outb as it is done in x86 platform.
Signed-off-by: RongrongZou <zourongrong@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Xinliang Liu <xinliang.liu@linaro.org>
Conflicts:
arch/arm64/include/asm/io.h
-rw-r--r-- | arch/arm64/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm64/include/asm/io.h | 55 | ||||
-rw-r--r-- | arch/arm64/include/asm/pci.h | 1 | ||||
-rw-r--r-- | arch/arm64/kernel/setup.c | 18 |
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) |