1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Copyright 1995, Russell King.
3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Various bits and pieces copyrights include:
4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *  Linus Torvalds (test_bit).
5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Big endian support: Copyright 2001, Nicolas Pitre
6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *  reworked by rmk.
7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * bit 0 is the LSB of an "unsigned long" quantity.
9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Please note that the code in this file should never be included
11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * from user space.  Many of these are not implemented in assembler
12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * since they would be too costly.  Also, they require privileged
13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * instructions (which are not available from user mode) to ensure
14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * that they are atomic.
15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ASM_ARM_BITOPS_H
18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ASM_ARM_BITOPS_H
19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef __KERNEL__
21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/compiler.h>
23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/system.h>
24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_mb__before_clear_bit()	mb()
26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define smp_mb__after_clear_bit()	mb()
27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * These functions are the basis of our bit ops.
30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * First, the atomic bitops. These use native endian.
32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flags;
36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long mask = 1UL << (bit & 31);
37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	p += bit >> 5;
39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_save(flags);
41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	*p |= mask;
42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_restore(flags);
43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flags;
48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long mask = 1UL << (bit & 31);
49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	p += bit >> 5;
51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_save(flags);
53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	*p &= ~mask;
54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_restore(flags);
55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flags;
60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long mask = 1UL << (bit & 31);
61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	p += bit >> 5;
63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_save(flags);
65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	*p ^= mask;
66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_restore(flags);
67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int
70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flags;
73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned int res;
74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long mask = 1UL << (bit & 31);
75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	p += bit >> 5;
77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_save(flags);
79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	res = *p;
80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	*p = res | mask;
81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_restore(flags);
82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return res & mask;
84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int
87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flags;
90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned int res;
91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long mask = 1UL << (bit & 31);
92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	p += bit >> 5;
94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_save(flags);
96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	res = *p;
97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	*p = res & ~mask;
98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_restore(flags);
99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return res & mask;
101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int
104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flags;
107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned int res;
108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long mask = 1UL << (bit & 31);
109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	p += bit >> 5;
111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_save(flags);
113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	res = *p;
114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	*p = res ^ mask;
115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	local_irq_restore(flags);
116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return res & mask;
118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/non-atomic.h>
121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *  A note about Endian-ness.
124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *  -------------------------
125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * When the ARM is put into big endian mode via CR15, the processor
127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * merely swaps the order of bytes within words, thus:
128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *          ------------ physical data bus bits -----------
130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *          D31 ... D24  D23 ... D16  D15 ... D8  D7 ... D0
131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * little     byte 3       byte 2       byte 1      byte 0
132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * big        byte 0       byte 1       byte 2      byte 3
133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This means that reading a 32-bit word at address 0 returns the same
135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * value irrespective of the endian mode bit.
136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Peripheral devices should be connected with the data bus reversed in
138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * "Big Endian" mode.  ARM Application Note 61 is applicable, and is
139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * available from http://www.arm.com/.
140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The following assumes that the data bus connectivity for big endian
142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * mode has been followed.
143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void _set_bit_le(int nr, volatile unsigned long * p);
151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void _clear_bit_le(int nr, volatile unsigned long * p);
152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void _change_bit_le(int nr, volatile unsigned long * p);
153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_first_zero_bit_le(const void * p, unsigned size);
157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_next_zero_bit_le(const void * p, int size, int offset);
158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_first_bit_le(const unsigned long *p, unsigned size);
159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_next_bit_le(const unsigned long *p, int size, int offset);
160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Big endian assembly bitops.  nr = 0 -> byte 3 bit 0.
163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void _set_bit_be(int nr, volatile unsigned long * p);
165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void _clear_bit_be(int nr, volatile unsigned long * p);
166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern void _change_bit_be(int nr, volatile unsigned long * p);
167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_first_zero_bit_be(const void * p, unsigned size);
171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_next_zero_bit_be(const void * p, int size, int offset);
172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_first_bit_be(const unsigned long *p, unsigned size);
173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int _find_next_bit_be(const unsigned long *p, int size, int offset);
174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef CONFIG_SMP
176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The __* form of bitops are non-atomic and may be reordered.
178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define	ATOMIC_BITOP_LE(name,nr,p)		\
180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(__builtin_constant_p(nr) ?		\
181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	 ____atomic_##name(nr, p) :		\
182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	 _##name##_le(nr,p))
183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define	ATOMIC_BITOP_BE(name,nr,p)		\
185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(__builtin_constant_p(nr) ?		\
186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	 ____atomic_##name(nr, p) :		\
187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	 _##name##_be(nr,p))
188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ATOMIC_BITOP_LE(name,nr,p)	_##name##_le(nr,p)
190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ATOMIC_BITOP_BE(name,nr,p)	_##name##_be(nr,p)
191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define NONATOMIC_BITOP(name,nr,p)		\
194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(____nonatomic_##name(nr, p))
195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ARMEB__
197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * These are the little endian, atomic definitions.
199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define set_bit(nr,p)			ATOMIC_BITOP_LE(set_bit,nr,p)
201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define clear_bit(nr,p)			ATOMIC_BITOP_LE(clear_bit,nr,p)
202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define change_bit(nr,p)		ATOMIC_BITOP_LE(change_bit,nr,p)
203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define test_and_set_bit(nr,p)		ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define test_and_change_bit(nr,p)	ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_first_zero_bit(p,sz)	_find_first_zero_bit_le(p,sz)
207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_le(p,sz,off)
208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_first_bit(p,sz)		_find_first_bit_le(p,sz)
209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_next_bit(p,sz,off)		_find_next_bit_le(p,sz,off)
210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define WORD_BITOFF_TO_LE(x)		((x))
212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * These are the big endian, atomic definitions.
217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define set_bit(nr,p)			ATOMIC_BITOP_BE(set_bit,nr,p)
219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define clear_bit(nr,p)			ATOMIC_BITOP_BE(clear_bit,nr,p)
220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define change_bit(nr,p)		ATOMIC_BITOP_BE(change_bit,nr,p)
221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define test_and_set_bit(nr,p)		ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
222c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define test_and_clear_bit(nr,p)	ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
223c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define test_and_change_bit(nr,p)	ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
224c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_first_zero_bit(p,sz)	_find_first_zero_bit_be(p,sz)
225c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_next_zero_bit(p,sz,off)	_find_next_zero_bit_be(p,sz,off)
226c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_first_bit(p,sz)		_find_first_bit_be(p,sz)
227c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define find_next_bit(p,sz,off)		_find_next_bit_be(p,sz,off)
228c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
229c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define WORD_BITOFF_TO_LE(x)		((x) ^ 0x18)
230c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
231c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
232c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
233c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if __LINUX_ARM_ARCH__ < 5
234c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
235c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/ffz.h>
236c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/__ffs.h>
237c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/fls.h>
238c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/ffs.h>
239c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
240c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
241c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
242c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int constant_fls(int x)
243c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
244c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	int r = 32;
245c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
246c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (!x)
247c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		return 0;
248c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (!(x & 0xffff0000u)) {
249c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		x <<= 16;
250c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r -= 16;
251c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
252c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (!(x & 0xff000000u)) {
253c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		x <<= 8;
254c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r -= 8;
255c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
256c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (!(x & 0xf0000000u)) {
257c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		x <<= 4;
258c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r -= 4;
259c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
260c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (!(x & 0xc0000000u)) {
261c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		x <<= 2;
262c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r -= 2;
263c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
264c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (!(x & 0x80000000u)) {
265c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		x <<= 1;
266c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		r -= 1;
267c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}
268c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return r;
269c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
270c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
271c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
272c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * On ARMv5 and above those functions can be implemented around
273c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the clz instruction for much better code efficiency.
274c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
275c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
276c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define fls(x) \
277c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	( __builtin_constant_p(x) ? constant_fls(x) : \
278c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	  ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) )
279c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
280c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ffs(x) (ffs(x) - 1)
281c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ffz(x) __ffs( ~(x) )
282c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
283c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
284c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
285c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/fls64.h>
286c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
287c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/sched.h>
288c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm-generic/bitops/hweight.h>
289c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
290c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
291c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Ext2 is defined to use little-endian byte ordering.
292c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * These do not need to be atomic.
293c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
294c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ext2_set_bit(nr,p)			\
295c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
296c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ext2_set_bit_atomic(lock,nr,p)          \
297c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru                test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
298c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ext2_clear_bit(nr,p)			\
299c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
300c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ext2_clear_bit_atomic(lock,nr,p)        \
301c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru                test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
302c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ext2_test_bit(nr,p)			\
303c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
304c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ext2_find_first_zero_bit(p,sz)		\
305c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		_find_first_zero_bit_le(p,sz)
306c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define ext2_find_next_zero_bit(p,sz,off)	\
307c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		_find_next_zero_bit_le(p,sz,off)
308c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
309c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
310c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Minix is defined to use little-endian byte ordering.
311c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * These do not need to be atomic.
312c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
313c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define minix_set_bit(nr,p)			\
314c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
315c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define minix_test_bit(nr,p)			\
316c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
317c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define minix_test_and_set_bit(nr,p)		\
318c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
319c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define minix_test_and_clear_bit(nr,p)		\
320c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
321c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define minix_find_first_zero_bit(p,sz)		\
322c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		_find_first_zero_bit_le(p,sz)
323c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
324c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __KERNEL__ */
325c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
326c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* _ARM_BITOPS_H */
327