Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
[deliverable/linux.git] / arch / xtensa / include / asm / bitops.h
CommitLineData
9a8fd558
CZ
1/*
2 * include/asm-xtensa/bitops.h
3 *
4 * Atomic operations that C can't guarantee us.Useful for resource counting etc.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
ef6051a9 10 * Copyright (C) 2001 - 2007 Tensilica Inc.
9a8fd558
CZ
11 */
12
13#ifndef _XTENSA_BITOPS_H
14#define _XTENSA_BITOPS_H
15
16#ifdef __KERNEL__
17
0624517d
JS
18#ifndef _LINUX_BITOPS_H
19#error only <linux/bitops.h> can be included directly
20#endif
21
9a8fd558
CZ
22#include <asm/processor.h>
23#include <asm/byteorder.h>
9a8fd558 24
f615136c
MF
25#define smp_mb__before_clear_bit() smp_mb()
26#define smp_mb__after_clear_bit() smp_mb()
9a8fd558 27
d4337aa5 28#include <asm-generic/bitops/non-atomic.h>
9a8fd558 29
288a60cf 30#if XCHAL_HAVE_NSA
9a8fd558 31
ef6051a9 32static inline unsigned long __cntlz (unsigned long x)
9a8fd558
CZ
33{
34 int lz;
35 asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
ef6051a9 36 return lz;
9a8fd558
CZ
37}
38
9a8fd558
CZ
39/*
40 * ffz: Find first zero in word. Undefined if no zero exists.
41 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
42 */
43
ef6051a9 44static inline int ffz(unsigned long x)
9a8fd558 45{
ef6051a9 46 return 31 - __cntlz(~x & -~x);
9a8fd558
CZ
47}
48
49/*
50 * __ffs: Find first bit set in word. Return 0 for bit 0
51 */
52
ef6051a9 53static inline int __ffs(unsigned long x)
9a8fd558 54{
ef6051a9 55 return 31 - __cntlz(x & -x);
9a8fd558
CZ
56}
57
58/*
59 * ffs: Find first bit set in word. This is defined the same way as
60 * the libc and compiler builtin ffs routines, therefore
61 * differs in spirit from the above ffz (man ffs).
62 */
63
ef6051a9 64static inline int ffs(unsigned long x)
9a8fd558 65{
ef6051a9 66 return 32 - __cntlz(x & -x);
9a8fd558
CZ
67}
68
69/*
70 * fls: Find last (most-significant) bit set in word.
71 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
72 */
73
ef6051a9 74static inline int fls (unsigned int x)
9a8fd558 75{
ef6051a9 76 return 32 - __cntlz(x);
9a8fd558 77}
ef6051a9 78
5ece5c51
RR
79/**
80 * __fls - find last (most-significant) set bit in a long word
81 * @word: the word to search
82 *
83 * Undefined if no set bit exists, so code should check against 0 first.
84 */
85static inline unsigned long __fls(unsigned long word)
86{
87 return 31 - __cntlz(word);
88}
ef6051a9
CZ
89#else
90
91/* Use the generic implementation if we don't have the nsa/nsau instructions. */
92
93# include <asm-generic/bitops/ffs.h>
94# include <asm-generic/bitops/__ffs.h>
95# include <asm-generic/bitops/ffz.h>
96# include <asm-generic/bitops/fls.h>
5ece5c51 97# include <asm-generic/bitops/__fls.h>
ef6051a9
CZ
98
99#endif
100
d4337aa5 101#include <asm-generic/bitops/fls64.h>
e5a9f6ad
MF
102
103#if XCHAL_HAVE_S32C1I
104
105static inline void set_bit(unsigned int bit, volatile unsigned long *p)
106{
107 unsigned long tmp, value;
108 unsigned long mask = 1UL << (bit & 31);
109
110 p += bit >> 5;
111
112 __asm__ __volatile__(
113 "1: l32i %1, %3, 0\n"
114 " wsr %1, scompare1\n"
115 " or %0, %1, %2\n"
116 " s32c1i %0, %3, 0\n"
117 " bne %0, %1, 1b\n"
118 : "=&a" (tmp), "=&a" (value)
119 : "a" (mask), "a" (p)
120 : "memory");
121}
122
123static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
124{
125 unsigned long tmp, value;
126 unsigned long mask = 1UL << (bit & 31);
127
128 p += bit >> 5;
129
130 __asm__ __volatile__(
131 "1: l32i %1, %3, 0\n"
132 " wsr %1, scompare1\n"
133 " and %0, %1, %2\n"
134 " s32c1i %0, %3, 0\n"
135 " bne %0, %1, 1b\n"
136 : "=&a" (tmp), "=&a" (value)
137 : "a" (~mask), "a" (p)
138 : "memory");
139}
140
141static inline void change_bit(unsigned int bit, volatile unsigned long *p)
142{
143 unsigned long tmp, value;
144 unsigned long mask = 1UL << (bit & 31);
145
146 p += bit >> 5;
147
148 __asm__ __volatile__(
149 "1: l32i %1, %3, 0\n"
150 " wsr %1, scompare1\n"
151 " xor %0, %1, %2\n"
152 " s32c1i %0, %3, 0\n"
153 " bne %0, %1, 1b\n"
154 : "=&a" (tmp), "=&a" (value)
155 : "a" (mask), "a" (p)
156 : "memory");
157}
158
159static inline int
160test_and_set_bit(unsigned int bit, volatile unsigned long *p)
161{
162 unsigned long tmp, value;
163 unsigned long mask = 1UL << (bit & 31);
164
165 p += bit >> 5;
166
167 __asm__ __volatile__(
168 "1: l32i %1, %3, 0\n"
169 " wsr %1, scompare1\n"
170 " or %0, %1, %2\n"
171 " s32c1i %0, %3, 0\n"
172 " bne %0, %1, 1b\n"
173 : "=&a" (tmp), "=&a" (value)
174 : "a" (mask), "a" (p)
175 : "memory");
176
177 return tmp & mask;
178}
179
180static inline int
181test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
182{
183 unsigned long tmp, value;
184 unsigned long mask = 1UL << (bit & 31);
185
186 p += bit >> 5;
187
188 __asm__ __volatile__(
189 "1: l32i %1, %3, 0\n"
190 " wsr %1, scompare1\n"
191 " and %0, %1, %2\n"
192 " s32c1i %0, %3, 0\n"
193 " bne %0, %1, 1b\n"
194 : "=&a" (tmp), "=&a" (value)
195 : "a" (~mask), "a" (p)
196 : "memory");
197
198 return tmp & mask;
199}
200
201static inline int
202test_and_change_bit(unsigned int bit, volatile unsigned long *p)
203{
204 unsigned long tmp, value;
205 unsigned long mask = 1UL << (bit & 31);
206
207 p += bit >> 5;
208
209 __asm__ __volatile__(
210 "1: l32i %1, %3, 0\n"
211 " wsr %1, scompare1\n"
212 " xor %0, %1, %2\n"
213 " s32c1i %0, %3, 0\n"
214 " bne %0, %1, 1b\n"
215 : "=&a" (tmp), "=&a" (value)
216 : "a" (mask), "a" (p)
217 : "memory");
218
219 return tmp & mask;
220}
221
222#else
223
224#include <asm-generic/bitops/atomic.h>
225
226#endif /* XCHAL_HAVE_S32C1I */
227
d4337aa5 228#include <asm-generic/bitops/find.h>
861b5ae7 229#include <asm-generic/bitops/le.h>
9a8fd558 230
148817ba 231#include <asm-generic/bitops/ext2-atomic-setbit.h>
9a8fd558 232
d4337aa5 233#include <asm-generic/bitops/hweight.h>
26333576 234#include <asm-generic/bitops/lock.h>
d4337aa5 235#include <asm-generic/bitops/sched.h>
9a8fd558
CZ
236
237#endif /* __KERNEL__ */
238
239#endif /* _XTENSA_BITOPS_H */
This page took 0.748111 seconds and 5 git commands to generate.