diff options
author | Nick Piggin <npiggin@suse.de> | 2007-10-18 06:06:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-18 17:37:29 -0400 |
commit | 66ffb04ca5ec43ca763e8a9802ca3244f5519ae1 (patch) | |
tree | 26df9afbce84c5f478044de16f90a80fc182bd61 | |
parent | 728697cd6b3c8c12d0ad5ebdce5616ef5d25bf18 (diff) |
powerpc: lock bitops
Add non-trivial lock bitops implementation for powerpc.
Signed-off-by: Nick Piggin <npiggin@suse.de>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | include/asm-powerpc/bitops.h | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h index 1d4c16613d2f..e85c3e078ba2 100644 --- a/include/asm-powerpc/bitops.h +++ b/include/asm-powerpc/bitops.h | |||
@@ -86,6 +86,24 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr) | |||
86 | : "cc" ); | 86 | : "cc" ); |
87 | } | 87 | } |
88 | 88 | ||
89 | static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr) | ||
90 | { | ||
91 | unsigned long old; | ||
92 | unsigned long mask = BITOP_MASK(nr); | ||
93 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | ||
94 | |||
95 | __asm__ __volatile__( | ||
96 | LWSYNC_ON_SMP | ||
97 | "1:" PPC_LLARX "%0,0,%3 # clear_bit_unlock\n" | ||
98 | "andc %0,%0,%2\n" | ||
99 | PPC405_ERR77(0,%3) | ||
100 | PPC_STLCX "%0,0,%3\n" | ||
101 | "bne- 1b" | ||
102 | : "=&r" (old), "+m" (*p) | ||
103 | : "r" (mask), "r" (p) | ||
104 | : "cc", "memory"); | ||
105 | } | ||
106 | |||
89 | static __inline__ void change_bit(int nr, volatile unsigned long *addr) | 107 | static __inline__ void change_bit(int nr, volatile unsigned long *addr) |
90 | { | 108 | { |
91 | unsigned long old; | 109 | unsigned long old; |
@@ -125,6 +143,27 @@ static __inline__ int test_and_set_bit(unsigned long nr, | |||
125 | return (old & mask) != 0; | 143 | return (old & mask) != 0; |
126 | } | 144 | } |
127 | 145 | ||
146 | static __inline__ int test_and_set_bit_lock(unsigned long nr, | ||
147 | volatile unsigned long *addr) | ||
148 | { | ||
149 | unsigned long old, t; | ||
150 | unsigned long mask = BITOP_MASK(nr); | ||
151 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | ||
152 | |||
153 | __asm__ __volatile__( | ||
154 | "1:" PPC_LLARX "%0,0,%3 # test_and_set_bit_lock\n" | ||
155 | "or %1,%0,%2 \n" | ||
156 | PPC405_ERR77(0,%3) | ||
157 | PPC_STLCX "%1,0,%3 \n" | ||
158 | "bne- 1b" | ||
159 | ISYNC_ON_SMP | ||
160 | : "=&r" (old), "=&r" (t) | ||
161 | : "r" (mask), "r" (p) | ||
162 | : "cc", "memory"); | ||
163 | |||
164 | return (old & mask) != 0; | ||
165 | } | ||
166 | |||
128 | static __inline__ int test_and_clear_bit(unsigned long nr, | 167 | static __inline__ int test_and_clear_bit(unsigned long nr, |
129 | volatile unsigned long *addr) | 168 | volatile unsigned long *addr) |
130 | { | 169 | { |
@@ -185,6 +224,12 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr) | |||
185 | 224 | ||
186 | #include <asm-generic/bitops/non-atomic.h> | 225 | #include <asm-generic/bitops/non-atomic.h> |
187 | 226 | ||
227 | static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr) | ||
228 | { | ||
229 | __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory"); | ||
230 | __clear_bit(nr, addr); | ||
231 | } | ||
232 | |||
188 | /* | 233 | /* |
189 | * Return the zero-based bit position (LE, not IBM bit numbering) of | 234 | * Return the zero-based bit position (LE, not IBM bit numbering) of |
190 | * the most significant 1-bit in a double word. | 235 | * the most significant 1-bit in a double word. |
@@ -266,7 +311,6 @@ static __inline__ int fls(unsigned int x) | |||
266 | #include <asm-generic/bitops/fls64.h> | 311 | #include <asm-generic/bitops/fls64.h> |
267 | 312 | ||
268 | #include <asm-generic/bitops/hweight.h> | 313 | #include <asm-generic/bitops/hweight.h> |
269 | #include <asm-generic/bitops/lock.h> | ||
270 | 314 | ||
271 | #define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0) | 315 | #define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0) |
272 | unsigned long find_next_zero_bit(const unsigned long *addr, | 316 | unsigned long find_next_zero_bit(const unsigned long *addr, |