diff options
Diffstat (limited to 'include/asm-ia64/spinlock.h')
-rw-r--r-- | include/asm-ia64/spinlock.h | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h index 909936f25512..d2430aa0d49d 100644 --- a/include/asm-ia64/spinlock.h +++ b/include/asm-ia64/spinlock.h | |||
@@ -93,7 +93,15 @@ _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) | |||
93 | # endif /* CONFIG_MCKINLEY */ | 93 | # endif /* CONFIG_MCKINLEY */ |
94 | #endif | 94 | #endif |
95 | } | 95 | } |
96 | |||
96 | #define _raw_spin_lock(lock) _raw_spin_lock_flags(lock, 0) | 97 | #define _raw_spin_lock(lock) _raw_spin_lock_flags(lock, 0) |
98 | |||
99 | /* Unlock by doing an ordered store and releasing the cacheline with nta */ | ||
100 | static inline void _raw_spin_unlock(spinlock_t *x) { | ||
101 | barrier(); | ||
102 | asm volatile ("st4.rel.nta [%0] = r0\n\t" :: "r"(x)); | ||
103 | } | ||
104 | |||
97 | #else /* !ASM_SUPPORTED */ | 105 | #else /* !ASM_SUPPORTED */ |
98 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) | 106 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) |
99 | # define _raw_spin_lock(x) \ | 107 | # define _raw_spin_lock(x) \ |
@@ -109,16 +117,16 @@ do { \ | |||
109 | } while (ia64_spinlock_val); \ | 117 | } while (ia64_spinlock_val); \ |
110 | } \ | 118 | } \ |
111 | } while (0) | 119 | } while (0) |
120 | #define _raw_spin_unlock(x) do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0) | ||
112 | #endif /* !ASM_SUPPORTED */ | 121 | #endif /* !ASM_SUPPORTED */ |
113 | 122 | ||
114 | #define spin_is_locked(x) ((x)->lock != 0) | 123 | #define spin_is_locked(x) ((x)->lock != 0) |
115 | #define _raw_spin_unlock(x) do { barrier(); ((spinlock_t *) x)->lock = 0; } while (0) | ||
116 | #define _raw_spin_trylock(x) (cmpxchg_acq(&(x)->lock, 0, 1) == 0) | 124 | #define _raw_spin_trylock(x) (cmpxchg_acq(&(x)->lock, 0, 1) == 0) |
117 | #define spin_unlock_wait(x) do { barrier(); } while ((x)->lock) | 125 | #define spin_unlock_wait(x) do { barrier(); } while ((x)->lock) |
118 | 126 | ||
119 | typedef struct { | 127 | typedef struct { |
120 | volatile unsigned int read_counter : 31; | 128 | volatile unsigned int read_counter : 24; |
121 | volatile unsigned int write_lock : 1; | 129 | volatile unsigned int write_lock : 8; |
122 | #ifdef CONFIG_PREEMPT | 130 | #ifdef CONFIG_PREEMPT |
123 | unsigned int break_lock; | 131 | unsigned int break_lock; |
124 | #endif | 132 | #endif |
@@ -174,6 +182,13 @@ do { \ | |||
174 | (result == 0); \ | 182 | (result == 0); \ |
175 | }) | 183 | }) |
176 | 184 | ||
185 | static inline void _raw_write_unlock(rwlock_t *x) | ||
186 | { | ||
187 | u8 *y = (u8 *)x; | ||
188 | barrier(); | ||
189 | asm volatile ("st1.rel.nta [%0] = r0\n\t" :: "r"(y+3) : "memory" ); | ||
190 | } | ||
191 | |||
177 | #else /* !ASM_SUPPORTED */ | 192 | #else /* !ASM_SUPPORTED */ |
178 | 193 | ||
179 | #define _raw_write_lock(l) \ | 194 | #define _raw_write_lock(l) \ |
@@ -195,14 +210,14 @@ do { \ | |||
195 | (ia64_val == 0); \ | 210 | (ia64_val == 0); \ |
196 | }) | 211 | }) |
197 | 212 | ||
213 | static inline void _raw_write_unlock(rwlock_t *x) | ||
214 | { | ||
215 | barrier(); | ||
216 | x->write_lock = 0; | ||
217 | } | ||
218 | |||
198 | #endif /* !ASM_SUPPORTED */ | 219 | #endif /* !ASM_SUPPORTED */ |
199 | 220 | ||
200 | #define _raw_read_trylock(lock) generic_raw_read_trylock(lock) | 221 | #define _raw_read_trylock(lock) generic_raw_read_trylock(lock) |
201 | 222 | ||
202 | #define _raw_write_unlock(x) \ | ||
203 | ({ \ | ||
204 | smp_mb__before_clear_bit(); /* need barrier before releasing lock... */ \ | ||
205 | clear_bit(31, (x)); \ | ||
206 | }) | ||
207 | |||
208 | #endif /* _ASM_IA64_SPINLOCK_H */ | 223 | #endif /* _ASM_IA64_SPINLOCK_H */ |