1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ASM_SPINLOCK_H
2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ASM_SPINLOCK_H
3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/atomic.h>
5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/rwlock.h>
6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/page.h>
7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/processor.h>
8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/compiler.h>
9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_PARAVIRT
11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/paravirt.h>
12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CLI_STRING	"cli"
14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define STI_STRING	"sti"
15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CLI_STI_CLOBBERS
16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CLI_STI_INPUT_ARGS
17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* CONFIG_PARAVIRT */
18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Your basic SMP spinlocks, allowing only a single CPU anywhere
21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Simple spin lock operations.  There are two variants, one clears IRQ's
23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * on the local processor, one does not.
24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * We make no fairness assumptions. They have a cost.
26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (the type definitions are in asm/spinlock_types.h)
28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_spin_is_locked(raw_spinlock_t *x)
31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return *(volatile signed char *)(&(x)->slock) <= 0;
33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_lock(raw_spinlock_t *lock)
36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile("\n1:\t"
38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     LOCK_PREFIX " ; decb %0\n\t"
39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "jns 3f\n"
40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "2:\t"
41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "rep;nop\n\t"
42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "cmpb $0,%0\n\t"
43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "jle 2b\n\t"
44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "jmp 1b\n"
45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "3:\n\t"
46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     : "+m" (lock->slock) : : "memory");
47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * It is easier for the lock validator if interrupts are not re-enabled
51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * in the middle of a lock-acquire. This is a performance feature anyway
52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * so we turn it off:
53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * NOTE: there's an irqs-on section here, which normally would have to be
55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant.
56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef CONFIG_PROVE_LOCKING
58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile(
61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"\n1:\t"
62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		LOCK_PREFIX " ; decb %[slock]\n\t"
63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"jns 5f\n"
64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"2:\t"
65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"testl $0x200, %[flags]\n\t"
66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"jz 4f\n\t"
67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		STI_STRING "\n"
68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"3:\t"
69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"rep;nop\n\t"
70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"cmpb $0, %[slock]\n\t"
71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"jle 3b\n\t"
72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		CLI_STRING "\n\t"
73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"jmp 1b\n"
74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"4:\t"
75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"rep;nop\n\t"
76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"cmpb $0, %[slock]\n\t"
77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"jg 1b\n\t"
78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"jmp 4b\n"
79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"5:\n\t"
80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: [slock] "+m" (lock->slock)
81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: [flags] "r" (flags)
82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	 	  CLI_STI_INPUT_ARGS
83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "memory" CLI_STI_CLOBBERS);
84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_spin_trylock(raw_spinlock_t *lock)
88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	char oldval;
90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile(
91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"xchgb %b0,%1"
92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		:"=q" (oldval), "+m" (lock->slock)
93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		:"0" (0) : "memory");
94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return oldval > 0;
95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * __raw_spin_unlock based on writing $1 to the low byte.
99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This method works. Despite all the confusion.
100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there)
101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (PPro errata 66, 92)
102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)
105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_unlock(raw_spinlock_t *lock)
107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile("movb $1,%0" : "+m" (lock->slock) :: "memory");
109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_unlock(raw_spinlock_t *lock)
114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	char oldval = 1;
116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile("xchgb %b0, %1"
118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     : "=q" (oldval), "+m" (lock->slock)
119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     : "0" (oldval) : "memory");
120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_unlock_wait(raw_spinlock_t *lock)
125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	while (__raw_spin_is_locked(lock))
127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		cpu_relax();
128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Read-write spinlocks, allowing multiple readers
132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * but only one writer.
133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * NOTE! it is quite common to have readers in interrupts
135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * but no interrupt writers. For those circumstances we
136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * can "mix" irq-safe locks - any writer needs to get a
137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * irq-safe write-lock, but readers can get non-irqsafe
138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * read-locks.
139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * On x86, we implement read-write locks as a 32-bit counter
141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * with the high bit (sign) being the "contended" bit.
142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The inline assembly is non-obvious. Think about it.
144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Changed to use the same technique as rw semaphores.  See
146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * semaphore.h for details.  -ben
147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the helpers are in arch/i386/kernel/semaphore.c
149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/**
152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * read_can_lock - would read_trylock() succeed?
153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * @lock: the rwlock in question.
154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_read_can_lock(raw_rwlock_t *x)
156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return (int)(x)->lock > 0;
158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/**
161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * write_can_lock - would write_trylock() succeed?
162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * @lock: the rwlock in question.
163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_write_can_lock(raw_rwlock_t *x)
165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return (x)->lock == RW_LOCK_BIAS;
167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_read_lock(raw_rwlock_t *rw)
170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "jns 1f\n"
173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "call __read_lock_failed\n\t"
174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "1:\n"
175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     ::"a" (rw) : "memory");
176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_write_lock(raw_rwlock_t *rw)
179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",(%0)\n\t"
181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "jz 1f\n"
182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "call __write_lock_failed\n\t"
183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     "1:\n"
184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		     ::"a" (rw) : "memory");
185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_read_trylock(raw_rwlock_t *lock)
188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	atomic_t *count = (atomic_t *)lock;
190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	atomic_dec(count);
191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (atomic_read(count) >= 0)
192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		return 1;
193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	atomic_inc(count);
194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return 0;
195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_write_trylock(raw_rwlock_t *lock)
198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	atomic_t *count = (atomic_t *)lock;
200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (atomic_sub_and_test(RW_LOCK_BIAS, count))
201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		return 1;
202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	atomic_add(RW_LOCK_BIAS, count);
203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return 0;
204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_read_unlock(raw_rwlock_t *rw)
207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_write_unlock(raw_rwlock_t *rw)
212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ", %0"
214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru				 : "+m" (rw->lock) : : "memory");
215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _raw_spin_relax(lock)	cpu_relax()
218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _raw_read_relax(lock)	cpu_relax()
219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _raw_write_relax(lock)	cpu_relax()
220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __ASM_SPINLOCK_H */
222