1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_SPINLOCK_LOCK1_H
3 #define __ASM_SPINLOCK_LOCK1_H
6 #include <asm/global_lock.h>
8 static inline int arch_spin_is_locked(arch_spinlock_t *lock)
14 WARN_ON(ret != 0 && ret != 1);
18 static inline void arch_spin_lock(arch_spinlock_t *lock)
20 unsigned int we_won = 0;
24 __global_lock1(flags);
25 if (lock->lock == 0) {
30 __global_unlock1(flags);
33 WARN_ON(lock->lock != 1);
36 /* Returns 0 if failed to acquire lock */
37 static inline int arch_spin_trylock(arch_spinlock_t *lock)
42 __global_lock1(flags);
48 __global_unlock1(flags);
52 static inline void arch_spin_unlock(arch_spinlock_t *lock)
63 * Write locks are easy - we just set bit 31. When unlocking, we can
64 * just write zero since the lock is exclusively held.
67 static inline void arch_write_lock(arch_rwlock_t *rw)
70 unsigned int we_won = 0;
73 __global_lock1(flags);
76 rw->lock = 0x80000000;
79 __global_unlock1(flags);
82 WARN_ON(rw->lock != 0x80000000);
85 static inline int arch_write_trylock(arch_rwlock_t *rw)
90 __global_lock1(flags);
94 rw->lock = 0x80000000;
96 __global_unlock1(flags);
101 static inline void arch_write_unlock(arch_rwlock_t *rw)
104 WARN_ON(rw->lock != 0x80000000);
108 /* write_can_lock - would write_trylock() succeed? */
109 static inline int arch_write_can_lock(arch_rwlock_t *rw)
119 * Read locks are a bit more hairy:
120 * - Exclusively load the lock value.
122 * - Store new lock value if positive, and we still own this location.
123 * If the value is negative, we've already failed.
124 * - If we failed to store the value, we want a negative result.
125 * - If we failed, try again.
126 * Unlocking is similarly hairy. We may have multiple read locks
127 * currently active. However, we know we won't have any write
130 static inline void arch_read_lock(arch_rwlock_t *rw)
133 unsigned int we_won = 0, ret;
136 __global_lock1(flags);
138 if (ret < 0x80000000) {
143 __global_unlock1(flags);
148 static inline void arch_read_unlock(arch_rwlock_t *rw)
153 __global_lock1(flags);
156 __global_unlock1(flags);
160 static inline int arch_read_trylock(arch_rwlock_t *rw)
165 __global_lock1(flags);
167 if (ret < 0x80000000) {
171 __global_unlock1(flags);
172 return (ret < 0x80000000);
175 /* read_can_lock - would read_trylock() succeed? */
176 static inline int arch_read_can_lock(arch_rwlock_t *rw)
182 return (ret < 0x80000000);
185 #endif /* __ASM_SPINLOCK_LOCK1_H */