aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/bitops.h
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2011-01-16 13:02:17 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-02 16:23:25 -0500
commit6323f0ccedf756dfe5f46549cec69a2d6d97937b (patch)
tree091e3408c12bbce33ef5d708b6131132b9660d4d /arch/arm/include/asm/bitops.h
parenta16ede35a2659170c855c5d267776666c0630f1f (diff)
ARM: bitops: switch set/clear/change bitops to use ldrex/strex
Switch the set/clear/change bitops to use the word-based exclusive operations, which are only present in a wider range of ARM architectures than the byte-based exclusive operations. Tested record: - Nicolas Pitre: ext3,rw,le - Sourav Poddar: nfs,le - Will Deacon: ext3,rw,le - Tony Lindgren: ext3+nfs,le Reviewed-by: Nicolas Pitre <nicolas.pitre@linaro.org> Tested-by: Sourav Poddar <sourav.poddar@ti.com> Tested-by: Will Deacon <will.deacon@arm.com> Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/include/asm/bitops.h')
-rw-r--r--arch/arm/include/asm/bitops.h60
1 files changed, 22 insertions, 38 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 7b1bb2bbaf88..af54ed102f5f 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -149,14 +149,18 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
149 */ 149 */
150 150
151/* 151/*
152 * Native endian assembly bitops. nr = 0 -> word 0 bit 0.
153 */
154extern void _set_bit(int nr, volatile unsigned long * p);
155extern void _clear_bit(int nr, volatile unsigned long * p);
156extern void _change_bit(int nr, volatile unsigned long * p);
157extern int _test_and_set_bit(int nr, volatile unsigned long * p);
158extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
159extern int _test_and_change_bit(int nr, volatile unsigned long * p);
160
161/*
152 * Little endian assembly bitops. nr = 0 -> byte 0 bit 0. 162 * Little endian assembly bitops. nr = 0 -> byte 0 bit 0.
153 */ 163 */
154extern void _set_bit_le(int nr, volatile unsigned long * p);
155extern void _clear_bit_le(int nr, volatile unsigned long * p);
156extern void _change_bit_le(int nr, volatile unsigned long * p);
157extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
158extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
159extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
160extern int _find_first_zero_bit_le(const void * p, unsigned size); 164extern int _find_first_zero_bit_le(const void * p, unsigned size);
161extern int _find_next_zero_bit_le(const void * p, int size, int offset); 165extern int _find_next_zero_bit_le(const void * p, int size, int offset);
162extern int _find_first_bit_le(const unsigned long *p, unsigned size); 166extern int _find_first_bit_le(const unsigned long *p, unsigned size);
@@ -165,12 +169,6 @@ extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
165/* 169/*
166 * Big endian assembly bitops. nr = 0 -> byte 3 bit 0. 170 * Big endian assembly bitops. nr = 0 -> byte 3 bit 0.
167 */ 171 */
168extern void _set_bit_be(int nr, volatile unsigned long * p);
169extern void _clear_bit_be(int nr, volatile unsigned long * p);
170extern void _change_bit_be(int nr, volatile unsigned long * p);
171extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
172extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
173extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
174extern int _find_first_zero_bit_be(const void * p, unsigned size); 172extern int _find_first_zero_bit_be(const void * p, unsigned size);
175extern int _find_next_zero_bit_be(const void * p, int size, int offset); 173extern int _find_next_zero_bit_be(const void * p, int size, int offset);
176extern int _find_first_bit_be(const unsigned long *p, unsigned size); 174extern int _find_first_bit_be(const unsigned long *p, unsigned size);
@@ -180,33 +178,26 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
180/* 178/*
181 * The __* form of bitops are non-atomic and may be reordered. 179 * The __* form of bitops are non-atomic and may be reordered.
182 */ 180 */
183#define ATOMIC_BITOP_LE(name,nr,p) \ 181#define ATOMIC_BITOP(name,nr,p) \
184 (__builtin_constant_p(nr) ? \ 182 (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p))
185 ____atomic_##name(nr, p) : \
186 _##name##_le(nr,p))
187
188#define ATOMIC_BITOP_BE(name,nr,p) \
189 (__builtin_constant_p(nr) ? \
190 ____atomic_##name(nr, p) : \
191 _##name##_be(nr,p))
192#else 183#else
193#define ATOMIC_BITOP_LE(name,nr,p) _##name##_le(nr,p) 184#define ATOMIC_BITOP(name,nr,p) _##name(nr,p)
194#define ATOMIC_BITOP_BE(name,nr,p) _##name##_be(nr,p)
195#endif 185#endif
196 186
197#define NONATOMIC_BITOP(name,nr,p) \ 187/*
198 (____nonatomic_##name(nr, p)) 188 * Native endian atomic definitions.
189 */
190#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p)
191#define clear_bit(nr,p) ATOMIC_BITOP(clear_bit,nr,p)
192#define change_bit(nr,p) ATOMIC_BITOP(change_bit,nr,p)
193#define test_and_set_bit(nr,p) ATOMIC_BITOP(test_and_set_bit,nr,p)
194#define test_and_clear_bit(nr,p) ATOMIC_BITOP(test_and_clear_bit,nr,p)
195#define test_and_change_bit(nr,p) ATOMIC_BITOP(test_and_change_bit,nr,p)
199 196
200#ifndef __ARMEB__ 197#ifndef __ARMEB__
201/* 198/*
202 * These are the little endian, atomic definitions. 199 * These are the little endian, atomic definitions.
203 */ 200 */
204#define set_bit(nr,p) ATOMIC_BITOP_LE(set_bit,nr,p)
205#define clear_bit(nr,p) ATOMIC_BITOP_LE(clear_bit,nr,p)
206#define change_bit(nr,p) ATOMIC_BITOP_LE(change_bit,nr,p)
207#define test_and_set_bit(nr,p) ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
208#define test_and_clear_bit(nr,p) ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
209#define test_and_change_bit(nr,p) ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
210#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz) 201#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz)
211#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off) 202#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off)
212#define find_first_bit(p,sz) _find_first_bit_le(p,sz) 203#define find_first_bit(p,sz) _find_first_bit_le(p,sz)
@@ -215,16 +206,9 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
215#define WORD_BITOFF_TO_LE(x) ((x)) 206#define WORD_BITOFF_TO_LE(x) ((x))
216 207
217#else 208#else
218
219/* 209/*
220 * These are the big endian, atomic definitions. 210 * These are the big endian, atomic definitions.
221 */ 211 */
222#define set_bit(nr,p) ATOMIC_BITOP_BE(set_bit,nr,p)
223#define clear_bit(nr,p) ATOMIC_BITOP_BE(clear_bit,nr,p)
224#define change_bit(nr,p) ATOMIC_BITOP_BE(change_bit,nr,p)
225#define test_and_set_bit(nr,p) ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
226#define test_and_clear_bit(nr,p) ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
227#define test_and_change_bit(nr,p) ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
228#define find_first_zero_bit(p,sz) _find_first_zero_bit_be(p,sz) 212#define find_first_zero_bit(p,sz) _find_first_zero_bit_be(p,sz)
229#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_be(p,sz,off) 213#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_be(p,sz,off)
230#define find_first_bit(p,sz) _find_first_bit_be(p,sz) 214#define find_first_bit(p,sz) _find_first_bit_be(p,sz)