1633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
2633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This file is subject to the terms and conditions of the GNU General Public
3633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * License.  See the file "COPYING" in the main directory of this archive
4633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * for more details.
5633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
6633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (c) 1994 - 1997, 99, 2000, 06, 07  Ralf Baechle (ralf@linux-mips.org)
7633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (c) 1999, 2000  Silicon Graphics, Inc.
8633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
9633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifndef _ASM_BITOPS_H
10633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define _ASM_BITOPS_H
11633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
12633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifndef _LINUX_BITOPS_H
13633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#error only <linux/bitops.h> can be included directly
14633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif
15633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
16633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/compiler.h>
17633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/irqflags.h>
18633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/types.h>
19633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/barrier.h>
20633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/bug.h>
21633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/byteorder.h>		/* sigh ... */
22633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/cpu-features.h>
23633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/sgidefs.h>
24633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/war.h>
25633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
26633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#if _MIPS_SZLONG == 32
27633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_LOG 5
28633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_MASK 31UL
29633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __LL		"ll	"
30633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __SC		"sc	"
31633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __INS		"ins    "
32633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __EXT		"ext    "
33633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#elif _MIPS_SZLONG == 64
34633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_LOG 6
35633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_MASK 63UL
36633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __LL		"lld	"
37633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __SC		"scd	"
38633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __INS		"dins    "
39633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __EXT		"dext    "
40633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif
41633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
42633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
43633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit() doesn't provide any barrier for the compiler.
44633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
45633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define smp_mb__before_clear_bit()	smp_llsc_mb()
46633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define smp_mb__after_clear_bit()	smp_llsc_mb()
47633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
48633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
49633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * set_bit - Atomically set a bit in memory
50633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: the bit to set
51633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: the address to start counting from
52633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
53633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This function is atomic and may not be reordered.  See __set_bit()
54633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * if you do not require the atomic guarantees.
55633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Note that @nr may be almost arbitrarily large; this function is not
56633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * restricted to acting on a single-word quantity.
57633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
58633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void set_bit(unsigned long nr, volatile unsigned long *addr)
59633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
60633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
61633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned short bit = nr & SZLONG_MASK;
62633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long temp;
63633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
64633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (cpu_has_llsc && R10000_LLSC_WAR) {
65633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
66633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
67633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1			# set_bit	\n"
68633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%0, %2					\n"
69633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%0, %1					\n"
70633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqzl	%0, 1b					\n"
71633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
72633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
73633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (1UL << bit), "m" (*m));
74633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_CPU_MIPSR2
75633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (__builtin_constant_p(bit)) {
76633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
77633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1			# set_bit	\n"
78633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __INS "%0, %4, %2, 1				\n"
79633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC "%0, %1					\n"
80633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%0, 2f					\n"
81633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
82633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
83633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
84633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
85633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (bit), "m" (*m), "r" (~0));
86633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* CONFIG_CPU_MIPSR2 */
87633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (cpu_has_llsc) {
88633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
89633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
90633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1			# set_bit	\n"
91633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%0, %2					\n"
92633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%0, %1					\n"
93633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%0, 2f					\n"
94633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
95633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
96633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
97633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
98633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
99633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (1UL << bit), "m" (*m));
100633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else {
101633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		volatile unsigned long *a = addr;
102633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long mask;
103633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long flags;
104633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
105633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		a += nr >> SZLONG_LOG;
106633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		mask = 1UL << bit;
107633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_save(flags);
108633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		*a |= mask;
109633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_restore(flags);
110633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
111633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
112633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
113633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
114633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit - Clears a bit in memory
115633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear
116633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from
117633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
118633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit() is atomic and may not be reordered.  However, it does
119633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * not contain a memory barrier, so if it is used for locking purposes,
120633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
121633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * in order to ensure changes are visible on other processors.
122633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
123633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
124633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
125633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
126633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned short bit = nr & SZLONG_MASK;
127633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long temp;
128633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
129633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (cpu_has_llsc && R10000_LLSC_WAR) {
130633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
131633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
132633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1			# clear_bit	\n"
133633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	and	%0, %2					\n"
134633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC "%0, %1					\n"
135633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqzl	%0, 1b					\n"
136633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
137633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
138633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (~(1UL << bit)), "m" (*m));
139633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_CPU_MIPSR2
140633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (__builtin_constant_p(bit)) {
141633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
142633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1			# clear_bit	\n"
143633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __INS "%0, $0, %2, 1				\n"
144633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC "%0, %1					\n"
145633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%0, 2f					\n"
146633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
147633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
148633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
149633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
150633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (bit), "m" (*m));
151633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* CONFIG_CPU_MIPSR2 */
152633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (cpu_has_llsc) {
153633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
154633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
155633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1			# clear_bit	\n"
156633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	and	%0, %2					\n"
157633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC "%0, %1					\n"
158633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%0, 2f					\n"
159633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
160633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
161633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
162633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
163633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
164633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (~(1UL << bit)), "m" (*m));
165633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else {
166633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		volatile unsigned long *a = addr;
167633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long mask;
168633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long flags;
169633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
170633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		a += nr >> SZLONG_LOG;
171633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		mask = 1UL << bit;
172633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_save(flags);
173633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		*a &= ~mask;
174633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_restore(flags);
175633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
176633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
177633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
178633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
179633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit_unlock - Clears a bit in memory
180633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear
181633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from
182633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
183633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit() is atomic and implies release semantics before the memory
184633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * operation. It can be used for an unlock.
185633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
186633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
187633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
188633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_mb__before_clear_bit();
189633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	clear_bit(nr, addr);
190633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
191633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
192633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
193633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * change_bit - Toggle a bit in memory
194633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to change
195633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from
196633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
197633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * change_bit() is atomic and may not be reordered.
198633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Note that @nr may be almost arbitrarily large; this function is not
199633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * restricted to acting on a single-word quantity.
200633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
201633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void change_bit(unsigned long nr, volatile unsigned long *addr)
202633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
203633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned short bit = nr & SZLONG_MASK;
204633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
205633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (cpu_has_llsc && R10000_LLSC_WAR) {
206633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
207633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
208633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
209633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
210633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3				\n"
211633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1		# change_bit	\n"
212633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	xor	%0, %2				\n"
213633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%0, %1				\n"
214633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqzl	%0, 1b				\n"
215633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0				\n"
216633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
217633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (1UL << bit), "m" (*m));
218633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (cpu_has_llsc) {
219633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
220633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
221633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
222633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
223633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3				\n"
224633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1		# change_bit	\n"
225633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	xor	%0, %2				\n"
226633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%0, %1				\n"
227633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%0, 2f				\n"
228633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2				\n"
229633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b				\n"
230633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous				\n"
231633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0				\n"
232633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m)
233633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (1UL << bit), "m" (*m));
234633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else {
235633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		volatile unsigned long *a = addr;
236633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long mask;
237633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long flags;
238633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
239633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		a += nr >> SZLONG_LOG;
240633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		mask = 1UL << bit;
241633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_save(flags);
242633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		*a ^= mask;
243633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_restore(flags);
244633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
245633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
246633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
247633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
248633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_set_bit - Set a bit and return its old value
249633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to set
250633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from
251633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
252633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and cannot be reordered.
253633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * It also implies a memory barrier.
254633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
255633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_set_bit(unsigned long nr,
256633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	volatile unsigned long *addr)
257633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
258633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned short bit = nr & SZLONG_MASK;
259633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long res;
260633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
261633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_llsc_mb();
262633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
263633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (cpu_has_llsc && R10000_LLSC_WAR) {
264633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
265633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
266633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
267633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
268633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
269633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
270633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%2, %0, %3				\n"
271633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%2, %1					\n"
272633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqzl	%2, 1b					\n"
273633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	and	%2, %0, %3				\n"
274633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
275633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
276633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
277633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
278633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (cpu_has_llsc) {
279633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
280633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
281633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
282633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
283633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	push					\n"
284633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	noreorder				\n"
285633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
286633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
287633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%2, %0, %3				\n"
288633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%2, %1					\n"
289633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%2, 2f					\n"
290633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 and	%2, %0, %3				\n"
291633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
292633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
293633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 nop						\n"
294633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
295633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	pop					\n"
296633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
297633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
298633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
299633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else {
300633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		volatile unsigned long *a = addr;
301633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long mask;
302633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long flags;
303633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
304633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		a += nr >> SZLONG_LOG;
305633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		mask = 1UL << bit;
306633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_save(flags);
307633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		res = (mask & *a);
308633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		*a |= mask;
309633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_restore(flags);
310633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
311633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
312633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_llsc_mb();
313633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
314633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return res != 0;
315633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
316633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
317633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
318633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_set_bit_lock - Set a bit and return its old value
319633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to set
320633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from
321633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
322633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and implies acquire ordering semantics
323633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * after the memory operation.
324633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
325633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_set_bit_lock(unsigned long nr,
326633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	volatile unsigned long *addr)
327633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
328633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned short bit = nr & SZLONG_MASK;
329633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long res;
330633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
331633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (cpu_has_llsc && R10000_LLSC_WAR) {
332633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
333633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
334633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
335633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
336633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
337633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
338633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%2, %0, %3				\n"
339633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%2, %1					\n"
340633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqzl	%2, 1b					\n"
341633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	and	%2, %0, %3				\n"
342633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
343633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
344633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
345633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
346633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (cpu_has_llsc) {
347633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
348633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
349633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
350633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
351633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	push					\n"
352633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	noreorder				\n"
353633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
354633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL "%0, %1		# test_and_set_bit	\n"
355633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%2, %0, %3				\n"
356633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%2, %1					\n"
357633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%2, 2f					\n"
358633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 and	%2, %0, %3				\n"
359633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
360633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
361633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 nop						\n"
362633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
363633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	pop					\n"
364633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
365633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
366633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
367633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else {
368633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		volatile unsigned long *a = addr;
369633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long mask;
370633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long flags;
371633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
372633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		a += nr >> SZLONG_LOG;
373633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		mask = 1UL << bit;
374633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_save(flags);
375633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		res = (mask & *a);
376633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		*a |= mask;
377633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_restore(flags);
378633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
379633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
380633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_llsc_mb();
381633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
382633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return res != 0;
383633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
384633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
385633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_clear_bit - Clear a bit and return its old value
386633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear
387633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from
388633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
389633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and cannot be reordered.
390633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * It also implies a memory barrier.
391633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
392633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_clear_bit(unsigned long nr,
393633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	volatile unsigned long *addr)
394633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
395633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned short bit = nr & SZLONG_MASK;
396633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long res;
397633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
398633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_llsc_mb();
399633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
400633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (cpu_has_llsc && R10000_LLSC_WAR) {
401633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
402633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
403633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
404633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
405633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
406633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
407633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%2, %0, %3				\n"
408633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	xor	%2, %3					\n"
409633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC 	"%2, %1					\n"
410633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqzl	%2, 1b					\n"
411633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	and	%2, %0, %3				\n"
412633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
413633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
414633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
415633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
416633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_CPU_MIPSR2
417633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (__builtin_constant_p(nr)) {
418633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
419633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
420633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
421633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
422633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
423633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __EXT "%2, %0, %3, 1				\n"
424633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __INS	"%0, $0, %3, 1				\n"
425633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC 	"%0, %1					\n"
426633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%0, 2f					\n"
427633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
428633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
429633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
430633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
431633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "ir" (bit), "m" (*m)
432633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
433633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif
434633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (cpu_has_llsc) {
435633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
436633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
437633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
438633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
439633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	push					\n"
440633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	noreorder				\n"
441633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
442633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL	"%0, %1		# test_and_clear_bit	\n"
443633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	or	%2, %0, %3				\n"
444633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	xor	%2, %3					\n"
445633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC 	"%2, %1					\n"
446633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%2, 2f					\n"
447633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 and	%2, %0, %3				\n"
448633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
449633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
450633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 nop						\n"
451633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
452633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	pop					\n"
453633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
454633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
455633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
456633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else {
457633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		volatile unsigned long *a = addr;
458633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long mask;
459633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long flags;
460633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
461633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		a += nr >> SZLONG_LOG;
462633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		mask = 1UL << bit;
463633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_save(flags);
464633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		res = (mask & *a);
465633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		*a &= ~mask;
466633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_restore(flags);
467633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
468633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
469633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_llsc_mb();
470633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
471633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return res != 0;
472633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
473633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
474633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
475633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_change_bit - Change a bit and return its old value
476633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to change
477633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from
478633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
479633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and cannot be reordered.
480633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * It also implies a memory barrier.
481633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
482633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_change_bit(unsigned long nr,
483633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	volatile unsigned long *addr)
484633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
485633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned short bit = nr & SZLONG_MASK;
486633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	unsigned long res;
487633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
488633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_llsc_mb();
489633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
490633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (cpu_has_llsc && R10000_LLSC_WAR) {
491633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
492633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
493633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
494633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
495633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
496633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL	"%0, %1		# test_and_change_bit	\n"
497633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	xor	%2, %0, %3				\n"
498633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"%2, %1					\n"
499633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqzl	%2, 1b					\n"
500633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	and	%2, %0, %3				\n"
501633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips0					\n"
502633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
503633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
504633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
505633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else if (cpu_has_llsc) {
506633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
507633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long temp;
508633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
509633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__ __volatile__(
510633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	push					\n"
511633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	noreorder				\n"
512633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips3					\n"
513633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"1:	" __LL	"%0, %1		# test_and_change_bit	\n"
514633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	xor	%2, %0, %3				\n"
515633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	" __SC	"\t%2, %1				\n"
516633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	beqz	%2, 2f					\n"
517633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 and	%2, %0, %3				\n"
518633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.subsection 2					\n"
519633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"2:	b	1b					\n"
520633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	 nop						\n"
521633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.previous					\n"
522633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	pop					\n"
523633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=&r" (temp), "=m" (*m), "=&r" (res)
524633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (1UL << bit), "m" (*m)
525633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "memory");
526633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	} else {
527633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		volatile unsigned long *a = addr;
528633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long mask;
529633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		unsigned long flags;
530633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
531633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		a += nr >> SZLONG_LOG;
532633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		mask = 1UL << bit;
533633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_save(flags);
534633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		res = (mask & *a);
535633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		*a ^= mask;
536633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		raw_local_irq_restore(flags);
537633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
538633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
539633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_llsc_mb();
540633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
541633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return res != 0;
542633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
543633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
544633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/non-atomic.h>
545633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
546633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
547633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * __clear_bit_unlock - Clears a bit in memory
548633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear
549633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from
550633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
551633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * __clear_bit() is non-atomic and implies release semantics before the memory
552633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * operation. It can be used for an unlock if no other CPUs can concurrently
553633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * modify other bits in the word.
554633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
555633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
556633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
557633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	smp_mb();
558633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	__clear_bit(nr, addr);
559633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
560633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
561633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
562633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
563633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
564633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Return the bit position (0..63) of the most significant 1 bit in a word
565633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Returns -1 if no 1 bit exists
566633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
567633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline unsigned long __fls(unsigned long x)
568633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
569633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	int lz;
570633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
571633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (sizeof(x) == 4) {
572633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		__asm__(
573633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	push					\n"
574633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	mips32					\n"
575633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	clz	%0, %1					\n"
576633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		"	.set	pop					\n"
577633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "=r" (lz)
578633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		: "r" (x));
579633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
580633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		return 31 - lz;
581633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	}
582633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
583633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	BUG_ON(sizeof(x) != 8);
584633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
585633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	__asm__(
586633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	"	.set	push						\n"
587633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	"	.set	mips64						\n"
588633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	"	dclz	%0, %1						\n"
589633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	"	.set	pop						\n"
590633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	: "=r" (lz)
591633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	: "r" (x));
592633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
593633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return 63 - lz;
594633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
595633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
596633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
597633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * __ffs - find first bit in word.
598633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @word: The word to search
599633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
600633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Returns 0..SZLONG-1
601633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Undefined if no bit exists, so code should check against 0 first.
602633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
603633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline unsigned long __ffs(unsigned long word)
604633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
605633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return __fls(word & -word);
606633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
607633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
608633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
609633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * fls - find last bit set.
610633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @word: The word to search
611633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
612633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This is defined the same way as ffs.
613633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
614633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
615633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int fls(int word)
616633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
617633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	__asm__("clz %0, %1" : "=r" (word) : "r" (word));
618633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
619633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return 32 - word;
620633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
621633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
622633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPS64)
623633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int fls64(__u64 word)
624633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
625633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	__asm__("dclz %0, %1" : "=r" (word) : "r" (word));
626633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
627633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return 64 - word;
628633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
629633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#else
630633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/fls64.h>
631633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif
632633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
633633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/*
634633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * ffs - find first bit set.
635633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @word: The word to search
636633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *
637633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This is defined the same way as
638633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * the libc and compiler builtin ffs routines, therefore
639633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * differs in spirit from the above ffz (man ffs).
640633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */
641633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int ffs(int word)
642633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{
643633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	if (!word)
644633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham		return 0;
645633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
646633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham	return fls(word & -word);
647633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham}
648633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
649633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#else
650633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
651633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/__ffs.h>
652633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/__fls.h>
653633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ffs.h>
654633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/fls.h>
655633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/fls64.h>
656633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
657633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /*defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) */
658633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
659633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ffz.h>
660633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/find.h>
661633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
662633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef __KERNEL__
663633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
664633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/sched.h>
665633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/hweight.h>
666633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ext2-non-atomic.h>
667633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ext2-atomic.h>
668633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/minix.h>
669633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
670633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* __KERNEL__ */
671633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham
672633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* _ASM_BITOPS_H */
673