2012-03-05 15:49:34 +04:00
/*
* Based on arch / arm / include / asm / barrier . h
*
* Copyright ( C ) 2012 ARM Ltd .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# ifndef __ASM_BARRIER_H
# define __ASM_BARRIER_H
# ifndef __ASSEMBLY__
2016-09-06 18:40:23 +03:00
# define __nops(n) ".rept " #n "\nnop\n.endr\n"
# define nops(n) asm volatile(__nops(n))
2012-03-05 15:49:34 +04:00
# define sev() asm volatile("sev" : : : "memory")
# define wfe() asm volatile("wfe" : : : "memory")
# define wfi() asm volatile("wfi" : : : "memory")
# define isb() asm volatile("isb" : : : "memory")
2014-05-02 19:24:11 +04:00
# define dmb(opt) asm volatile("dmb " #opt : : : "memory")
# define dsb(opt) asm volatile("dsb " #opt : : : "memory")
2012-03-05 15:49:34 +04:00
2014-05-02 19:24:10 +04:00
# define mb() dsb(sy)
2014-05-02 19:24:11 +04:00
# define rmb() dsb(ld)
# define wmb() dsb(st)
2012-03-05 15:49:34 +04:00
2014-12-12 02:02:06 +03:00
# define dma_rmb() dmb(oshld)
# define dma_wmb() dmb(oshst)
2015-12-27 16:04:42 +03:00
# define __smp_mb() dmb(ish)
# define __smp_rmb() dmb(ishld)
# define __smp_wmb() dmb(ishst)
2013-11-06 17:57:36 +04:00
2017-05-03 18:09:34 +03:00
# define __smp_store_release(p, v) \
2013-11-06 17:57:36 +04:00
do { \
2017-05-03 18:09:34 +03:00
union { typeof ( * p ) __val ; char __c [ 1 ] ; } __u = \
{ . __val = ( __force typeof ( * p ) ) ( v ) } ; \
2013-11-06 17:57:36 +04:00
compiletime_assert_atomic_type ( * p ) ; \
switch ( sizeof ( * p ) ) { \
2015-04-20 13:14:19 +03:00
case 1 : \
asm volatile ( " stlrb %w1, %0 " \
2017-05-03 18:09:34 +03:00
: " =Q " ( * p ) \
: " r " ( * ( __u8 * ) __u . __c ) \
: " memory " ) ; \
2015-04-20 13:14:19 +03:00
break ; \
case 2 : \
asm volatile ( " stlrh %w1, %0 " \
2017-05-03 18:09:34 +03:00
: " =Q " ( * p ) \
: " r " ( * ( __u16 * ) __u . __c ) \
: " memory " ) ; \
2015-04-20 13:14:19 +03:00
break ; \
2013-11-06 17:57:36 +04:00
case 4 : \
asm volatile ( " stlr %w1, %0 " \
2017-05-03 18:09:34 +03:00
: " =Q " ( * p ) \
: " r " ( * ( __u32 * ) __u . __c ) \
: " memory " ) ; \
2013-11-06 17:57:36 +04:00
break ; \
case 8 : \
asm volatile ( " stlr %1, %0 " \
2017-05-03 18:09:34 +03:00
: " =Q " ( * p ) \
: " r " ( * ( __u64 * ) __u . __c ) \
: " memory " ) ; \
2013-11-06 17:57:36 +04:00
break ; \
} \
} while ( 0 )
2015-12-27 16:04:42 +03:00
# define __smp_load_acquire(p) \
2013-11-06 17:57:36 +04:00
( { \
2015-11-18 13:13:08 +03:00
union { typeof ( * p ) __val ; char __c [ 1 ] ; } __u ; \
2013-11-06 17:57:36 +04:00
compiletime_assert_atomic_type ( * p ) ; \
switch ( sizeof ( * p ) ) { \
2015-04-20 13:14:19 +03:00
case 1 : \
asm volatile ( " ldarb %w0, %1 " \
2015-11-18 13:13:08 +03:00
: " =r " ( * ( __u8 * ) __u . __c ) \
: " Q " ( * p ) : " memory " ) ; \
2015-04-20 13:14:19 +03:00
break ; \
case 2 : \
asm volatile ( " ldarh %w0, %1 " \
2015-11-18 13:13:08 +03:00
: " =r " ( * ( __u16 * ) __u . __c ) \
: " Q " ( * p ) : " memory " ) ; \
2015-04-20 13:14:19 +03:00
break ; \
2013-11-06 17:57:36 +04:00
case 4 : \
asm volatile ( " ldar %w0, %1 " \
2015-11-18 13:13:08 +03:00
: " =r " ( * ( __u32 * ) __u . __c ) \
: " Q " ( * p ) : " memory " ) ; \
2013-11-06 17:57:36 +04:00
break ; \
case 8 : \
asm volatile ( " ldar %0, %1 " \
2015-11-18 13:13:08 +03:00
: " =r " ( * ( __u64 * ) __u . __c ) \
: " Q " ( * p ) : " memory " ) ; \
2013-11-06 17:57:36 +04:00
break ; \
} \
2015-11-18 13:13:08 +03:00
__u . __val ; \
2013-11-06 17:57:36 +04:00
} )
2016-06-27 20:43:54 +03:00
# define smp_cond_load_acquire(ptr, cond_expr) \
( { \
typeof ( ptr ) __PTR = ( ptr ) ; \
typeof ( * ptr ) VAL ; \
for ( ; ; ) { \
VAL = smp_load_acquire ( __PTR ) ; \
if ( cond_expr ) \
break ; \
__cmpwait_relaxed ( __PTR , VAL ) ; \
} \
VAL ; \
} )
2015-12-21 10:22:18 +03:00
# include <asm-generic/barrier.h>
2014-03-13 22:00:37 +04:00
2012-03-05 15:49:34 +04:00
# endif /* __ASSEMBLY__ */
# endif /* __ASM_BARRIER_H */