arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / powerpc / include / asm / cmpxchg.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_POWERPC_CMPXCHG_H_
3 #define _ASM_POWERPC_CMPXCHG_H_
4
5 #ifdef __KERNEL__
6 #include <linux/compiler.h>
7 #include <asm/synch.h>
8 #include <linux/bug.h>
9
10 #ifdef __BIG_ENDIAN
11 #define BITOFF_CAL(size, off)   ((sizeof(u32) - size - off) * BITS_PER_BYTE)
12 #else
13 #define BITOFF_CAL(size, off)   (off * BITS_PER_BYTE)
14 #endif
15
16 #define XCHG_GEN(type, sfx, cl)                         \
17 static inline u32 __xchg_##type##sfx(volatile void *p, u32 val) \
18 {                                                               \
19         unsigned int prev, prev_mask, tmp, bitoff, off;         \
20                                                                 \
21         off = (unsigned long)p % sizeof(u32);                   \
22         bitoff = BITOFF_CAL(sizeof(type), off);                 \
23         p -= off;                                               \
24         val <<= bitoff;                                         \
25         prev_mask = (u32)(type)-1 << bitoff;                    \
26                                                                 \
27         __asm__ __volatile__(                                   \
28 "1:     lwarx   %0,0,%3\n"                                      \
29 "       andc    %1,%0,%5\n"                                     \
30 "       or      %1,%1,%4\n"                                     \
31 "       stwcx.  %1,0,%3\n"                                      \
32 "       bne-    1b\n"                                           \
33         : "=&r" (prev), "=&r" (tmp), "+m" (*(u32*)p)            \
34         : "r" (p), "r" (val), "r" (prev_mask)                   \
35         : "cc", cl);                                            \
36                                                                 \
37         return prev >> bitoff;                                  \
38 }
39
40 #define CMPXCHG_GEN(type, sfx, br, br2, cl)                     \
41 static inline                                                   \
42 u32 __cmpxchg_##type##sfx(volatile void *p, u32 old, u32 new)   \
43 {                                                               \
44         unsigned int prev, prev_mask, tmp, bitoff, off;         \
45                                                                 \
46         off = (unsigned long)p % sizeof(u32);                   \
47         bitoff = BITOFF_CAL(sizeof(type), off);                 \
48         p -= off;                                               \
49         old <<= bitoff;                                         \
50         new <<= bitoff;                                         \
51         prev_mask = (u32)(type)-1 << bitoff;                    \
52                                                                 \
53         __asm__ __volatile__(                                   \
54         br                                                      \
55 "1:     lwarx   %0,0,%3\n"                                      \
56 "       and     %1,%0,%6\n"                                     \
57 "       cmpw    0,%1,%4\n"                                      \
58 "       bne-    2f\n"                                           \
59 "       andc    %1,%0,%6\n"                                     \
60 "       or      %1,%1,%5\n"                                     \
61 "       stwcx.  %1,0,%3\n"                                      \
62 "       bne-    1b\n"                                           \
63         br2                                                     \
64         "\n"                                                    \
65 "2:"                                                            \
66         : "=&r" (prev), "=&r" (tmp), "+m" (*(u32*)p)            \
67         : "r" (p), "r" (old), "r" (new), "r" (prev_mask)        \
68         : "cc", cl);                                            \
69                                                                 \
70         return prev >> bitoff;                                  \
71 }
72
73 /*
74  * Atomic exchange
75  *
76  * Changes the memory location '*p' to be val and returns
77  * the previous value stored there.
78  */
79
80 #ifndef CONFIG_PPC_HAS_LBARX_LHARX
81 XCHG_GEN(u8, _local, "memory");
82 XCHG_GEN(u8, _relaxed, "cc");
83 XCHG_GEN(u16, _local, "memory");
84 XCHG_GEN(u16, _relaxed, "cc");
85 #else
86 static __always_inline unsigned long
87 __xchg_u8_local(volatile void *p, unsigned long val)
88 {
89         unsigned long prev;
90
91         __asm__ __volatile__(
92 "1:     lbarx   %0,0,%2         # __xchg_u8_local\n"
93 "       stbcx.  %3,0,%2 \n"
94 "       bne-    1b"
95         : "=&r" (prev), "+m" (*(volatile unsigned char *)p)
96         : "r" (p), "r" (val)
97         : "cc", "memory");
98
99         return prev;
100 }
101
102 static __always_inline unsigned long
103 __xchg_u8_relaxed(u8 *p, unsigned long val)
104 {
105         unsigned long prev;
106
107         __asm__ __volatile__(
108 "1:     lbarx   %0,0,%2         # __xchg_u8_relaxed\n"
109 "       stbcx.  %3,0,%2\n"
110 "       bne-    1b"
111         : "=&r" (prev), "+m" (*p)
112         : "r" (p), "r" (val)
113         : "cc");
114
115         return prev;
116 }
117
118 static __always_inline unsigned long
119 __xchg_u16_local(volatile void *p, unsigned long val)
120 {
121         unsigned long prev;
122
123         __asm__ __volatile__(
124 "1:     lharx   %0,0,%2         # __xchg_u16_local\n"
125 "       sthcx.  %3,0,%2\n"
126 "       bne-    1b"
127         : "=&r" (prev), "+m" (*(volatile unsigned short *)p)
128         : "r" (p), "r" (val)
129         : "cc", "memory");
130
131         return prev;
132 }
133
134 static __always_inline unsigned long
135 __xchg_u16_relaxed(u16 *p, unsigned long val)
136 {
137         unsigned long prev;
138
139         __asm__ __volatile__(
140 "1:     lharx   %0,0,%2         # __xchg_u16_relaxed\n"
141 "       sthcx.  %3,0,%2\n"
142 "       bne-    1b"
143         : "=&r" (prev), "+m" (*p)
144         : "r" (p), "r" (val)
145         : "cc");
146
147         return prev;
148 }
149 #endif
150
151 static __always_inline unsigned long
152 __xchg_u32_local(volatile void *p, unsigned long val)
153 {
154         unsigned long prev;
155
156         __asm__ __volatile__(
157 "1:     lwarx   %0,0,%2 \n"
158 "       stwcx.  %3,0,%2 \n\
159         bne-    1b"
160         : "=&r" (prev), "+m" (*(volatile unsigned int *)p)
161         : "r" (p), "r" (val)
162         : "cc", "memory");
163
164         return prev;
165 }
166
167 static __always_inline unsigned long
168 __xchg_u32_relaxed(u32 *p, unsigned long val)
169 {
170         unsigned long prev;
171
172         __asm__ __volatile__(
173 "1:     lwarx   %0,0,%2\n"
174 "       stwcx.  %3,0,%2\n"
175 "       bne-    1b"
176         : "=&r" (prev), "+m" (*p)
177         : "r" (p), "r" (val)
178         : "cc");
179
180         return prev;
181 }
182
183 #ifdef CONFIG_PPC64
184 static __always_inline unsigned long
185 __xchg_u64_local(volatile void *p, unsigned long val)
186 {
187         unsigned long prev;
188
189         __asm__ __volatile__(
190 "1:     ldarx   %0,0,%2 \n"
191 "       stdcx.  %3,0,%2 \n\
192         bne-    1b"
193         : "=&r" (prev), "+m" (*(volatile unsigned long *)p)
194         : "r" (p), "r" (val)
195         : "cc", "memory");
196
197         return prev;
198 }
199
200 static __always_inline unsigned long
201 __xchg_u64_relaxed(u64 *p, unsigned long val)
202 {
203         unsigned long prev;
204
205         __asm__ __volatile__(
206 "1:     ldarx   %0,0,%2\n"
207 "       stdcx.  %3,0,%2\n"
208 "       bne-    1b"
209         : "=&r" (prev), "+m" (*p)
210         : "r" (p), "r" (val)
211         : "cc");
212
213         return prev;
214 }
215 #endif
216
217 static __always_inline unsigned long
218 __xchg_local(void *ptr, unsigned long x, unsigned int size)
219 {
220         switch (size) {
221         case 1:
222                 return __xchg_u8_local(ptr, x);
223         case 2:
224                 return __xchg_u16_local(ptr, x);
225         case 4:
226                 return __xchg_u32_local(ptr, x);
227 #ifdef CONFIG_PPC64
228         case 8:
229                 return __xchg_u64_local(ptr, x);
230 #endif
231         }
232         BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local");
233         return x;
234 }
235
236 static __always_inline unsigned long
237 __xchg_relaxed(void *ptr, unsigned long x, unsigned int size)
238 {
239         switch (size) {
240         case 1:
241                 return __xchg_u8_relaxed(ptr, x);
242         case 2:
243                 return __xchg_u16_relaxed(ptr, x);
244         case 4:
245                 return __xchg_u32_relaxed(ptr, x);
246 #ifdef CONFIG_PPC64
247         case 8:
248                 return __xchg_u64_relaxed(ptr, x);
249 #endif
250         }
251         BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_relaxed");
252         return x;
253 }
254 #define arch_xchg_local(ptr,x)                                               \
255   ({                                                                         \
256      __typeof__(*(ptr)) _x_ = (x);                                           \
257      (__typeof__(*(ptr))) __xchg_local((ptr),                                \
258                 (unsigned long)_x_, sizeof(*(ptr)));                         \
259   })
260
261 #define arch_xchg_relaxed(ptr, x)                                       \
262 ({                                                                      \
263         __typeof__(*(ptr)) _x_ = (x);                                   \
264         (__typeof__(*(ptr))) __xchg_relaxed((ptr),                      \
265                         (unsigned long)_x_, sizeof(*(ptr)));            \
266 })
267
268 /*
269  * Compare and exchange - if *p == old, set it to new,
270  * and return the old value of *p.
271  */
272 #ifndef CONFIG_PPC_HAS_LBARX_LHARX
273 CMPXCHG_GEN(u8, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
274 CMPXCHG_GEN(u8, _local, , , "memory");
275 CMPXCHG_GEN(u8, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
276 CMPXCHG_GEN(u8, _relaxed, , , "cc");
277 CMPXCHG_GEN(u16, , PPC_ATOMIC_ENTRY_BARRIER, PPC_ATOMIC_EXIT_BARRIER, "memory");
278 CMPXCHG_GEN(u16, _local, , , "memory");
279 CMPXCHG_GEN(u16, _acquire, , PPC_ACQUIRE_BARRIER, "memory");
280 CMPXCHG_GEN(u16, _relaxed, , , "cc");
281 #else
282 static __always_inline unsigned long
283 __cmpxchg_u8(volatile unsigned char *p, unsigned long old, unsigned long new)
284 {
285         unsigned int prev;
286
287         __asm__ __volatile__ (
288         PPC_ATOMIC_ENTRY_BARRIER
289 "1:     lbarx   %0,0,%2         # __cmpxchg_u8\n"
290 "       cmpw    0,%0,%3\n"
291 "       bne-    2f\n"
292 "       stbcx.  %4,0,%2\n"
293 "       bne-    1b"
294         PPC_ATOMIC_EXIT_BARRIER
295         "\n\
296 2:"
297         : "=&r" (prev), "+m" (*p)
298         : "r" (p), "r" (old), "r" (new)
299         : "cc", "memory");
300
301         return prev;
302 }
303
304 static __always_inline unsigned long
305 __cmpxchg_u8_local(volatile unsigned char *p, unsigned long old,
306                         unsigned long new)
307 {
308         unsigned int prev;
309
310         __asm__ __volatile__ (
311 "1:     lbarx   %0,0,%2         # __cmpxchg_u8_local\n"
312 "       cmpw    0,%0,%3\n"
313 "       bne-    2f\n"
314 "       stbcx.  %4,0,%2\n"
315 "       bne-    1b\n"
316 "2:"
317         : "=&r" (prev), "+m" (*p)
318         : "r" (p), "r" (old), "r" (new)
319         : "cc", "memory");
320
321         return prev;
322 }
323
324 static __always_inline unsigned long
325 __cmpxchg_u8_relaxed(u8 *p, unsigned long old, unsigned long new)
326 {
327         unsigned long prev;
328
329         __asm__ __volatile__ (
330 "1:     lbarx   %0,0,%2         # __cmpxchg_u8_relaxed\n"
331 "       cmpw    0,%0,%3\n"
332 "       bne-    2f\n"
333 "       stbcx.  %4,0,%2\n"
334 "       bne-    1b\n"
335 "2:"
336         : "=&r" (prev), "+m" (*p)
337         : "r" (p), "r" (old), "r" (new)
338         : "cc");
339
340         return prev;
341 }
342
343 static __always_inline unsigned long
344 __cmpxchg_u8_acquire(u8 *p, unsigned long old, unsigned long new)
345 {
346         unsigned long prev;
347
348         __asm__ __volatile__ (
349 "1:     lbarx   %0,0,%2         # __cmpxchg_u8_acquire\n"
350 "       cmpw    0,%0,%3\n"
351 "       bne-    2f\n"
352 "       stbcx.  %4,0,%2\n"
353 "       bne-    1b\n"
354         PPC_ACQUIRE_BARRIER
355 "2:"
356         : "=&r" (prev), "+m" (*p)
357         : "r" (p), "r" (old), "r" (new)
358         : "cc", "memory");
359
360         return prev;
361 }
362
363 static __always_inline unsigned long
364 __cmpxchg_u16(volatile unsigned short *p, unsigned long old, unsigned long new)
365 {
366         unsigned int prev;
367
368         __asm__ __volatile__ (
369         PPC_ATOMIC_ENTRY_BARRIER
370 "1:     lharx   %0,0,%2         # __cmpxchg_u16\n"
371 "       cmpw    0,%0,%3\n"
372 "       bne-    2f\n"
373 "       sthcx.  %4,0,%2\n"
374 "       bne-    1b\n"
375         PPC_ATOMIC_EXIT_BARRIER
376 "2:"
377         : "=&r" (prev), "+m" (*p)
378         : "r" (p), "r" (old), "r" (new)
379         : "cc", "memory");
380
381         return prev;
382 }
383
384 static __always_inline unsigned long
385 __cmpxchg_u16_local(volatile unsigned short *p, unsigned long old,
386                         unsigned long new)
387 {
388         unsigned int prev;
389
390         __asm__ __volatile__ (
391 "1:     lharx   %0,0,%2         # __cmpxchg_u16_local\n"
392 "       cmpw    0,%0,%3\n"
393 "       bne-    2f\n"
394 "       sthcx.  %4,0,%2\n"
395 "       bne-    1b"
396 "2:"
397         : "=&r" (prev), "+m" (*p)
398         : "r" (p), "r" (old), "r" (new)
399         : "cc", "memory");
400
401         return prev;
402 }
403
404 static __always_inline unsigned long
405 __cmpxchg_u16_relaxed(u16 *p, unsigned long old, unsigned long new)
406 {
407         unsigned long prev;
408
409         __asm__ __volatile__ (
410 "1:     lharx   %0,0,%2         # __cmpxchg_u16_relaxed\n"
411 "       cmpw    0,%0,%3\n"
412 "       bne-    2f\n"
413 "       sthcx.  %4,0,%2\n"
414 "       bne-    1b\n"
415 "2:"
416         : "=&r" (prev), "+m" (*p)
417         : "r" (p), "r" (old), "r" (new)
418         : "cc");
419
420         return prev;
421 }
422
423 static __always_inline unsigned long
424 __cmpxchg_u16_acquire(u16 *p, unsigned long old, unsigned long new)
425 {
426         unsigned long prev;
427
428         __asm__ __volatile__ (
429 "1:     lharx   %0,0,%2         # __cmpxchg_u16_acquire\n"
430 "       cmpw    0,%0,%3\n"
431 "       bne-    2f\n"
432 "       sthcx.  %4,0,%2\n"
433 "       bne-    1b\n"
434         PPC_ACQUIRE_BARRIER
435 "2:"
436         : "=&r" (prev), "+m" (*p)
437         : "r" (p), "r" (old), "r" (new)
438         : "cc", "memory");
439
440         return prev;
441 }
442 #endif
443
444 static __always_inline unsigned long
445 __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
446 {
447         unsigned int prev;
448
449         __asm__ __volatile__ (
450         PPC_ATOMIC_ENTRY_BARRIER
451 "1:     lwarx   %0,0,%2         # __cmpxchg_u32\n\
452         cmpw    0,%0,%3\n\
453         bne-    2f\n"
454 "       stwcx.  %4,0,%2\n\
455         bne-    1b"
456         PPC_ATOMIC_EXIT_BARRIER
457         "\n\
458 2:"
459         : "=&r" (prev), "+m" (*p)
460         : "r" (p), "r" (old), "r" (new)
461         : "cc", "memory");
462
463         return prev;
464 }
465
466 static __always_inline unsigned long
467 __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old,
468                         unsigned long new)
469 {
470         unsigned int prev;
471
472         __asm__ __volatile__ (
473 "1:     lwarx   %0,0,%2         # __cmpxchg_u32\n\
474         cmpw    0,%0,%3\n\
475         bne-    2f\n"
476 "       stwcx.  %4,0,%2\n\
477         bne-    1b"
478         "\n\
479 2:"
480         : "=&r" (prev), "+m" (*p)
481         : "r" (p), "r" (old), "r" (new)
482         : "cc", "memory");
483
484         return prev;
485 }
486
487 static __always_inline unsigned long
488 __cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new)
489 {
490         unsigned long prev;
491
492         __asm__ __volatile__ (
493 "1:     lwarx   %0,0,%2         # __cmpxchg_u32_relaxed\n"
494 "       cmpw    0,%0,%3\n"
495 "       bne-    2f\n"
496 "       stwcx.  %4,0,%2\n"
497 "       bne-    1b\n"
498 "2:"
499         : "=&r" (prev), "+m" (*p)
500         : "r" (p), "r" (old), "r" (new)
501         : "cc");
502
503         return prev;
504 }
505
506 /*
507  * cmpxchg family don't have order guarantee if cmp part fails, therefore we
508  * can avoid superfluous barriers if we use assembly code to implement
509  * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for
510  * cmpxchg_release() because that will result in putting a barrier in the
511  * middle of a ll/sc loop, which is probably a bad idea. For example, this
512  * might cause the conditional store more likely to fail.
513  */
514 static __always_inline unsigned long
515 __cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new)
516 {
517         unsigned long prev;
518
519         __asm__ __volatile__ (
520 "1:     lwarx   %0,0,%2         # __cmpxchg_u32_acquire\n"
521 "       cmpw    0,%0,%3\n"
522 "       bne-    2f\n"
523 "       stwcx.  %4,0,%2\n"
524 "       bne-    1b\n"
525         PPC_ACQUIRE_BARRIER
526         "\n"
527 "2:"
528         : "=&r" (prev), "+m" (*p)
529         : "r" (p), "r" (old), "r" (new)
530         : "cc", "memory");
531
532         return prev;
533 }
534
535 #ifdef CONFIG_PPC64
536 static __always_inline unsigned long
537 __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
538 {
539         unsigned long prev;
540
541         __asm__ __volatile__ (
542         PPC_ATOMIC_ENTRY_BARRIER
543 "1:     ldarx   %0,0,%2         # __cmpxchg_u64\n\
544         cmpd    0,%0,%3\n\
545         bne-    2f\n\
546         stdcx.  %4,0,%2\n\
547         bne-    1b"
548         PPC_ATOMIC_EXIT_BARRIER
549         "\n\
550 2:"
551         : "=&r" (prev), "+m" (*p)
552         : "r" (p), "r" (old), "r" (new)
553         : "cc", "memory");
554
555         return prev;
556 }
557
558 static __always_inline unsigned long
559 __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old,
560                         unsigned long new)
561 {
562         unsigned long prev;
563
564         __asm__ __volatile__ (
565 "1:     ldarx   %0,0,%2         # __cmpxchg_u64\n\
566         cmpd    0,%0,%3\n\
567         bne-    2f\n\
568         stdcx.  %4,0,%2\n\
569         bne-    1b"
570         "\n\
571 2:"
572         : "=&r" (prev), "+m" (*p)
573         : "r" (p), "r" (old), "r" (new)
574         : "cc", "memory");
575
576         return prev;
577 }
578
579 static __always_inline unsigned long
580 __cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new)
581 {
582         unsigned long prev;
583
584         __asm__ __volatile__ (
585 "1:     ldarx   %0,0,%2         # __cmpxchg_u64_relaxed\n"
586 "       cmpd    0,%0,%3\n"
587 "       bne-    2f\n"
588 "       stdcx.  %4,0,%2\n"
589 "       bne-    1b\n"
590 "2:"
591         : "=&r" (prev), "+m" (*p)
592         : "r" (p), "r" (old), "r" (new)
593         : "cc");
594
595         return prev;
596 }
597
598 static __always_inline unsigned long
599 __cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new)
600 {
601         unsigned long prev;
602
603         __asm__ __volatile__ (
604 "1:     ldarx   %0,0,%2         # __cmpxchg_u64_acquire\n"
605 "       cmpd    0,%0,%3\n"
606 "       bne-    2f\n"
607 "       stdcx.  %4,0,%2\n"
608 "       bne-    1b\n"
609         PPC_ACQUIRE_BARRIER
610         "\n"
611 "2:"
612         : "=&r" (prev), "+m" (*p)
613         : "r" (p), "r" (old), "r" (new)
614         : "cc", "memory");
615
616         return prev;
617 }
618 #endif
619
620 static __always_inline unsigned long
621 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
622           unsigned int size)
623 {
624         switch (size) {
625         case 1:
626                 return __cmpxchg_u8(ptr, old, new);
627         case 2:
628                 return __cmpxchg_u16(ptr, old, new);
629         case 4:
630                 return __cmpxchg_u32(ptr, old, new);
631 #ifdef CONFIG_PPC64
632         case 8:
633                 return __cmpxchg_u64(ptr, old, new);
634 #endif
635         }
636         BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg");
637         return old;
638 }
639
640 static __always_inline unsigned long
641 __cmpxchg_local(void *ptr, unsigned long old, unsigned long new,
642           unsigned int size)
643 {
644         switch (size) {
645         case 1:
646                 return __cmpxchg_u8_local(ptr, old, new);
647         case 2:
648                 return __cmpxchg_u16_local(ptr, old, new);
649         case 4:
650                 return __cmpxchg_u32_local(ptr, old, new);
651 #ifdef CONFIG_PPC64
652         case 8:
653                 return __cmpxchg_u64_local(ptr, old, new);
654 #endif
655         }
656         BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_local");
657         return old;
658 }
659
660 static __always_inline unsigned long
661 __cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new,
662                   unsigned int size)
663 {
664         switch (size) {
665         case 1:
666                 return __cmpxchg_u8_relaxed(ptr, old, new);
667         case 2:
668                 return __cmpxchg_u16_relaxed(ptr, old, new);
669         case 4:
670                 return __cmpxchg_u32_relaxed(ptr, old, new);
671 #ifdef CONFIG_PPC64
672         case 8:
673                 return __cmpxchg_u64_relaxed(ptr, old, new);
674 #endif
675         }
676         BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_relaxed");
677         return old;
678 }
679
680 static __always_inline unsigned long
681 __cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new,
682                   unsigned int size)
683 {
684         switch (size) {
685         case 1:
686                 return __cmpxchg_u8_acquire(ptr, old, new);
687         case 2:
688                 return __cmpxchg_u16_acquire(ptr, old, new);
689         case 4:
690                 return __cmpxchg_u32_acquire(ptr, old, new);
691 #ifdef CONFIG_PPC64
692         case 8:
693                 return __cmpxchg_u64_acquire(ptr, old, new);
694 #endif
695         }
696         BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire");
697         return old;
698 }
699 #define arch_cmpxchg(ptr, o, n)                                          \
700   ({                                                                     \
701      __typeof__(*(ptr)) _o_ = (o);                                       \
702      __typeof__(*(ptr)) _n_ = (n);                                       \
703      (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,           \
704                                     (unsigned long)_n_, sizeof(*(ptr))); \
705   })
706
707
708 #define arch_cmpxchg_local(ptr, o, n)                                    \
709   ({                                                                     \
710      __typeof__(*(ptr)) _o_ = (o);                                       \
711      __typeof__(*(ptr)) _n_ = (n);                                       \
712      (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,     \
713                                     (unsigned long)_n_, sizeof(*(ptr))); \
714   })
715
716 #define arch_cmpxchg_relaxed(ptr, o, n)                                 \
717 ({                                                                      \
718         __typeof__(*(ptr)) _o_ = (o);                                   \
719         __typeof__(*(ptr)) _n_ = (n);                                   \
720         (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr),                   \
721                         (unsigned long)_o_, (unsigned long)_n_,         \
722                         sizeof(*(ptr)));                                \
723 })
724
725 #define arch_cmpxchg_acquire(ptr, o, n)                                 \
726 ({                                                                      \
727         __typeof__(*(ptr)) _o_ = (o);                                   \
728         __typeof__(*(ptr)) _n_ = (n);                                   \
729         (__typeof__(*(ptr))) __cmpxchg_acquire((ptr),                   \
730                         (unsigned long)_o_, (unsigned long)_n_,         \
731                         sizeof(*(ptr)));                                \
732 })
733 #ifdef CONFIG_PPC64
734 #define arch_cmpxchg64(ptr, o, n)                                       \
735   ({                                                                    \
736         BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
737         arch_cmpxchg((ptr), (o), (n));                                  \
738   })
739 #define arch_cmpxchg64_local(ptr, o, n)                                 \
740   ({                                                                    \
741         BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
742         arch_cmpxchg_local((ptr), (o), (n));                            \
743   })
744 #define arch_cmpxchg64_relaxed(ptr, o, n)                               \
745 ({                                                                      \
746         BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
747         arch_cmpxchg_relaxed((ptr), (o), (n));                          \
748 })
749 #define arch_cmpxchg64_acquire(ptr, o, n)                               \
750 ({                                                                      \
751         BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
752         arch_cmpxchg_acquire((ptr), (o), (n));                          \
753 })
754 #else
755 #include <asm-generic/cmpxchg-local.h>
756 #define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
757 #endif
758
759 #endif /* __KERNEL__ */
760 #endif /* _ASM_POWERPC_CMPXCHG_H_ */