aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/include/asm/cmpxchg.h
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-03-12 19:36:56 -0400
committerBob Liu <lliubbo@gmail.com>2012-03-20 23:00:08 -0400
commit3bed8d67469cc7129b0babc0211c32fa68408ce0 (patch)
treec0d49ca0813d61e2c4f266b7da9dcc244bf8bee5 /arch/blackfin/include/asm/cmpxchg.h
parent0eceb82f55a9e3756cada9e60ecc3a9b7b5979f5 (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.h132
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
14asmlinkage unsigned long __raw_xchg_1_asm(volatile void *ptr, unsigned long value);
15asmlinkage unsigned long __raw_xchg_2_asm(volatile void *ptr, unsigned long value);
16asmlinkage unsigned long __raw_xchg_4_asm(volatile void *ptr, unsigned long value);
17asmlinkage unsigned long __raw_cmpxchg_1_asm(volatile void *ptr,
18 unsigned long new, unsigned long old);
19asmlinkage unsigned long __raw_cmpxchg_2_asm(volatile void *ptr,
20 unsigned long new, unsigned long old);
21asmlinkage unsigned long __raw_cmpxchg_4_asm(volatile void *ptr,
22 unsigned long new, unsigned long old);
23
24static 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 */
49static 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
77struct __xchg_dummy {
78 unsigned long a[100];
79};
80#define __xg(x) ((volatile struct __xchg_dummy *)(x))
81
82static 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__ */