]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/metag/include/asm/atomic_lnkget.h
arm: imx6: defconfig: update tx6 defconfigs
[karo-tx-linux.git] / arch / metag / include / asm / atomic_lnkget.h
1 #ifndef __ASM_METAG_ATOMIC_LNKGET_H
2 #define __ASM_METAG_ATOMIC_LNKGET_H
3
4 #define ATOMIC_INIT(i)  { (i) }
5
6 #define atomic_set(v, i)                ((v)->counter = (i))
7
8 #include <linux/compiler.h>
9
10 #include <asm/barrier.h>
11
12 /*
13  * None of these asm statements clobber memory as LNKSET writes around
14  * the cache so the memory it modifies cannot safely be read by any means
15  * other than these accessors.
16  */
17
18 static inline int atomic_read(const atomic_t *v)
19 {
20         int temp;
21
22         asm volatile (
23                 "LNKGETD %0, [%1]\n"
24                 : "=da" (temp)
25                 : "da" (&v->counter));
26
27         return temp;
28 }
29
30 static inline void atomic_add(int i, atomic_t *v)
31 {
32         int temp;
33
34         asm volatile (
35                 "1:     LNKGETD %0, [%1]\n"
36                 "       ADD     %0, %0, %2\n"
37                 "       LNKSETD [%1], %0\n"
38                 "       DEFR    %0, TXSTAT\n"
39                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
40                 "       CMPT    %0, #HI(0x02000000)\n"
41                 "       BNZ     1b\n"
42                 : "=&d" (temp)
43                 : "da" (&v->counter), "bd" (i)
44                 : "cc");
45 }
46
47 static inline void atomic_sub(int i, atomic_t *v)
48 {
49         int temp;
50
51         asm volatile (
52                 "1:     LNKGETD %0, [%1]\n"
53                 "       SUB     %0, %0, %2\n"
54                 "       LNKSETD [%1], %0\n"
55                 "       DEFR    %0, TXSTAT\n"
56                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
57                 "       CMPT    %0, #HI(0x02000000)\n"
58                 "       BNZ 1b\n"
59                 : "=&d" (temp)
60                 : "da" (&v->counter), "bd" (i)
61                 : "cc");
62 }
63
64 static inline int atomic_add_return(int i, atomic_t *v)
65 {
66         int result, temp;
67
68         smp_mb();
69
70         asm volatile (
71                 "1:     LNKGETD %1, [%2]\n"
72                 "       ADD     %1, %1, %3\n"
73                 "       LNKSETD [%2], %1\n"
74                 "       DEFR    %0, TXSTAT\n"
75                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
76                 "       CMPT    %0, #HI(0x02000000)\n"
77                 "       BNZ 1b\n"
78                 : "=&d" (temp), "=&da" (result)
79                 : "da" (&v->counter), "bd" (i)
80                 : "cc");
81
82         smp_mb();
83
84         return result;
85 }
86
87 static inline int atomic_sub_return(int i, atomic_t *v)
88 {
89         int result, temp;
90
91         smp_mb();
92
93         asm volatile (
94                 "1:     LNKGETD %1, [%2]\n"
95                 "       SUB     %1, %1, %3\n"
96                 "       LNKSETD [%2], %1\n"
97                 "       DEFR    %0, TXSTAT\n"
98                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
99                 "       CMPT    %0, #HI(0x02000000)\n"
100                 "       BNZ     1b\n"
101                 : "=&d" (temp), "=&da" (result)
102                 : "da" (&v->counter), "bd" (i)
103                 : "cc");
104
105         smp_mb();
106
107         return result;
108 }
109
110 static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
111 {
112         int temp;
113
114         asm volatile (
115                 "1:     LNKGETD %0, [%1]\n"
116                 "       AND     %0, %0, %2\n"
117                 "       LNKSETD [%1] %0\n"
118                 "       DEFR    %0, TXSTAT\n"
119                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
120                 "       CMPT    %0, #HI(0x02000000)\n"
121                 "       BNZ     1b\n"
122                 : "=&d" (temp)
123                 : "da" (&v->counter), "bd" (~mask)
124                 : "cc");
125 }
126
127 static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
128 {
129         int temp;
130
131         asm volatile (
132                 "1:     LNKGETD %0, [%1]\n"
133                 "       OR      %0, %0, %2\n"
134                 "       LNKSETD [%1], %0\n"
135                 "       DEFR    %0, TXSTAT\n"
136                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
137                 "       CMPT    %0, #HI(0x02000000)\n"
138                 "       BNZ     1b\n"
139                 : "=&d" (temp)
140                 : "da" (&v->counter), "bd" (mask)
141                 : "cc");
142 }
143
144 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
145 {
146         int result, temp;
147
148         smp_mb();
149
150         asm volatile (
151                 "1:     LNKGETD %1, [%2]\n"
152                 "       CMP     %1, %3\n"
153                 "       LNKSETDEQ [%2], %4\n"
154                 "       BNE     2f\n"
155                 "       DEFR    %0, TXSTAT\n"
156                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
157                 "       CMPT    %0, #HI(0x02000000)\n"
158                 "       BNZ     1b\n"
159                 "2:\n"
160                 : "=&d" (temp), "=&d" (result)
161                 : "da" (&v->counter), "bd" (old), "da" (new)
162                 : "cc");
163
164         smp_mb();
165
166         return result;
167 }
168
169 static inline int atomic_xchg(atomic_t *v, int new)
170 {
171         int temp, old;
172
173         asm volatile (
174                 "1:     LNKGETD %1, [%2]\n"
175                 "       LNKSETD [%2], %3\n"
176                 "       DEFR    %0, TXSTAT\n"
177                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
178                 "       CMPT    %0, #HI(0x02000000)\n"
179                 "       BNZ     1b\n"
180                 : "=&d" (temp), "=&d" (old)
181                 : "da" (&v->counter), "da" (new)
182                 : "cc");
183
184         return old;
185 }
186
187 static inline int __atomic_add_unless(atomic_t *v, int a, int u)
188 {
189         int result, temp;
190
191         smp_mb();
192
193         asm volatile (
194                 "1:     LNKGETD %1, [%2]\n"
195                 "       CMP     %1, %3\n"
196                 "       ADD     %0, %1, %4\n"
197                 "       LNKSETDNE [%2], %0\n"
198                 "       BEQ     2f\n"
199                 "       DEFR    %0, TXSTAT\n"
200                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
201                 "       CMPT    %0, #HI(0x02000000)\n"
202                 "       BNZ     1b\n"
203                 "2:\n"
204                 : "=&d" (temp), "=&d" (result)
205                 : "da" (&v->counter), "bd" (u), "bd" (a)
206                 : "cc");
207
208         smp_mb();
209
210         return result;
211 }
212
213 static inline int atomic_sub_if_positive(int i, atomic_t *v)
214 {
215         int result, temp;
216
217         asm volatile (
218                 "1:     LNKGETD %1, [%2]\n"
219                 "       SUBS    %1, %1, %3\n"
220                 "       LNKSETDGE [%2], %1\n"
221                 "       BLT     2f\n"
222                 "       DEFR    %0, TXSTAT\n"
223                 "       ANDT    %0, %0, #HI(0x3f000000)\n"
224                 "       CMPT    %0, #HI(0x02000000)\n"
225                 "       BNZ     1b\n"
226                 "2:\n"
227                 : "=&d" (temp), "=&da" (result)
228                 : "da" (&v->counter), "bd" (i)
229                 : "cc");
230
231         return result;
232 }
233
234 #endif /* __ASM_METAG_ATOMIC_LNKGET_H */