1
2
3
4
5
6
7
8
9
10
11#ifndef _XTENSA_SPINLOCK_H
12#define _XTENSA_SPINLOCK_H
13
14#include <asm/barrier.h>
15#include <asm/processor.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#define arch_spin_is_locked(x) ((x)->slock != 0)
35
36static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
37{
38 smp_cond_load_acquire(&lock->slock, !VAL);
39}
40
41#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
42
43static inline void arch_spin_lock(arch_spinlock_t *lock)
44{
45 unsigned long tmp;
46
47 __asm__ __volatile__(
48 " movi %0, 0\n"
49 " wsr %0, scompare1\n"
50 "1: movi %0, 1\n"
51 " s32c1i %0, %1, 0\n"
52 " bnez %0, 1b\n"
53 : "=&a" (tmp)
54 : "a" (&lock->slock)
55 : "memory");
56}
57
58
59
60static inline int arch_spin_trylock(arch_spinlock_t *lock)
61{
62 unsigned long tmp;
63
64 __asm__ __volatile__(
65 " movi %0, 0\n"
66 " wsr %0, scompare1\n"
67 " movi %0, 1\n"
68 " s32c1i %0, %1, 0\n"
69 : "=&a" (tmp)
70 : "a" (&lock->slock)
71 : "memory");
72
73 return tmp == 0 ? 1 : 0;
74}
75
76static inline void arch_spin_unlock(arch_spinlock_t *lock)
77{
78 unsigned long tmp;
79
80 __asm__ __volatile__(
81 " movi %0, 0\n"
82 " s32ri %0, %1, 0\n"
83 : "=&a" (tmp)
84 : "a" (&lock->slock)
85 : "memory");
86}
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105#define arch_write_can_lock(x) ((x)->lock == 0)
106
107static inline void arch_write_lock(arch_rwlock_t *rw)
108{
109 unsigned long tmp;
110
111 __asm__ __volatile__(
112 " movi %0, 0\n"
113 " wsr %0, scompare1\n"
114 "1: movi %0, 1\n"
115 " slli %0, %0, 31\n"
116 " s32c1i %0, %1, 0\n"
117 " bnez %0, 1b\n"
118 : "=&a" (tmp)
119 : "a" (&rw->lock)
120 : "memory");
121}
122
123
124
125static inline int arch_write_trylock(arch_rwlock_t *rw)
126{
127 unsigned long tmp;
128
129 __asm__ __volatile__(
130 " movi %0, 0\n"
131 " wsr %0, scompare1\n"
132 " movi %0, 1\n"
133 " slli %0, %0, 31\n"
134 " s32c1i %0, %1, 0\n"
135 : "=&a" (tmp)
136 : "a" (&rw->lock)
137 : "memory");
138
139 return tmp == 0 ? 1 : 0;
140}
141
142static inline void arch_write_unlock(arch_rwlock_t *rw)
143{
144 unsigned long tmp;
145
146 __asm__ __volatile__(
147 " movi %0, 0\n"
148 " s32ri %0, %1, 0\n"
149 : "=&a" (tmp)
150 : "a" (&rw->lock)
151 : "memory");
152}
153
154static inline void arch_read_lock(arch_rwlock_t *rw)
155{
156 unsigned long tmp;
157 unsigned long result;
158
159 __asm__ __volatile__(
160 "1: l32i %1, %2, 0\n"
161 " bltz %1, 1b\n"
162 " wsr %1, scompare1\n"
163 " addi %0, %1, 1\n"
164 " s32c1i %0, %2, 0\n"
165 " bne %0, %1, 1b\n"
166 : "=&a" (result), "=&a" (tmp)
167 : "a" (&rw->lock)
168 : "memory");
169}
170
171
172
173static inline int arch_read_trylock(arch_rwlock_t *rw)
174{
175 unsigned long result;
176 unsigned long tmp;
177
178 __asm__ __volatile__(
179 " l32i %1, %2, 0\n"
180 " addi %0, %1, 1\n"
181 " bltz %0, 1f\n"
182 " wsr %1, scompare1\n"
183 " s32c1i %0, %2, 0\n"
184 " sub %0, %0, %1\n"
185 "1:\n"
186 : "=&a" (result), "=&a" (tmp)
187 : "a" (&rw->lock)
188 : "memory");
189
190 return result == 0;
191}
192
193static inline void arch_read_unlock(arch_rwlock_t *rw)
194{
195 unsigned long tmp1, tmp2;
196
197 __asm__ __volatile__(
198 "1: l32i %1, %2, 0\n"
199 " addi %0, %1, -1\n"
200 " wsr %1, scompare1\n"
201 " s32c1i %0, %2, 0\n"
202 " bne %0, %1, 1b\n"
203 : "=&a" (tmp1), "=&a" (tmp2)
204 : "a" (&rw->lock)
205 : "memory");
206}
207
208#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
209#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
210
211#endif
212