1024b246eSLinus Torvalds #ifndef _ALPHA_SPINLOCK_H 2024b246eSLinus Torvalds #define _ALPHA_SPINLOCK_H 3024b246eSLinus Torvalds 4024b246eSLinus Torvalds #include <linux/kernel.h> 5024b246eSLinus Torvalds #include <asm/current.h> 6024b246eSLinus Torvalds 7024b246eSLinus Torvalds /* 8024b246eSLinus Torvalds * Simple spin lock operations. There are two variants, one clears IRQ's 9024b246eSLinus Torvalds * on the local processor, one does not. 10024b246eSLinus Torvalds * 11024b246eSLinus Torvalds * We make no fairness assumptions. They have a cost. 12024b246eSLinus Torvalds */ 13024b246eSLinus Torvalds 140199c4e6SThomas Gleixner #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) 150199c4e6SThomas Gleixner #define arch_spin_is_locked(x) ((x)->lock != 0) 160199c4e6SThomas Gleixner #define arch_spin_unlock_wait(x) \ 17024b246eSLinus Torvalds do { cpu_relax(); } while ((x)->lock) 18024b246eSLinus Torvalds 19*8f8dcb3fSMatt Turner static inline int arch_spin_value_unlocked(arch_spinlock_t lock) 20*8f8dcb3fSMatt Turner { 21*8f8dcb3fSMatt Turner return lock.lock == 0; 22*8f8dcb3fSMatt Turner } 23*8f8dcb3fSMatt Turner 240199c4e6SThomas Gleixner static inline void arch_spin_unlock(arch_spinlock_t * lock) 25024b246eSLinus Torvalds { 26024b246eSLinus Torvalds mb(); 27024b246eSLinus Torvalds lock->lock = 0; 28024b246eSLinus Torvalds } 29024b246eSLinus Torvalds 300199c4e6SThomas Gleixner static inline void arch_spin_lock(arch_spinlock_t * lock) 31024b246eSLinus Torvalds { 32024b246eSLinus Torvalds long tmp; 33024b246eSLinus Torvalds 34024b246eSLinus Torvalds __asm__ __volatile__( 35024b246eSLinus Torvalds "1: ldl_l %0,%1\n" 36024b246eSLinus Torvalds " bne %0,2f\n" 37024b246eSLinus Torvalds " lda %0,1\n" 38024b246eSLinus Torvalds " stl_c %0,%1\n" 39024b246eSLinus Torvalds " beq %0,2f\n" 40024b246eSLinus Torvalds " mb\n" 41024b246eSLinus Torvalds ".subsection 2\n" 42024b246eSLinus Torvalds "2: ldl %0,%1\n" 43024b246eSLinus Torvalds " bne %0,2b\n" 44024b246eSLinus Torvalds " br 1b\n" 45024b246eSLinus Torvalds ".previous" 46024b246eSLinus Torvalds : "=&r" (tmp), "=m" (lock->lock) 47024b246eSLinus Torvalds : "m"(lock->lock) : "memory"); 48024b246eSLinus Torvalds } 49024b246eSLinus Torvalds 500199c4e6SThomas Gleixner static inline int arch_spin_trylock(arch_spinlock_t *lock) 51024b246eSLinus Torvalds { 52024b246eSLinus Torvalds return !test_and_set_bit(0, &lock->lock); 53024b246eSLinus Torvalds } 54024b246eSLinus Torvalds 55024b246eSLinus Torvalds /***********************************************************/ 56024b246eSLinus Torvalds 57e5931943SThomas Gleixner static inline int arch_read_can_lock(arch_rwlock_t *lock) 58024b246eSLinus Torvalds { 59024b246eSLinus Torvalds return (lock->lock & 1) == 0; 60024b246eSLinus Torvalds } 61024b246eSLinus Torvalds 62e5931943SThomas Gleixner static inline int arch_write_can_lock(arch_rwlock_t *lock) 63024b246eSLinus Torvalds { 64024b246eSLinus Torvalds return lock->lock == 0; 65024b246eSLinus Torvalds } 66024b246eSLinus Torvalds 67e5931943SThomas Gleixner static inline void arch_read_lock(arch_rwlock_t *lock) 68024b246eSLinus Torvalds { 69024b246eSLinus Torvalds long regx; 70024b246eSLinus Torvalds 71024b246eSLinus Torvalds __asm__ __volatile__( 72024b246eSLinus Torvalds "1: ldl_l %1,%0\n" 73024b246eSLinus Torvalds " blbs %1,6f\n" 74024b246eSLinus Torvalds " subl %1,2,%1\n" 75024b246eSLinus Torvalds " stl_c %1,%0\n" 76024b246eSLinus Torvalds " beq %1,6f\n" 77024b246eSLinus Torvalds " mb\n" 78024b246eSLinus Torvalds ".subsection 2\n" 79024b246eSLinus Torvalds "6: ldl %1,%0\n" 80024b246eSLinus Torvalds " blbs %1,6b\n" 81024b246eSLinus Torvalds " br 1b\n" 82024b246eSLinus Torvalds ".previous" 83024b246eSLinus Torvalds : "=m" (*lock), "=&r" (regx) 84024b246eSLinus Torvalds : "m" (*lock) : "memory"); 85024b246eSLinus Torvalds } 86024b246eSLinus Torvalds 87e5931943SThomas Gleixner static inline void arch_write_lock(arch_rwlock_t *lock) 88024b246eSLinus Torvalds { 89024b246eSLinus Torvalds long regx; 90024b246eSLinus Torvalds 91024b246eSLinus Torvalds __asm__ __volatile__( 92024b246eSLinus Torvalds "1: ldl_l %1,%0\n" 93024b246eSLinus Torvalds " bne %1,6f\n" 94024b246eSLinus Torvalds " lda %1,1\n" 95024b246eSLinus Torvalds " stl_c %1,%0\n" 96024b246eSLinus Torvalds " beq %1,6f\n" 97024b246eSLinus Torvalds " mb\n" 98024b246eSLinus Torvalds ".subsection 2\n" 99024b246eSLinus Torvalds "6: ldl %1,%0\n" 100024b246eSLinus Torvalds " bne %1,6b\n" 101024b246eSLinus Torvalds " br 1b\n" 102024b246eSLinus Torvalds ".previous" 103024b246eSLinus Torvalds : "=m" (*lock), "=&r" (regx) 104024b246eSLinus Torvalds : "m" (*lock) : "memory"); 105024b246eSLinus Torvalds } 106024b246eSLinus Torvalds 107e5931943SThomas Gleixner static inline int arch_read_trylock(arch_rwlock_t * lock) 108024b246eSLinus Torvalds { 109024b246eSLinus Torvalds long regx; 110024b246eSLinus Torvalds int success; 111024b246eSLinus Torvalds 112024b246eSLinus Torvalds __asm__ __volatile__( 113024b246eSLinus Torvalds "1: ldl_l %1,%0\n" 114024b246eSLinus Torvalds " lda %2,0\n" 115024b246eSLinus Torvalds " blbs %1,2f\n" 116024b246eSLinus Torvalds " subl %1,2,%2\n" 117024b246eSLinus Torvalds " stl_c %2,%0\n" 118024b246eSLinus Torvalds " beq %2,6f\n" 119024b246eSLinus Torvalds "2: mb\n" 120024b246eSLinus Torvalds ".subsection 2\n" 121024b246eSLinus Torvalds "6: br 1b\n" 122024b246eSLinus Torvalds ".previous" 123024b246eSLinus Torvalds : "=m" (*lock), "=&r" (regx), "=&r" (success) 124024b246eSLinus Torvalds : "m" (*lock) : "memory"); 125024b246eSLinus Torvalds 126024b246eSLinus Torvalds return success; 127024b246eSLinus Torvalds } 128024b246eSLinus Torvalds 129e5931943SThomas Gleixner static inline int arch_write_trylock(arch_rwlock_t * lock) 130024b246eSLinus Torvalds { 131024b246eSLinus Torvalds long regx; 132024b246eSLinus Torvalds int success; 133024b246eSLinus Torvalds 134024b246eSLinus Torvalds __asm__ __volatile__( 135024b246eSLinus Torvalds "1: ldl_l %1,%0\n" 136024b246eSLinus Torvalds " lda %2,0\n" 137024b246eSLinus Torvalds " bne %1,2f\n" 138024b246eSLinus Torvalds " lda %2,1\n" 139024b246eSLinus Torvalds " stl_c %2,%0\n" 140024b246eSLinus Torvalds " beq %2,6f\n" 141024b246eSLinus Torvalds "2: mb\n" 142024b246eSLinus Torvalds ".subsection 2\n" 143024b246eSLinus Torvalds "6: br 1b\n" 144024b246eSLinus Torvalds ".previous" 145024b246eSLinus Torvalds : "=m" (*lock), "=&r" (regx), "=&r" (success) 146024b246eSLinus Torvalds : "m" (*lock) : "memory"); 147024b246eSLinus Torvalds 148024b246eSLinus Torvalds return success; 149024b246eSLinus Torvalds } 150024b246eSLinus Torvalds 151e5931943SThomas Gleixner static inline void arch_read_unlock(arch_rwlock_t * lock) 152024b246eSLinus Torvalds { 153024b246eSLinus Torvalds long regx; 154024b246eSLinus Torvalds __asm__ __volatile__( 155024b246eSLinus Torvalds " mb\n" 156024b246eSLinus Torvalds "1: ldl_l %1,%0\n" 157024b246eSLinus Torvalds " addl %1,2,%1\n" 158024b246eSLinus Torvalds " stl_c %1,%0\n" 159024b246eSLinus Torvalds " beq %1,6f\n" 160024b246eSLinus Torvalds ".subsection 2\n" 161024b246eSLinus Torvalds "6: br 1b\n" 162024b246eSLinus Torvalds ".previous" 163024b246eSLinus Torvalds : "=m" (*lock), "=&r" (regx) 164024b246eSLinus Torvalds : "m" (*lock) : "memory"); 165024b246eSLinus Torvalds } 166024b246eSLinus Torvalds 167e5931943SThomas Gleixner static inline void arch_write_unlock(arch_rwlock_t * lock) 168024b246eSLinus Torvalds { 169024b246eSLinus Torvalds mb(); 170024b246eSLinus Torvalds lock->lock = 0; 171024b246eSLinus Torvalds } 172024b246eSLinus Torvalds 173e5931943SThomas Gleixner #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) 174e5931943SThomas Gleixner #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) 175f5f7eac4SRobin Holt 176024b246eSLinus Torvalds #endif /* _ALPHA_SPINLOCK_H */ 177