diff options
author | David Howells <dhowells@redhat.com> | 2012-03-12 19:36:56 -0400 |
---|---|---|
committer | Bob Liu <lliubbo@gmail.com> | 2012-03-20 23:00:08 -0400 |
commit | 3bed8d67469cc7129b0babc0211c32fa68408ce0 (patch) | |
tree | c0d49ca0813d61e2c4f266b7da9dcc244bf8bee5 /arch/blackfin/include/asm/cmpxchg.h | |
parent | 0eceb82f55a9e3756cada9e60ecc3a9b7b5979f5 (diff) |
Disintegrate asm/system.h for Blackfin [ver #2]
Disintegrate asm/system.h for Blackfin.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: uclinux-dist-devel@blackfin.uclinux.org
Signed-off-by: Bob Liu <lliubbo@gmail.com>
Diffstat (limited to 'arch/blackfin/include/asm/cmpxchg.h')
-rw-r--r-- | arch/blackfin/include/asm/cmpxchg.h | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/arch/blackfin/include/asm/cmpxchg.h b/arch/blackfin/include/asm/cmpxchg.h new file mode 100644 index 000000000000..ba2484f4cb2a --- /dev/null +++ b/arch/blackfin/include/asm/cmpxchg.h | |||
@@ -0,0 +1,132 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2011 Analog Devices Inc. | ||
3 | * | ||
4 | * Licensed under the GPL-2 or later. | ||
5 | */ | ||
6 | |||
7 | #ifndef __ARCH_BLACKFIN_CMPXCHG__ | ||
8 | #define __ARCH_BLACKFIN_CMPXCHG__ | ||
9 | |||
10 | #ifdef CONFIG_SMP | ||
11 | |||
12 | #include <linux/linkage.h> | ||
13 | |||
14 | asmlinkage unsigned long __raw_xchg_1_asm(volatile void *ptr, unsigned long value); | ||
15 | asmlinkage unsigned long __raw_xchg_2_asm(volatile void *ptr, unsigned long value); | ||
16 | asmlinkage unsigned long __raw_xchg_4_asm(volatile void *ptr, unsigned long value); | ||
17 | asmlinkage unsigned long __raw_cmpxchg_1_asm(volatile void *ptr, | ||
18 | unsigned long new, unsigned long old); | ||
19 | asmlinkage unsigned long __raw_cmpxchg_2_asm(volatile void *ptr, | ||
20 | unsigned long new, unsigned long old); | ||
21 | asmlinkage unsigned long __raw_cmpxchg_4_asm(volatile void *ptr, | ||
22 | unsigned long new, unsigned long old); | ||
23 | |||
24 | static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | ||
25 | int size) | ||
26 | { | ||
27 | unsigned long tmp; | ||
28 | |||
29 | switch (size) { | ||
30 | case 1: | ||
31 | tmp = __raw_xchg_1_asm(ptr, x); | ||
32 | break; | ||
33 | case 2: | ||
34 | tmp = __raw_xchg_2_asm(ptr, x); | ||
35 | break; | ||
36 | case 4: | ||
37 | tmp = __raw_xchg_4_asm(ptr, x); | ||
38 | break; | ||
39 | } | ||
40 | |||
41 | return tmp; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
46 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
47 | * indicated by comparing RETURN with OLD. | ||
48 | */ | ||
49 | static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | ||
50 | unsigned long new, int size) | ||
51 | { | ||
52 | unsigned long tmp; | ||
53 | |||
54 | switch (size) { | ||
55 | case 1: | ||
56 | tmp = __raw_cmpxchg_1_asm(ptr, new, old); | ||
57 | break; | ||
58 | case 2: | ||
59 | tmp = __raw_cmpxchg_2_asm(ptr, new, old); | ||
60 | break; | ||
61 | case 4: | ||
62 | tmp = __raw_cmpxchg_4_asm(ptr, new, old); | ||
63 | break; | ||
64 | } | ||
65 | |||
66 | return tmp; | ||
67 | } | ||
68 | #define cmpxchg(ptr, o, n) \ | ||
69 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ | ||
70 | (unsigned long)(n), sizeof(*(ptr)))) | ||
71 | |||
72 | #else /* !CONFIG_SMP */ | ||
73 | |||
74 | #include <mach/blackfin.h> | ||
75 | #include <asm/irqflags.h> | ||
76 | |||
77 | struct __xchg_dummy { | ||
78 | unsigned long a[100]; | ||
79 | }; | ||
80 | #define __xg(x) ((volatile struct __xchg_dummy *)(x)) | ||
81 | |||
82 | static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | ||
83 | int size) | ||
84 | { | ||
85 | unsigned long tmp = 0; | ||
86 | unsigned long flags; | ||
87 | |||
88 | flags = hard_local_irq_save(); | ||
89 | |||
90 | switch (size) { | ||
91 | case 1: | ||
92 | __asm__ __volatile__ | ||
93 | ("%0 = b%2 (z);\n\t" | ||
94 | "b%2 = %1;\n\t" | ||
95 | : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); | ||
96 | break; | ||
97 | case 2: | ||
98 | __asm__ __volatile__ | ||
99 | ("%0 = w%2 (z);\n\t" | ||
100 | "w%2 = %1;\n\t" | ||
101 | : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); | ||
102 | break; | ||
103 | case 4: | ||
104 | __asm__ __volatile__ | ||
105 | ("%0 = %2;\n\t" | ||
106 | "%2 = %1;\n\t" | ||
107 | : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory"); | ||
108 | break; | ||
109 | } | ||
110 | hard_local_irq_restore(flags); | ||
111 | return tmp; | ||
112 | } | ||
113 | |||
114 | #include <asm-generic/cmpxchg-local.h> | ||
115 | |||
116 | /* | ||
117 | * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make | ||
118 | * them available. | ||
119 | */ | ||
120 | #define cmpxchg_local(ptr, o, n) \ | ||
121 | ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ | ||
122 | (unsigned long)(n), sizeof(*(ptr)))) | ||
123 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | ||
124 | |||
125 | #include <asm-generic/cmpxchg.h> | ||
126 | |||
127 | #endif /* !CONFIG_SMP */ | ||
128 | |||
129 | #define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) | ||
130 | #define tas(ptr) ((void)xchg((ptr), 1)) | ||
131 | |||
132 | #endif /* __ARCH_BLACKFIN_CMPXCHG__ */ | ||