aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2011-02-11 12:25:48 +0000
committerAlbert Aribaud <albert.aribaud@free.fr>2011-02-21 08:30:55 +0100
commit495df3bad9f250a36470cce15f14c36c616172b6 (patch)
treecb5c1c1f3a4aab72b37538b527096fea076c3def
parent6087f1a90cb2f275752496229b96f0e00aa0a7cd (diff)
ARM: fix write*() I/O accessors
Commit 3c0659b "ARM: Avoid compiler optimization for readb, writeb and friends." introduced I/O accessors with memory barriers. Unfortunately the new write*() accessors introduced a bug: The problem is that the argument "v" gets evaluated twice. This breaks code like used here (from "drivers/net/dnet.c"): for (i = 0; i < wrsz; i++) writel(*bufp++, &dnet->regs->TX_DATA_FIFO); Use auxiliary variables to avoid such problems. Signed-off-by: Wolfgang Denk <wd@denx.de> Cc: Albert Aribaud <albert.aribaud@free.fr> Cc: Alexander Holler <holler@ahsoftware.de> Cc: Dirk Behme <dirk.behme@googlemail.com>
-rw-r--r--arch/arm/include/asm/io.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 3886f1589..1fbc531a0 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -133,9 +133,9 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
#define __iormb() dmb()
#define __iowmb() dmb()
-#define writeb(v,c) ({ __iowmb(); __arch_putb(v,c); v; })
-#define writew(v,c) ({ __iowmb(); __arch_putw(v,c); v; })
-#define writel(v,c) ({ __iowmb(); __arch_putl(v,c); v; })
+#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; })
+#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; })
+#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; })
#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; })
#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; })