Linux 3.11-rc3
[cris-mirror.git] / arch / xtensa / include / asm / spinlock.h
blob03975906b36fc34dc6a47abbe979c899ddc4f3e0
1 /*
2 * include/asm-xtensa/spinlock.h
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
8 * Copyright (C) 2001 - 2005 Tensilica Inc.
9 */
11 #ifndef _XTENSA_SPINLOCK_H
12 #define _XTENSA_SPINLOCK_H
15 * spinlock
17 * There is at most one owner of a spinlock. There are not different
18 * types of spinlock owners like there are for rwlocks (see below).
20 * When trying to obtain a spinlock, the function "spins" forever, or busy-
21 * waits, until the lock is obtained. When spinning, presumably some other
22 * owner will soon give up the spinlock making it available to others. Use
23 * the trylock functions to avoid spinning forever.
25 * possible values:
27 * 0 nobody owns the spinlock
28 * 1 somebody owns the spinlock
31 #define __raw_spin_is_locked(x) ((x)->slock != 0)
32 #define __raw_spin_unlock_wait(lock) \
33 do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
35 #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
37 static inline void __raw_spin_lock(raw_spinlock_t *lock)
39 unsigned long tmp;
41 __asm__ __volatile__(
42 " movi %0, 0\n"
43 " wsr %0, scompare1\n"
44 "1: movi %0, 1\n"
45 " s32c1i %0, %1, 0\n"
46 " bnez %0, 1b\n"
47 : "=&a" (tmp)
48 : "a" (&lock->slock)
49 : "memory");
52 /* Returns 1 if the lock is obtained, 0 otherwise. */
54 static inline int __raw_spin_trylock(raw_spinlock_t *lock)
56 unsigned long tmp;
58 __asm__ __volatile__(
59 " movi %0, 0\n"
60 " wsr %0, scompare1\n"
61 " movi %0, 1\n"
62 " s32c1i %0, %1, 0\n"
63 : "=&a" (tmp)
64 : "a" (&lock->slock)
65 : "memory");
67 return tmp == 0 ? 1 : 0;
70 static inline void __raw_spin_unlock(raw_spinlock_t *lock)
72 unsigned long tmp;
74 __asm__ __volatile__(
75 " movi %0, 0\n"
76 " s32ri %0, %1, 0\n"
77 : "=&a" (tmp)
78 : "a" (&lock->slock)
79 : "memory");
83 * rwlock
85 * Read-write locks are really a more flexible spinlock. They allow
86 * multiple readers but only one writer. Write ownership is exclusive
87 * (i.e., all other readers and writers are blocked from ownership while
88 * there is a write owner). These rwlocks are unfair to writers. Writers
89 * can be starved for an indefinite time by readers.
91 * possible values:
93 * 0 nobody owns the rwlock
94 * >0 one or more readers own the rwlock
95 * (the positive value is the actual number of readers)
96 * 0x80000000 one writer owns the rwlock, no other writers, no readers
99 #define __raw_write_can_lock(x) ((x)->lock == 0)
101 static inline void __raw_write_lock(raw_rwlock_t *rw)
103 unsigned long tmp;
105 __asm__ __volatile__(
106 " movi %0, 0\n"
107 " wsr %0, scompare1\n"
108 "1: movi %0, 1\n"
109 " slli %0, %0, 31\n"
110 " s32c1i %0, %1, 0\n"
111 " bnez %0, 1b\n"
112 : "=&a" (tmp)
113 : "a" (&rw->lock)
114 : "memory");
117 /* Returns 1 if the lock is obtained, 0 otherwise. */
119 static inline int __raw_write_trylock(raw_rwlock_t *rw)
121 unsigned long tmp;
123 __asm__ __volatile__(
124 " movi %0, 0\n"
125 " wsr %0, scompare1\n"
126 " movi %0, 1\n"
127 " slli %0, %0, 31\n"
128 " s32c1i %0, %1, 0\n"
129 : "=&a" (tmp)
130 : "a" (&rw->lock)
131 : "memory");
133 return tmp == 0 ? 1 : 0;
136 static inline void __raw_write_unlock(raw_rwlock_t *rw)
138 unsigned long tmp;
140 __asm__ __volatile__(
141 " movi %0, 0\n"
142 " s32ri %0, %1, 0\n"
143 : "=&a" (tmp)
144 : "a" (&rw->lock)
145 : "memory");
148 static inline void __raw_read_lock(raw_rwlock_t *rw)
150 unsigned long tmp;
151 unsigned long result;
153 __asm__ __volatile__(
154 "1: l32i %1, %2, 0\n"
155 " bltz %1, 1b\n"
156 " wsr %1, scompare1\n"
157 " addi %0, %1, 1\n"
158 " s32c1i %0, %2, 0\n"
159 " bne %0, %1, 1b\n"
160 : "=&a" (result), "=&a" (tmp)
161 : "a" (&rw->lock)
162 : "memory");
165 /* Returns 1 if the lock is obtained, 0 otherwise. */
167 static inline int __raw_read_trylock(raw_rwlock_t *rw)
169 unsigned long result;
170 unsigned long tmp;
172 __asm__ __volatile__(
173 " l32i %1, %2, 0\n"
174 " addi %0, %1, 1\n"
175 " bltz %0, 1f\n"
176 " wsr %1, scompare1\n"
177 " s32c1i %0, %2, 0\n"
178 " sub %0, %0, %1\n"
179 "1:\n"
180 : "=&a" (result), "=&a" (tmp)
181 : "a" (&rw->lock)
182 : "memory");
184 return result == 0;
187 static inline void __raw_read_unlock(raw_rwlock_t *rw)
189 unsigned long tmp1, tmp2;
191 __asm__ __volatile__(
192 "1: l32i %1, %2, 0\n"
193 " addi %0, %1, -1\n"
194 " wsr %1, scompare1\n"
195 " s32c1i %0, %2, 0\n"
196 " bne %0, %1, 1b\n"
197 : "=&a" (tmp1), "=&a" (tmp2)
198 : "a" (&rw->lock)
199 : "memory");
202 #endif /* _XTENSA_SPINLOCK_H */