@ -10,6 +10,46 @@
# include <linux/types.h>
# include <asm/byteorder.h>
# ifdef CONFIG_ISA_ARCV2
/*
* ARCv2 based HS38 cores are in - order issue , but still weakly ordered
* due to micro - arch buffering / queuing of load / store , cache hit vs . miss . . .
*
* Explicit barrier provided by DMB instruction
* - Operand supports fine grained load / store / load + store semantics
* - Ensures that selected memory operation issued before it will complete
* before any subsequent memory operation of same type
* - DMB guarantees SMP as well as local barrier semantics
* ( asm - generic / barrier . h ensures sane smp_ * mb if not defined here , i . e .
* UP : barrier ( ) , SMP : smp_ * mb = = * mb )
* - DSYNC provides DMB + completion_of_cache_bpu_maintenance_ops hence not needed
* in the general case . Plus it only provides full barrier .
*/
# define mb() asm volatile("dmb 3\n" : : : "memory")
# define rmb() asm volatile("dmb 1\n" : : : "memory")
# define wmb() asm volatile("dmb 2\n" : : : "memory")
# else
/*
* ARCompact based cores ( ARC700 ) only have SYNC instruction which is super
* heavy weight as it flushes the pipeline as well .
* There are no real SMP implementations of such cores .
*/
# define mb() asm volatile("sync\n" : : : "memory")
# endif
# ifdef CONFIG_ISA_ARCV2
# define __iormb() rmb()
# define __iowmb() wmb()
# else
# define __iormb() do { } while (0)
# define __iowmb() do { } while (0)
# endif
/*
* Given a physical address and a length , return a virtual address
* that can be used to access the memory range with the caching
@ -72,18 +112,6 @@ static inline u32 __raw_readl(const volatile void __iomem *addr)
return w ;
}
# define readb __raw_readb
static inline u16 readw ( const volatile void __iomem * addr )
{
return __le16_to_cpu ( __raw_readw ( addr ) ) ;
}
static inline u32 readl ( const volatile void __iomem * addr )
{
return __le32_to_cpu ( __raw_readl ( addr ) ) ;
}
static inline void __raw_writeb ( u8 b , volatile void __iomem * addr )
{
__asm__ __volatile__ ( " stb%U1 %0, %1 \n "
@ -108,10 +136,6 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr)
: " memory " ) ;
}
# define writeb __raw_writeb
# define writew(b, addr) __raw_writew(__cpu_to_le16(b), addr)
# define writel(b, addr) __raw_writel(__cpu_to_le32(b), addr)
static inline int __raw_readsb ( unsigned int addr , void * data , int bytelen )
{
__asm__ __volatile__ ( " 1:ld.di r8, [r0] \n "
@ -184,6 +208,45 @@ static inline int __raw_writesl(unsigned int addr, void *data, int longlen)
return longlen ;
}
/*
* 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 barrier ordering themselves
*
* Also these are defined to perform little endian accesses .
* To provide the typical device register semantics of fixed endian ,
* swap the byte order for Big Endian
*
* http : //lkml.kernel.org/r/201603100845.30602.arnd@arndb.de
*/
# define readb_relaxed(c) __raw_readb(c)
# define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
__raw_readw ( c ) ) ; __r ; } )
# define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
__raw_readl ( c ) ) ; __r ; } )
# define writeb_relaxed(v,c) __raw_writeb(v,c)
# define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c)
# define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c)
# define out_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v), a)
# define in_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a))