|
|
@@ -98,9 +98,45 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr)
|
|
|
|
|
|
}
|
|
|
|
|
|
-#define readb_relaxed readb
|
|
|
-#define readw_relaxed readw
|
|
|
-#define readl_relaxed readl
|
|
|
+#ifdef CONFIG_ISA_ARCV2
|
|
|
+#include <asm/barrier.h>
|
|
|
+#define __iormb() rmb()
|
|
|
+#define __iowmb() wmb()
|
|
|
+#else
|
|
|
+#define __iormb() do { } while (0)
|
|
|
+#define __iowmb() do { } while (0)
|
|
|
+#endif
|
|
|
+
|
|
|
+/*
|
|
|
+ * MMIO can also get buffered/optimized in micro-arch, so barriers needed
|
|
|
+ * Based on ARM model for the typical use case
|
|
|
+ *
|
|
|
+ * <ST [DMA buffer]>
|
|
|
+ * <writel MMIO "go" reg>
|
|
|
+ * or:
|
|
|
+ * <readl MMIO "status" reg>
|
|
|
+ * <LD [DMA buffer]>
|
|
|
+ *
|
|
|
+ * http://lkml.kernel.org/r/20150622133656.GG1583@arm.com
|
|
|
+ */
|
|
|
+#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
|
|
|
+#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
|
|
|
+#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
|
|
|
+
|
|
|
+#define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); })
|
|
|
+#define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); })
|
|
|
+#define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); })
|
|
|
+
|
|
|
+/*
|
|
|
+ * Relaxed API for drivers which can handle any ordering themselves
|
|
|
+ */
|
|
|
+#define readb_relaxed(c) __raw_readb(c)
|
|
|
+#define readw_relaxed(c) __raw_readw(c)
|
|
|
+#define readl_relaxed(c) __raw_readl(c)
|
|
|
+
|
|
|
+#define writeb_relaxed(v,c) __raw_writeb(v,c)
|
|
|
+#define writew_relaxed(v,c) __raw_writew(v,c)
|
|
|
+#define writel_relaxed(v,c) __raw_writel(v,c)
|
|
|
|
|
|
#include <asm-generic/io.h>
|
|
|
|