1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_BARRIER_H
3 #define __ASM_BARRIER_H
4 
5 #include <asm/alternative.h>
6 
7 #ifndef __ASSEMBLY__
8 
9 /* The synchronize caches instruction executes as a nop on systems in
10    which all memory references are performed in order. */
11 #define synchronize_caches() asm volatile("sync" \
12 	ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \
13 	: : : "memory")
14 
15 #if defined(CONFIG_SMP)
16 #define mb()		do { synchronize_caches(); } while (0)
17 #define rmb()		mb()
18 #define wmb()		mb()
19 #define dma_rmb()	mb()
20 #define dma_wmb()	mb()
21 #else
22 #define mb()		barrier()
23 #define rmb()		barrier()
24 #define wmb()		barrier()
25 #define dma_rmb()	barrier()
26 #define dma_wmb()	barrier()
27 #endif
28 
29 #define __smp_mb()	mb()
30 #define __smp_rmb()	mb()
31 #define __smp_wmb()	mb()
32 
33 #define __smp_store_release(p, v)					\
34 do {									\
35 	typeof(p) __p = (p);						\
36         union { typeof(*p) __val; char __c[1]; } __u =			\
37                 { .__val = (__force typeof(*p)) (v) };			\
38 	compiletime_assert_atomic_type(*p);				\
39 	switch (sizeof(*p)) {						\
40 	case 1:								\
41 		asm volatile("stb,ma %0,0(%1)"				\
42 				: : "r"(*(__u8 *)__u.__c), "r"(__p)	\
43 				: "memory");				\
44 		break;							\
45 	case 2:								\
46 		asm volatile("sth,ma %0,0(%1)"				\
47 				: : "r"(*(__u16 *)__u.__c), "r"(__p)	\
48 				: "memory");				\
49 		break;							\
50 	case 4:								\
51 		asm volatile("stw,ma %0,0(%1)"				\
52 				: : "r"(*(__u32 *)__u.__c), "r"(__p)	\
53 				: "memory");				\
54 		break;							\
55 	case 8:								\
56 		if (IS_ENABLED(CONFIG_64BIT))				\
57 			asm volatile("std,ma %0,0(%1)"			\
58 				: : "r"(*(__u64 *)__u.__c), "r"(__p)	\
59 				: "memory");				\
60 		break;							\
61 	}								\
62 } while (0)
63 
64 #define __smp_load_acquire(p)						\
65 ({									\
66 	union { typeof(*p) __val; char __c[1]; } __u;			\
67 	typeof(p) __p = (p);						\
68 	compiletime_assert_atomic_type(*p);				\
69 	switch (sizeof(*p)) {						\
70 	case 1:								\
71 		asm volatile("ldb,ma 0(%1),%0"				\
72 				: "=r"(*(__u8 *)__u.__c) : "r"(__p)	\
73 				: "memory");				\
74 		break;							\
75 	case 2:								\
76 		asm volatile("ldh,ma 0(%1),%0"				\
77 				: "=r"(*(__u16 *)__u.__c) : "r"(__p)	\
78 				: "memory");				\
79 		break;							\
80 	case 4:								\
81 		asm volatile("ldw,ma 0(%1),%0"				\
82 				: "=r"(*(__u32 *)__u.__c) : "r"(__p)	\
83 				: "memory");				\
84 		break;							\
85 	case 8:								\
86 		if (IS_ENABLED(CONFIG_64BIT))				\
87 			asm volatile("ldd,ma 0(%1),%0"			\
88 				: "=r"(*(__u64 *)__u.__c) : "r"(__p)	\
89 				: "memory");				\
90 		break;							\
91 	}								\
92 	__u.__val;							\
93 })
94 #include <asm-generic/barrier.h>
95 
96 #endif /* !__ASSEMBLY__ */
97 #endif /* __ASM_BARRIER_H */
98