arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / openrisc / include / asm / atomic.h
1 /*
2  * Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
3  *
4  * This file is licensed under the terms of the GNU General Public License
5  * version 2.  This program is licensed "as is" without any warranty of any
6  * kind, whether express or implied.
7  */
8
9 #ifndef __ASM_OPENRISC_ATOMIC_H
10 #define __ASM_OPENRISC_ATOMIC_H
11
12 #include <linux/types.h>
13
14 /* Atomically perform op with v->counter and i */
15 #define ATOMIC_OP(op)                                                   \
16 static inline void arch_atomic_##op(int i, atomic_t *v)                 \
17 {                                                                       \
18         int tmp;                                                        \
19                                                                         \
20         __asm__ __volatile__(                                           \
21                 "1:     l.lwa   %0,0(%1)        \n"                     \
22                 "       l." #op " %0,%0,%2      \n"                     \
23                 "       l.swa   0(%1),%0        \n"                     \
24                 "       l.bnf   1b              \n"                     \
25                 "        l.nop                  \n"                     \
26                 : "=&r"(tmp)                                            \
27                 : "r"(&v->counter), "r"(i)                              \
28                 : "cc", "memory");                                      \
29 }
30
31 /* Atomically perform op with v->counter and i, return the result */
32 #define ATOMIC_OP_RETURN(op)                                            \
33 static inline int arch_atomic_##op##_return(int i, atomic_t *v)         \
34 {                                                                       \
35         int tmp;                                                        \
36                                                                         \
37         __asm__ __volatile__(                                           \
38                 "1:     l.lwa   %0,0(%1)        \n"                     \
39                 "       l." #op " %0,%0,%2      \n"                     \
40                 "       l.swa   0(%1),%0        \n"                     \
41                 "       l.bnf   1b              \n"                     \
42                 "        l.nop                  \n"                     \
43                 : "=&r"(tmp)                                            \
44                 : "r"(&v->counter), "r"(i)                              \
45                 : "cc", "memory");                                      \
46                                                                         \
47         return tmp;                                                     \
48 }
49
50 /* Atomically perform op with v->counter and i, return orig v->counter */
51 #define ATOMIC_FETCH_OP(op)                                             \
52 static inline int arch_atomic_fetch_##op(int i, atomic_t *v)            \
53 {                                                                       \
54         int tmp, old;                                                   \
55                                                                         \
56         __asm__ __volatile__(                                           \
57                 "1:     l.lwa   %0,0(%2)        \n"                     \
58                 "       l." #op " %1,%0,%3      \n"                     \
59                 "       l.swa   0(%2),%1        \n"                     \
60                 "       l.bnf   1b              \n"                     \
61                 "        l.nop                  \n"                     \
62                 : "=&r"(old), "=&r"(tmp)                                \
63                 : "r"(&v->counter), "r"(i)                              \
64                 : "cc", "memory");                                      \
65                                                                         \
66         return old;                                                     \
67 }
68
69 ATOMIC_OP_RETURN(add)
70 ATOMIC_OP_RETURN(sub)
71
72 ATOMIC_FETCH_OP(add)
73 ATOMIC_FETCH_OP(sub)
74 ATOMIC_FETCH_OP(and)
75 ATOMIC_FETCH_OP(or)
76 ATOMIC_FETCH_OP(xor)
77
78 ATOMIC_OP(add)
79 ATOMIC_OP(sub)
80 ATOMIC_OP(and)
81 ATOMIC_OP(or)
82 ATOMIC_OP(xor)
83
84 #undef ATOMIC_FETCH_OP
85 #undef ATOMIC_OP_RETURN
86 #undef ATOMIC_OP
87
88 #define arch_atomic_add_return  arch_atomic_add_return
89 #define arch_atomic_sub_return  arch_atomic_sub_return
90 #define arch_atomic_fetch_add   arch_atomic_fetch_add
91 #define arch_atomic_fetch_sub   arch_atomic_fetch_sub
92 #define arch_atomic_fetch_and   arch_atomic_fetch_and
93 #define arch_atomic_fetch_or    arch_atomic_fetch_or
94 #define arch_atomic_fetch_xor   arch_atomic_fetch_xor
95 #define arch_atomic_add         arch_atomic_add
96 #define arch_atomic_sub         arch_atomic_sub
97 #define arch_atomic_and         arch_atomic_and
98 #define arch_atomic_or          arch_atomic_or
99 #define arch_atomic_xor         arch_atomic_xor
100
101 /*
102  * Atomically add a to v->counter as long as v is not already u.
103  * Returns the original value at v->counter.
104  *
105  * This is often used through atomic_inc_not_zero()
106  */
107 static inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
108 {
109         int old, tmp;
110
111         __asm__ __volatile__(
112                 "1:     l.lwa %0, 0(%2)         \n"
113                 "       l.sfeq %0, %4           \n"
114                 "       l.bf 2f                 \n"
115                 "        l.add %1, %0, %3       \n"
116                 "       l.swa 0(%2), %1         \n"
117                 "       l.bnf 1b                \n"
118                 "        l.nop                  \n"
119                 "2:                             \n"
120                 : "=&r"(old), "=&r" (tmp)
121                 : "r"(&v->counter), "r"(a), "r"(u)
122                 : "cc", "memory");
123
124         return old;
125 }
126 #define arch_atomic_fetch_add_unless    arch_atomic_fetch_add_unless
127
128 #define arch_atomic_read(v)             READ_ONCE((v)->counter)
129 #define arch_atomic_set(v,i)            WRITE_ONCE((v)->counter, (i))
130
131 #include <asm/cmpxchg.h>
132
133 #endif /* __ASM_OPENRISC_ATOMIC_H */