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