Merge tag 'asm-generic' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Apr 2018 16:15:48 +0000 (09:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 12 Apr 2018 16:15:48 +0000 (09:15 -0700)
Pull asm-generic fixes from Arnd Bergmann:
 "I have one regression fix for a minor build problem after the
  architecture removal series, plus a rework of the barriers in the
  readl/writel functions, thanks to work by Sinan Kaya:

  This started from a discussion on the linuxpcc and rdma mailing
  lists[1]. To summarize, we decided that architectures are responsible
  to serialize readl() and writel() accesses on a device MMIO space
  relative to DMA performed by that device.

  This series provides a pessimistic implementation of that behavior for
  asm-generic/io.h, which is in turn used by a number of architectures
  (h8300, microblaze, nios2, openrisc, s390, sparc, um, unicore32, and
  xtensa). Some of those presumably need no extra barriers, or something
  weaker than rmb()/wmb(), and they are advised to override the new
  default for better performance.

  For inb()/outb(), the same barriers are used, but architectures might
  want to add another barrier to outb() here if that can guarantee
  non-posted behavior (some architectures can, others cannot do that).

  The readl_relaxed()/writel_relaxed() family of functions retains the
  existing behavior with no extra barriers"

[1] https://lists.ozlabs.org/pipermail/linuxppc-dev/2018-March/170481.html

* tag 'asm-generic' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic:
  io: change writeX_relaxed() to remove barriers
  io: change readX_relaxed() to remove barriers
  dts: remove cris & metag dts hard link file
  io: change inX() to have their own IO barrier overrides
  io: change outX() to have their own IO barrier overrides
  io: define stronger ordering for the default writeX() implementation
  io: define stronger ordering for the default readX() implementation
  io: define several IO & PIO barrier types for the asm-generic version

include/asm-generic/io.h
scripts/dtc/include-prefixes/cris [deleted symlink]
scripts/dtc/include-prefixes/metag [deleted symlink]

index 04c4cc6fd820ae28b7a072d47e5f8d74acfe9f5e..66d1d45fa2e1c11dcf17231f0a32f883bb2c1a12 100644 (file)
 #define mmiowb() do {} while (0)
 #endif
 
+#ifndef __io_br
+#define __io_br()      barrier()
+#endif
+
+/* prevent prefetching of coherent DMA data ahead of a dma-complete */
+#ifndef __io_ar
+#ifdef rmb
+#define __io_ar()      rmb()
+#else
+#define __io_ar()      barrier()
+#endif
+#endif
+
+/* flush writes to coherent DMA data before possibly triggering a DMA read */
+#ifndef __io_bw
+#ifdef wmb
+#define __io_bw()      wmb()
+#else
+#define __io_bw()      barrier()
+#endif
+#endif
+
+/* serialize device access against a spin_unlock, usually handled there. */
+#ifndef __io_aw
+#define __io_aw()      barrier()
+#endif
+
+#ifndef __io_pbw
+#define __io_pbw()     __io_bw()
+#endif
+
+#ifndef __io_paw
+#define __io_paw()     __io_aw()
+#endif
+
+#ifndef __io_pbr
+#define __io_pbr()     __io_br()
+#endif
+
+#ifndef __io_par
+#define __io_par()     __io_ar()
+#endif
+
+
 /*
  * __raw_{read,write}{b,w,l,q}() access memory in native endianness.
  *
@@ -110,7 +154,12 @@ static inline void __raw_writeq(u64 value, volatile void __iomem *addr)
 #define readb readb
 static inline u8 readb(const volatile void __iomem *addr)
 {
-       return __raw_readb(addr);
+       u8 val;
+
+       __io_br();
+       val = __raw_readb(addr);
+       __io_ar();
+       return val;
 }
 #endif
 
@@ -118,7 +167,12 @@ static inline u8 readb(const volatile void __iomem *addr)
 #define readw readw
 static inline u16 readw(const volatile void __iomem *addr)
 {
-       return __le16_to_cpu(__raw_readw(addr));
+       u16 val;
+
+       __io_br();
+       val = __le16_to_cpu(__raw_readw(addr));
+       __io_ar();
+       return val;
 }
 #endif
 
@@ -126,7 +180,12 @@ static inline u16 readw(const volatile void __iomem *addr)
 #define readl readl
 static inline u32 readl(const volatile void __iomem *addr)
 {
-       return __le32_to_cpu(__raw_readl(addr));
+       u32 val;
+
+       __io_br();
+       val = __le32_to_cpu(__raw_readl(addr));
+       __io_ar();
+       return val;
 }
 #endif
 
@@ -135,7 +194,12 @@ static inline u32 readl(const volatile void __iomem *addr)
 #define readq readq
 static inline u64 readq(const volatile void __iomem *addr)
 {
-       return __le64_to_cpu(__raw_readq(addr));
+       u64 val;
+
+       __io_br();
+       val = __le64_to_cpu(__raw_readq(addr));
+       __io_ar();
+       return val;
 }
 #endif
 #endif /* CONFIG_64BIT */
@@ -144,7 +208,9 @@ static inline u64 readq(const volatile void __iomem *addr)
 #define writeb writeb
 static inline void writeb(u8 value, volatile void __iomem *addr)
 {
+       __io_bw();
        __raw_writeb(value, addr);
+       __io_aw();
 }
 #endif
 
@@ -152,7 +218,9 @@ static inline void writeb(u8 value, volatile void __iomem *addr)
 #define writew writew
 static inline void writew(u16 value, volatile void __iomem *addr)
 {
+       __io_bw();
        __raw_writew(cpu_to_le16(value), addr);
+       __io_aw();
 }
 #endif
 
@@ -160,7 +228,9 @@ static inline void writew(u16 value, volatile void __iomem *addr)
 #define writel writel
 static inline void writel(u32 value, volatile void __iomem *addr)
 {
+       __io_bw();
        __raw_writel(__cpu_to_le32(value), addr);
+       __io_aw();
 }
 #endif
 
@@ -169,7 +239,9 @@ static inline void writel(u32 value, volatile void __iomem *addr)
 #define writeq writeq
 static inline void writeq(u64 value, volatile void __iomem *addr)
 {
+       __io_bw();
        __raw_writeq(__cpu_to_le64(value), addr);
+       __io_aw();
 }
 #endif
 #endif /* CONFIG_64BIT */
@@ -180,35 +252,67 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
  * accesses.
  */
 #ifndef readb_relaxed
-#define readb_relaxed readb
+#define readb_relaxed readb_relaxed
+static inline u8 readb_relaxed(const volatile void __iomem *addr)
+{
+       return __raw_readb(addr);
+}
 #endif
 
 #ifndef readw_relaxed
-#define readw_relaxed readw
+#define readw_relaxed readw_relaxed
+static inline u16 readw_relaxed(const volatile void __iomem *addr)
+{
+       return __le16_to_cpu(__raw_readw(addr));
+}
 #endif
 
 #ifndef readl_relaxed
-#define readl_relaxed readl
+#define readl_relaxed readl_relaxed
+static inline u32 readl_relaxed(const volatile void __iomem *addr)
+{
+       return __le32_to_cpu(__raw_readl(addr));
+}
 #endif
 
 #if defined(readq) && !defined(readq_relaxed)
-#define readq_relaxed readq
+#define readq_relaxed readq_relaxed
+static inline u64 readq_relaxed(const volatile void __iomem *addr)
+{
+       return __le64_to_cpu(__raw_readq(addr));
+}
 #endif
 
 #ifndef writeb_relaxed
-#define writeb_relaxed writeb
+#define writeb_relaxed writeb_relaxed
+static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
+{
+       __raw_writeb(value, addr);
+}
 #endif
 
 #ifndef writew_relaxed
-#define writew_relaxed writew
+#define writew_relaxed writew_relaxed
+static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
+{
+       __raw_writew(cpu_to_le16(value), addr);
+}
 #endif
 
 #ifndef writel_relaxed
-#define writel_relaxed writel
+#define writel_relaxed writel_relaxed
+static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
+{
+       __raw_writel(__cpu_to_le32(value), addr);
+}
 #endif
 
 #if defined(writeq) && !defined(writeq_relaxed)
-#define writeq_relaxed writeq
+#define writeq_relaxed writeq_relaxed
+static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
+{
+       __raw_writeq(__cpu_to_le64(value), addr);
+}
 #endif
 
 /*
@@ -363,7 +467,12 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer,
 #define inb inb
 static inline u8 inb(unsigned long addr)
 {
-       return readb(PCI_IOBASE + addr);
+       u8 val;
+
+       __io_pbr();
+       val = __raw_readb(PCI_IOBASE + addr);
+       __io_par();
+       return val;
 }
 #endif
 
@@ -371,7 +480,12 @@ static inline u8 inb(unsigned long addr)
 #define inw inw
 static inline u16 inw(unsigned long addr)
 {
-       return readw(PCI_IOBASE + addr);
+       u16 val;
+
+       __io_pbr();
+       val = __le16_to_cpu(__raw_readw(PCI_IOBASE + addr));
+       __io_par();
+       return val;
 }
 #endif
 
@@ -379,7 +493,12 @@ static inline u16 inw(unsigned long addr)
 #define inl inl
 static inline u32 inl(unsigned long addr)
 {
-       return readl(PCI_IOBASE + addr);
+       u32 val;
+
+       __io_pbr();
+       val = __le32_to_cpu(__raw_readl(PCI_IOBASE + addr));
+       __io_par();
+       return val;
 }
 #endif
 
@@ -387,7 +506,9 @@ static inline u32 inl(unsigned long addr)
 #define outb outb
 static inline void outb(u8 value, unsigned long addr)
 {
-       writeb(value, PCI_IOBASE + addr);
+       __io_pbw();
+       __raw_writeb(value, PCI_IOBASE + addr);
+       __io_paw();
 }
 #endif
 
@@ -395,7 +516,9 @@ static inline void outb(u8 value, unsigned long addr)
 #define outw outw
 static inline void outw(u16 value, unsigned long addr)
 {
-       writew(value, PCI_IOBASE + addr);
+       __io_pbw();
+       __raw_writew(cpu_to_le16(value), PCI_IOBASE + addr);
+       __io_paw();
 }
 #endif
 
@@ -403,7 +526,9 @@ static inline void outw(u16 value, unsigned long addr)
 #define outl outl
 static inline void outl(u32 value, unsigned long addr)
 {
-       writel(value, PCI_IOBASE + addr);
+       __io_pbw();
+       __raw_writel(cpu_to_le32(value), PCI_IOBASE + addr);
+       __io_paw();
 }
 #endif
 
diff --git a/scripts/dtc/include-prefixes/cris b/scripts/dtc/include-prefixes/cris
deleted file mode 120000 (symlink)
index 736d998..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../arch/cris/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/metag b/scripts/dtc/include-prefixes/metag
deleted file mode 120000 (symlink)
index 87a3c84..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../arch/metag/boot/dts
\ No newline at end of file