@@ -100,9 +100,45 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr)
100100
101101}
102102
103- #define readb_relaxed readb
104- #define readw_relaxed readw
105- #define readl_relaxed readl
103+ #ifdef CONFIG_ISA_ARCV2
104+ #include <asm/barrier.h>
105+ #define __iormb () rmb()
106+ #define __iowmb () wmb()
107+ #else
108+ #define __iormb () do { } while (0)
109+ #define __iowmb () do { } while (0)
110+ #endif
111+
112+ /*
113+ * MMIO can also get buffered/optimized in micro-arch, so barriers needed
114+ * Based on ARM model for the typical use case
115+ *
116+ * <writel_relaxed DMA buffer>
117+ * <writel MMIO "go" reg>
118+ * or:
119+ * <readl MMIO "status" reg>
120+ * <readl_relaxed DMA buffer>
121+ *
122+ * http://www.spinics.net/lists/kernel/msg2018397.html
123+ */
124+ #define readb (c ) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
125+ #define readw (c ) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
126+ #define readl (c ) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
127+
128+ #define writeb (v ,c ) ({ __iowmb(); writeb_relaxed(v,c); })
129+ #define writew (v ,c ) ({ __iowmb(); writew_relaxed(v,c); })
130+ #define writel (v ,c ) ({ __iowmb(); writel_relaxed(v,c); })
131+
132+ /*
133+ * Relaxed API for drivers which can handle any ordering themselves
134+ */
135+ #define readb_relaxed (c ) __raw_readb(c)
136+ #define readw_relaxed (c ) __raw_readw(c)
137+ #define readl_relaxed (c ) __raw_readl(c)
138+
139+ #define writeb_relaxed (v ,c ) __raw_writeb(v,c)
140+ #define writew_relaxed (v ,c ) __raw_writew(v,c)
141+ #define writel_relaxed (v ,c ) __raw_writel(v,c)
106142
107143#include <asm-generic/io.h>
108144
0 commit comments