summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-10-26 19:42:08 +0200
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-10-29 11:04:27 +0100
commit7629a9f661f72eb383fb896e59efea1eac74e882 (patch)
tree1983cc4138765d367f91f5beb2d656418a16d8bc /arch/arm
parentARM: 7566/1: vfp: fix save and restore when running on pre-VFPv3 and CONFIG_V... (diff)
downloadlinux-7629a9f661f72eb383fb896e59efea1eac74e882.tar.xz
linux-7629a9f661f72eb383fb896e59efea1eac74e882.zip
ARM: 7567/1: io: avoid GCC's offsettable addressing modes for halfword accesses
Using the 'o' memory constraint in inline assembly can result in GCC generating invalid immediate offsets for memory access instructions with reduced addressing capabilities (i.e. smaller than 12-bit immediate offsets): http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54983 As there is no constraint to specify the exact addressing mode we need, fallback to using 'Q' exclusively for halfword I/O accesses. This may emit an additional add instruction (using an extra register) in order to construct the address but it will always be accepted by GAS. Reported-by: Bastian Hecht <hechtb@googlemail.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/io.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 35c1ed89b936..42f042ee4ada 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
asm volatile("strh %1, %0"
- : "+Qo" (*(volatile u16 __force *)addr)
+ : "+Q" (*(volatile u16 __force *)addr)
: "r" (val));
}
@@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr)
{
u16 val;
asm volatile("ldrh %1, %0"
- : "+Qo" (*(volatile u16 __force *)addr),
+ : "+Q" (*(volatile u16 __force *)addr),
"=r" (val));
return val;
}