aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 09:48:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 09:48:00 -0400
commitdbb885fecc1b1b35e93416bedd24d21bd20f60ed (patch)
tree9aa92bcc4e3d3594eba0ba85d72b878d85f35a59 /arch/m68k/include
parentd6dd50e07c5bec00db2005969b1a01f8ca3d25ef (diff)
parent2291059c852706c6f5ffb400366042b7625066cd (diff)
Merge branch 'locking-arch-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull arch atomic cleanups from Ingo Molnar: "This is a series kept separate from the main locking tree, which cleans up and improves various details in the atomics type handling: - Remove the unused atomic_or_long() method - Consolidate and compress atomic ops implementations between architectures, to reduce linecount and to make it easier to add new ops. - Rewrite generic atomic support to only require cmpxchg() from an architecture - generate all other methods from that" * 'locking-arch-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits) locking,arch: Use ACCESS_ONCE() instead of cast to volatile in atomic_read() locking, mips: Fix atomics locking, sparc64: Fix atomics locking,arch: Rewrite generic atomic support locking,arch,xtensa: Fold atomic_ops locking,arch,sparc: Fold atomic_ops locking,arch,sh: Fold atomic_ops locking,arch,powerpc: Fold atomic_ops locking,arch,parisc: Fold atomic_ops locking,arch,mn10300: Fold atomic_ops locking,arch,mips: Fold atomic_ops locking,arch,metag: Fold atomic_ops locking,arch,m68k: Fold atomic_ops locking,arch,m32r: Fold atomic_ops locking,arch,ia64: Fold atomic_ops locking,arch,hexagon: Fold atomic_ops locking,arch,cris: Fold atomic_ops locking,arch,avr32: Fold atomic_ops locking,arch,arm64: Fold atomic_ops locking,arch,arm: Fold atomic_ops ...
Diffstat (limited to 'arch/m68k/include')
-rw-r--r--arch/m68k/include/asm/atomic.h111
1 files changed, 48 insertions, 63 deletions
diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h
index 55695212a2ae..e85f047fb072 100644
--- a/arch/m68k/include/asm/atomic.h
+++ b/arch/m68k/include/asm/atomic.h
@@ -17,7 +17,7 @@
17 17
18#define ATOMIC_INIT(i) { (i) } 18#define ATOMIC_INIT(i) { (i) }
19 19
20#define atomic_read(v) (*(volatile int *)&(v)->counter) 20#define atomic_read(v) ACCESS_ONCE((v)->counter)
21#define atomic_set(v, i) (((v)->counter) = i) 21#define atomic_set(v, i) (((v)->counter) = i)
22 22
23/* 23/*
@@ -30,16 +30,57 @@
30#define ASM_DI "di" 30#define ASM_DI "di"
31#endif 31#endif
32 32
33static inline void atomic_add(int i, atomic_t *v) 33#define ATOMIC_OP(op, c_op, asm_op) \
34{ 34static inline void atomic_##op(int i, atomic_t *v) \
35 __asm__ __volatile__("addl %1,%0" : "+m" (*v) : ASM_DI (i)); 35{ \
36 __asm__ __volatile__(#asm_op "l %1,%0" : "+m" (*v) : ASM_DI (i));\
37} \
38
39#ifdef CONFIG_RMW_INSNS
40
41#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
42static inline int atomic_##op##_return(int i, atomic_t *v) \
43{ \
44 int t, tmp; \
45 \
46 __asm__ __volatile__( \
47 "1: movel %2,%1\n" \
48 " " #asm_op "l %3,%1\n" \
49 " casl %2,%1,%0\n" \
50 " jne 1b" \
51 : "+m" (*v), "=&d" (t), "=&d" (tmp) \
52 : "g" (i), "2" (atomic_read(v))); \
53 return t; \
36} 54}
37 55
38static inline void atomic_sub(int i, atomic_t *v) 56#else
39{ 57
40 __asm__ __volatile__("subl %1,%0" : "+m" (*v) : ASM_DI (i)); 58#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
59static inline int atomic_##op##_return(int i, atomic_t * v) \
60{ \
61 unsigned long flags; \
62 int t; \
63 \
64 local_irq_save(flags); \
65 t = (v->counter c_op i); \
66 local_irq_restore(flags); \
67 \
68 return t; \
41} 69}
42 70
71#endif /* CONFIG_RMW_INSNS */
72
73#define ATOMIC_OPS(op, c_op, asm_op) \
74 ATOMIC_OP(op, c_op, asm_op) \
75 ATOMIC_OP_RETURN(op, c_op, asm_op)
76
77ATOMIC_OPS(add, +=, add)
78ATOMIC_OPS(sub, -=, sub)
79
80#undef ATOMIC_OPS
81#undef ATOMIC_OP_RETURN
82#undef ATOMIC_OP
83
43static inline void atomic_inc(atomic_t *v) 84static inline void atomic_inc(atomic_t *v)
44{ 85{
45 __asm__ __volatile__("addql #1,%0" : "+m" (*v)); 86 __asm__ __volatile__("addql #1,%0" : "+m" (*v));
@@ -76,67 +117,11 @@ static inline int atomic_inc_and_test(atomic_t *v)
76 117
77#ifdef CONFIG_RMW_INSNS 118#ifdef CONFIG_RMW_INSNS
78 119
79static inline int atomic_add_return(int i, atomic_t *v)
80{
81 int t, tmp;
82
83 __asm__ __volatile__(
84 "1: movel %2,%1\n"
85 " addl %3,%1\n"
86 " casl %2,%1,%0\n"
87 " jne 1b"
88 : "+m" (*v), "=&d" (t), "=&d" (tmp)
89 : "g" (i), "2" (atomic_read(v)));
90 return t;
91}
92
93static inline int atomic_sub_return(int i, atomic_t *v)
94{
95 int t, tmp;
96
97 __asm__ __volatile__(
98 "1: movel %2,%1\n"
99 " subl %3,%1\n"
100 " casl %2,%1,%0\n"
101 " jne 1b"
102 : "+m" (*v), "=&d" (t), "=&d" (tmp)
103 : "g" (i), "2" (atomic_read(v)));
104 return t;
105}
106
107#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) 120#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
108#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 121#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
109 122
110#else /* !CONFIG_RMW_INSNS */ 123#else /* !CONFIG_RMW_INSNS */
111 124
112static inline int atomic_add_return(int i, atomic_t * v)
113{
114 unsigned long flags;
115 int t;
116
117 local_irq_save(flags);
118 t = atomic_read(v);
119 t += i;
120 atomic_set(v, t);
121 local_irq_restore(flags);
122
123 return t;
124}
125
126static inline int atomic_sub_return(int i, atomic_t * v)
127{
128 unsigned long flags;
129 int t;
130
131 local_irq_save(flags);
132 t = atomic_read(v);
133 t -= i;
134 atomic_set(v, t);
135 local_irq_restore(flags);
136
137 return t;
138}
139
140static inline int atomic_cmpxchg(atomic_t *v, int old, int new) 125static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
141{ 126{
142 unsigned long flags; 127 unsigned long flags;