diff options
Diffstat (limited to 'arch/microblaze/include/asm/cmpxchg.h')
-rw-r--r-- | arch/microblaze/include/asm/cmpxchg.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/microblaze/include/asm/cmpxchg.h b/arch/microblaze/include/asm/cmpxchg.h new file mode 100644 index 000000000000..0094859abd9b --- /dev/null +++ b/arch/microblaze/include/asm/cmpxchg.h | |||
@@ -0,0 +1,40 @@ | |||
1 | #ifndef _ASM_MICROBLAZE_CMPXCHG_H | ||
2 | #define _ASM_MICROBLAZE_CMPXCHG_H | ||
3 | |||
4 | void __bad_xchg(volatile void *ptr, int size); | ||
5 | |||
6 | static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | ||
7 | int size) | ||
8 | { | ||
9 | unsigned long ret; | ||
10 | unsigned long flags; | ||
11 | |||
12 | switch (size) { | ||
13 | case 1: | ||
14 | local_irq_save(flags); | ||
15 | ret = *(volatile unsigned char *)ptr; | ||
16 | *(volatile unsigned char *)ptr = x; | ||
17 | local_irq_restore(flags); | ||
18 | break; | ||
19 | |||
20 | case 4: | ||
21 | local_irq_save(flags); | ||
22 | ret = *(volatile unsigned long *)ptr; | ||
23 | *(volatile unsigned long *)ptr = x; | ||
24 | local_irq_restore(flags); | ||
25 | break; | ||
26 | default: | ||
27 | __bad_xchg(ptr, size), ret = 0; | ||
28 | break; | ||
29 | } | ||
30 | |||
31 | return ret; | ||
32 | } | ||
33 | |||
34 | #define xchg(ptr, x) \ | ||
35 | ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) | ||
36 | |||
37 | #include <asm-generic/cmpxchg.h> | ||
38 | #include <asm-generic/cmpxchg-local.h> | ||
39 | |||
40 | #endif /* _ASM_MICROBLAZE_CMPXCHG_H */ | ||