Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _ALPHA_SPINLOCK_H |
2 | #define _ALPHA_SPINLOCK_H | |
3 | ||
4 | #include <linux/config.h> | |
5 | #include <asm/system.h> | |
6 | #include <linux/kernel.h> | |
7 | #include <asm/current.h> | |
8 | ||
1da177e4 LT |
9 | /* |
10 | * Simple spin lock operations. There are two variants, one clears IRQ's | |
11 | * on the local processor, one does not. | |
12 | * | |
13 | * We make no fairness assumptions. They have a cost. | |
14 | */ | |
15 | ||
fb1c8f93 IM |
16 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) |
17 | #define __raw_spin_is_locked(x) ((x)->lock != 0) | |
18 | #define __raw_spin_unlock_wait(x) \ | |
19 | do { cpu_relax(); } while ((x)->lock) | |
20 | ||
21 | static inline void __raw_spin_unlock(raw_spinlock_t * lock) | |
1da177e4 LT |
22 | { |
23 | mb(); | |
24 | lock->lock = 0; | |
25 | } | |
26 | ||
fb1c8f93 | 27 | static inline void __raw_spin_lock(raw_spinlock_t * lock) |
1da177e4 LT |
28 | { |
29 | long tmp; | |
30 | ||
31 | __asm__ __volatile__( | |
32 | "1: ldl_l %0,%1\n" | |
33 | " bne %0,2f\n" | |
34 | " lda %0,1\n" | |
35 | " stl_c %0,%1\n" | |
36 | " beq %0,2f\n" | |
37 | " mb\n" | |
38 | ".subsection 2\n" | |
39 | "2: ldl %0,%1\n" | |
40 | " bne %0,2b\n" | |
41 | " br 1b\n" | |
42 | ".previous" | |
43 | : "=&r" (tmp), "=m" (lock->lock) | |
44 | : "m"(lock->lock) : "memory"); | |
45 | } | |
46 | ||
fb1c8f93 | 47 | static inline int __raw_spin_trylock(raw_spinlock_t *lock) |
1da177e4 LT |
48 | { |
49 | return !test_and_set_bit(0, &lock->lock); | |
50 | } | |
1da177e4 LT |
51 | |
52 | /***********************************************************/ | |
53 | ||
fb1c8f93 | 54 | static inline int __raw_read_can_lock(raw_rwlock_t *lock) |
1da177e4 LT |
55 | { |
56 | return (lock->lock & 1) == 0; | |
57 | } | |
58 | ||
fb1c8f93 | 59 | static inline int __raw_write_can_lock(raw_rwlock_t *lock) |
1da177e4 LT |
60 | { |
61 | return lock->lock == 0; | |
62 | } | |
63 | ||
fb1c8f93 | 64 | static inline void __raw_read_lock(raw_rwlock_t *lock) |
1da177e4 LT |
65 | { |
66 | long regx; | |
67 | ||
68 | __asm__ __volatile__( | |
69 | "1: ldl_l %1,%0\n" | |
fb1c8f93 IM |
70 | " blbs %1,6f\n" |
71 | " subl %1,2,%1\n" | |
1da177e4 LT |
72 | " stl_c %1,%0\n" |
73 | " beq %1,6f\n" | |
74 | " mb\n" | |
75 | ".subsection 2\n" | |
76 | "6: ldl %1,%0\n" | |
fb1c8f93 | 77 | " blbs %1,6b\n" |
1da177e4 LT |
78 | " br 1b\n" |
79 | ".previous" | |
80 | : "=m" (*lock), "=&r" (regx) | |
81 | : "m" (*lock) : "memory"); | |
82 | } | |
83 | ||
fb1c8f93 | 84 | static inline void __raw_write_lock(raw_rwlock_t *lock) |
1da177e4 LT |
85 | { |
86 | long regx; | |
87 | ||
88 | __asm__ __volatile__( | |
89 | "1: ldl_l %1,%0\n" | |
fb1c8f93 IM |
90 | " bne %1,6f\n" |
91 | " lda %1,1\n" | |
1da177e4 LT |
92 | " stl_c %1,%0\n" |
93 | " beq %1,6f\n" | |
94 | " mb\n" | |
95 | ".subsection 2\n" | |
96 | "6: ldl %1,%0\n" | |
fb1c8f93 | 97 | " bne %1,6b\n" |
1da177e4 LT |
98 | " br 1b\n" |
99 | ".previous" | |
100 | : "=m" (*lock), "=&r" (regx) | |
101 | : "m" (*lock) : "memory"); | |
102 | } | |
1da177e4 | 103 | |
fb1c8f93 | 104 | static inline int __raw_read_trylock(raw_rwlock_t * lock) |
1da177e4 LT |
105 | { |
106 | long regx; | |
107 | int success; | |
108 | ||
109 | __asm__ __volatile__( | |
110 | "1: ldl_l %1,%0\n" | |
111 | " lda %2,0\n" | |
112 | " blbs %1,2f\n" | |
113 | " subl %1,2,%2\n" | |
114 | " stl_c %2,%0\n" | |
115 | " beq %2,6f\n" | |
116 | "2: mb\n" | |
117 | ".subsection 2\n" | |
118 | "6: br 1b\n" | |
119 | ".previous" | |
120 | : "=m" (*lock), "=&r" (regx), "=&r" (success) | |
121 | : "m" (*lock) : "memory"); | |
122 | ||
123 | return success; | |
124 | } | |
125 | ||
fb1c8f93 | 126 | static inline int __raw_write_trylock(raw_rwlock_t * lock) |
1da177e4 LT |
127 | { |
128 | long regx; | |
129 | int success; | |
130 | ||
131 | __asm__ __volatile__( | |
132 | "1: ldl_l %1,%0\n" | |
133 | " lda %2,0\n" | |
134 | " bne %1,2f\n" | |
135 | " lda %2,1\n" | |
136 | " stl_c %2,%0\n" | |
137 | " beq %2,6f\n" | |
138 | "2: mb\n" | |
139 | ".subsection 2\n" | |
140 | "6: br 1b\n" | |
141 | ".previous" | |
142 | : "=m" (*lock), "=&r" (regx), "=&r" (success) | |
143 | : "m" (*lock) : "memory"); | |
144 | ||
145 | return success; | |
146 | } | |
147 | ||
fb1c8f93 | 148 | static inline void __raw_read_unlock(raw_rwlock_t * lock) |
1da177e4 LT |
149 | { |
150 | long regx; | |
151 | __asm__ __volatile__( | |
152 | " mb\n" | |
153 | "1: ldl_l %1,%0\n" | |
154 | " addl %1,2,%1\n" | |
155 | " stl_c %1,%0\n" | |
156 | " beq %1,6f\n" | |
157 | ".subsection 2\n" | |
158 | "6: br 1b\n" | |
159 | ".previous" | |
160 | : "=m" (*lock), "=&r" (regx) | |
161 | : "m" (*lock) : "memory"); | |
162 | } | |
163 | ||
fb1c8f93 IM |
164 | static inline void __raw_write_unlock(raw_rwlock_t * lock) |
165 | { | |
166 | mb(); | |
167 | lock->lock = 0; | |
168 | } | |
169 | ||
1da177e4 | 170 | #endif /* _ALPHA_SPINLOCK_H */ |