aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/include/asm/io.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 21:20:57 +0900
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 21:20:57 +0900
commit0e51793e162ca432fc5f04178cf82b80a92c2659 (patch)
treecf7ffdb5064e2f7b6647a63e7323d1c4e99b7739 /arch/arm/include/asm/io.h
parent5cad3598ea0cdb817681f74518d3213583a04f7a (diff)
parentb4874a3d298606c20118d1ead73235439bbc2823 (diff)
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
Pull ARM updates from Russell King: "This is the first chunk of ARM updates for this merge window. Conflicts are expected in two files - asm/timex.h and mach-integrator/integrator_cp.c. Nothing particularly stands out more than anything else. Most of the growth is down to the opcodes stuff from Dave Martin, which is countered by Rob's patches to use more of the asm-generic headers on ARM." (A few more conflicts grew since then, but it all looked fairly trivial) * 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (44 commits) ARM: 7548/1: include linux/sched.h in syscall.h ARM: 7541/1: Add ARM ERRATA 775420 workaround ARM: ensure vm_struct has its phys_addr member filled in ARM: 7540/1: kexec: Check segment memory addresses ARM: 7539/1: kexec: scan for dtb magic in segments ARM: 7538/1: delay: add registration mechanism for delay timer sources ARM: 7536/1: smp: Formalize an IPI for wakeup ARM: 7525/1: ptrace: use updated syscall number for syscall auditing ARM: 7524/1: support syscall tracing ARM: 7519/1: integrator: convert platform devices to Device Tree ARM: 7518/1: integrator: convert AMBA devices to device tree ARM: 7517/1: integrator: initial device tree support ARM: 7516/1: plat-versatile: add DT support to FPGA IRQ ARM: 7515/1: integrator: check PL010 base address from resource ARM: 7514/1: integrator: call common init function from machine ARM: 7522/1: arch_timers: register a time/cycle counter ARM: 7523/1: arch_timers: enable the use of the virtual timer ARM: 7531/1: mark kernelmode mem{cpy,set} non-experimental ARM: 7520/1: Build dtb files in all target ARM: Fix build warning in arch/arm/mm/alignment.c ...
Diffstat (limited to 'arch/arm/include/asm/io.h')
-rw-r--r--arch/arm/include/asm/io.h67
1 files changed, 61 insertions, 6 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 8f4db67533e..35c1ed89b93 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -47,13 +47,68 @@ extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);
extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
-#define __raw_writeb(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)))
-#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
-#define __raw_writel(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)))
+#if __LINUX_ARM_ARCH__ < 6
+/*
+ * Half-word accesses are problematic with RiscPC due to limitations of
+ * the bus. Rather than special-case the machine, just let the compiler
+ * generate the access for CPUs prior to ARMv6.
+ */
+#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
+#else
+/*
+ * When running under a hypervisor, we want to avoid I/O accesses with
+ * writeback addressing modes as these incur a significant performance
+ * overhead (the address generation must be emulated in software).
+ */
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+ asm volatile("strh %1, %0"
+ : "+Qo" (*(volatile u16 __force *)addr)
+ : "r" (val));
+}
+
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+ u16 val;
+ asm volatile("ldrh %1, %0"
+ : "+Qo" (*(volatile u16 __force *)addr),
+ "=r" (val));
+ return val;
+}
+#endif
-#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
-#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
-#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+ asm volatile("strb %1, %0"
+ : "+Qo" (*(volatile u8 __force *)addr)
+ : "r" (val));
+}
+
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+ asm volatile("str %1, %0"
+ : "+Qo" (*(volatile u32 __force *)addr)
+ : "r" (val));
+}
+
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+ u8 val;
+ asm volatile("ldrb %1, %0"
+ : "+Qo" (*(volatile u8 __force *)addr),
+ "=r" (val));
+ return val;
+}
+
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+ u32 val;
+ asm volatile("ldr %1, %0"
+ : "+Qo" (*(volatile u32 __force *)addr),
+ "=r" (val));
+ return val;
+}
/*
* Architecture ioremap implementation.