Revisão | 495df3bad9f250a36470cce15f14c36c616172b6 (tree) |
---|---|
Hora | 2011-02-21 16:30:55 |
Autor | Wolfgang Denk <wd@denx...> |
Commiter | Albert Aribaud |
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>
@@ -133,9 +133,9 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen) | ||
133 | 133 | #define __iormb() dmb() |
134 | 134 | #define __iowmb() dmb() |
135 | 135 | |
136 | -#define writeb(v,c) ({ __iowmb(); __arch_putb(v,c); v; }) | |
137 | -#define writew(v,c) ({ __iowmb(); __arch_putw(v,c); v; }) | |
138 | -#define writel(v,c) ({ __iowmb(); __arch_putl(v,c); v; }) | |
136 | +#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; }) | |
137 | +#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; }) | |
138 | +#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; }) | |
139 | 139 | |
140 | 140 | #define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; }) |
141 | 141 | #define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; }) |