Commit c17b0aad authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'asm-generic' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic

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
parents e241e3f2 a71e7c44
...@@ -25,6 +25,50 @@ ...@@ -25,6 +25,50 @@
#define mmiowb() do {} while (0) #define mmiowb() do {} while (0)
#endif #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. * __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) ...@@ -110,7 +154,12 @@ static inline void __raw_writeq(u64 value, volatile void __iomem *addr)
#define readb readb #define readb readb
static inline u8 readb(const volatile void __iomem *addr) 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 #endif
...@@ -118,7 +167,12 @@ static inline u8 readb(const volatile void __iomem *addr) ...@@ -118,7 +167,12 @@ static inline u8 readb(const volatile void __iomem *addr)
#define readw readw #define readw readw
static inline u16 readw(const volatile void __iomem *addr) 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 #endif
...@@ -126,7 +180,12 @@ static inline u16 readw(const volatile void __iomem *addr) ...@@ -126,7 +180,12 @@ static inline u16 readw(const volatile void __iomem *addr)
#define readl readl #define readl readl
static inline u32 readl(const volatile void __iomem *addr) 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 #endif
...@@ -135,7 +194,12 @@ static inline u32 readl(const volatile void __iomem *addr) ...@@ -135,7 +194,12 @@ static inline u32 readl(const volatile void __iomem *addr)
#define readq readq #define readq readq
static inline u64 readq(const volatile void __iomem *addr) 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
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
...@@ -144,7 +208,9 @@ static inline u64 readq(const volatile void __iomem *addr) ...@@ -144,7 +208,9 @@ static inline u64 readq(const volatile void __iomem *addr)
#define writeb writeb #define writeb writeb
static inline void writeb(u8 value, volatile void __iomem *addr) static inline void writeb(u8 value, volatile void __iomem *addr)
{ {
__io_bw();
__raw_writeb(value, addr); __raw_writeb(value, addr);
__io_aw();
} }
#endif #endif
...@@ -152,7 +218,9 @@ static inline void writeb(u8 value, volatile void __iomem *addr) ...@@ -152,7 +218,9 @@ static inline void writeb(u8 value, volatile void __iomem *addr)
#define writew writew #define writew writew
static inline void writew(u16 value, volatile void __iomem *addr) static inline void writew(u16 value, volatile void __iomem *addr)
{ {
__io_bw();
__raw_writew(cpu_to_le16(value), addr); __raw_writew(cpu_to_le16(value), addr);
__io_aw();
} }
#endif #endif
...@@ -160,7 +228,9 @@ static inline void writew(u16 value, volatile void __iomem *addr) ...@@ -160,7 +228,9 @@ static inline void writew(u16 value, volatile void __iomem *addr)
#define writel writel #define writel writel
static inline void writel(u32 value, volatile void __iomem *addr) static inline void writel(u32 value, volatile void __iomem *addr)
{ {
__io_bw();
__raw_writel(__cpu_to_le32(value), addr); __raw_writel(__cpu_to_le32(value), addr);
__io_aw();
} }
#endif #endif
...@@ -169,7 +239,9 @@ static inline void writel(u32 value, volatile void __iomem *addr) ...@@ -169,7 +239,9 @@ static inline void writel(u32 value, volatile void __iomem *addr)
#define writeq writeq #define writeq writeq
static inline void writeq(u64 value, volatile void __iomem *addr) static inline void writeq(u64 value, volatile void __iomem *addr)
{ {
__io_bw();
__raw_writeq(__cpu_to_le64(value), addr); __raw_writeq(__cpu_to_le64(value), addr);
__io_aw();
} }
#endif #endif
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
...@@ -180,35 +252,67 @@ static inline void writeq(u64 value, volatile void __iomem *addr) ...@@ -180,35 +252,67 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
* accesses. * accesses.
*/ */
#ifndef readb_relaxed #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 #endif
#ifndef readw_relaxed #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 #endif
#ifndef readl_relaxed #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 #endif
#if defined(readq) && !defined(readq_relaxed) #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 #endif
#ifndef writeb_relaxed #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 #endif
#ifndef writew_relaxed #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 #endif
#ifndef writel_relaxed #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 #endif
#if defined(writeq) && !defined(writeq_relaxed) #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 #endif
/* /*
...@@ -363,7 +467,12 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer, ...@@ -363,7 +467,12 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer,
#define inb inb #define inb inb
static inline u8 inb(unsigned long addr) 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 #endif
...@@ -371,7 +480,12 @@ static inline u8 inb(unsigned long addr) ...@@ -371,7 +480,12 @@ static inline u8 inb(unsigned long addr)
#define inw inw #define inw inw
static inline u16 inw(unsigned long addr) 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 #endif
...@@ -379,7 +493,12 @@ static inline u16 inw(unsigned long addr) ...@@ -379,7 +493,12 @@ static inline u16 inw(unsigned long addr)
#define inl inl #define inl inl
static inline u32 inl(unsigned long addr) 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 #endif
...@@ -387,7 +506,9 @@ static inline u32 inl(unsigned long addr) ...@@ -387,7 +506,9 @@ static inline u32 inl(unsigned long addr)
#define outb outb #define outb outb
static inline void outb(u8 value, unsigned long addr) 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 #endif
...@@ -395,7 +516,9 @@ static inline void outb(u8 value, unsigned long addr) ...@@ -395,7 +516,9 @@ static inline void outb(u8 value, unsigned long addr)
#define outw outw #define outw outw
static inline void outw(u16 value, unsigned long addr) 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 #endif
...@@ -403,7 +526,9 @@ static inline void outw(u16 value, unsigned long addr) ...@@ -403,7 +526,9 @@ static inline void outw(u16 value, unsigned long addr)
#define outl outl #define outl outl
static inline void outl(u32 value, unsigned long addr) 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 #endif
......
../../../arch/cris/boot/dts
\ No newline at end of file
../../../arch/metag/boot/dts
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment