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