public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] ARM: fix write*() I/O accessors
@ 2011-02-11 22:25 Wolfgang Denk
  2011-02-11 22:31 ` Albert ARIBAUD
  2011-02-11 22:51 ` Alexander Holler
  0 siblings, 2 replies; 4+ messages in thread
From: Wolfgang Denk @ 2011-02-11 22:25 UTC (permalink / raw)
  To: u-boot

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>
---

This patch fixes a pretty nasty problem.  Everybody who has
experienced strange failures on ARM lately should apply it ASAP and
re-test.  As far as I can tell at least the following drivers are
affected:

drivers/net/dnet.c:		writel(*bufp++, &dnet->regs->TX_DATA_FIFO);
drivers/usb/musb/musb_core.c:	writeb(*data++, &musbr->fifox[ep]);
drivers/mmc/pxa_mmc.c:		writel(*src++, MMC_TXFIFO);
drivers/mmc/mxcmmc.c:		writel(*buf++, &host->base->buffer_access);
drivers/spi/davinci_spi.c:	writel(data1_reg_val | *txp++, &ds->regs->dat1);

Albert, please apply ASAP!


 arch/arm/include/asm/io.h |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 3886f15..1fbc531 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; })
-- 
1.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-02-11 22:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-11 22:25 [U-Boot] [PATCH] ARM: fix write*() I/O accessors Wolfgang Denk
2011-02-11 22:31 ` Albert ARIBAUD
2011-02-11 22:40   ` Wolfgang Denk
2011-02-11 22:51 ` Alexander Holler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox