GNU Linux-libre 4.9-gnu1
[releases.git] / arch / microblaze / include / asm / cmpxchg.h
1 #ifndef _ASM_MICROBLAZE_CMPXCHG_H
2 #define _ASM_MICROBLAZE_CMPXCHG_H
3
4 #include <linux/irqflags.h>
5
6 void __bad_xchg(volatile void *ptr, int size);
7
8 static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
9                                                                 int size)
10 {
11         unsigned long ret;
12         unsigned long flags;
13
14         switch (size) {
15         case 1:
16                 local_irq_save(flags);
17                 ret = *(volatile unsigned char *)ptr;
18                 *(volatile unsigned char *)ptr = x;
19                 local_irq_restore(flags);
20                 break;
21
22         case 4:
23                 local_irq_save(flags);
24                 ret = *(volatile unsigned long *)ptr;
25                 *(volatile unsigned long *)ptr = x;
26                 local_irq_restore(flags);
27                 break;
28         default:
29                 __bad_xchg(ptr, size), ret = 0;
30                 break;
31         }
32
33         return ret;
34 }
35
36 #define xchg(ptr, x) \
37         ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
38
39 #include <asm-generic/cmpxchg.h>
40 #include <asm-generic/cmpxchg-local.h>
41
42 #endif /* _ASM_MICROBLAZE_CMPXCHG_H */