aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2014-03-23 14:06:34 -0400
committerIngo Molnar <mingo@kernel.org>2014-08-14 06:48:08 -0400
commitd839bae4269aea46bff4133066a411cfba5c7c46 (patch)
treeaf4454c73ca7196041df6611d43642d60527a4e4
parentc9ebe21b204f95e3aba84ee91c8b9347d73806f1 (diff)
locking,arch,m68k: Fold atomic_ops
Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Requires asm_op due to eor. Signed-off-by: Peter Zijlstra <peterz@infradead.org> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: linux-m68k@lists.linux-m68k.org Link: http://lkml.kernel.org/r/20140509091646.GO30445@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/m68k/include/asm/atomic.h109
1 files changed, 47 insertions, 62 deletions
diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h
index 55695212a2ae..663d4ba2462c 100644
--- a/arch/m68k/include/asm/atomic.h
+++ b/arch/m68k/include/asm/atomic.h
@@ -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;