1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ASM_SPINLOCK_H 2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ASM_SPINLOCK_H 3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if __LINUX_ARM_ARCH__ < 6 5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#error SMP not supported on pre-ARMv6 CPUs 6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * ARMv6 Spin-locking. 10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * We exclusively read the old value. If it is zero, we may have 12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * won the lock, so we try exclusively storing it. A memory barrier 13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * is required after we get a lock, and before we release it, because 14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * V6 CPUs are assumed to have weakly ordered memory. 15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Unlocked value: 0 17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Locked value: 1 18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __raw_spin_is_locked(x) ((x)->lock != 0) 21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __raw_spin_unlock_wait(lock) \ 22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) 23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) 25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_lock(raw_spinlock_t *lock) 27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long tmp; 29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru"1: ldrex %0, [%1]\n" 32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" teq %0, #0\n" 33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_CPU_32v6K 34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" wfene\n" 35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" strexeq %0, %2, [%1]\n" 37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" teqeq %0, #0\n" 38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" bne 1b" 39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (tmp) 40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&lock->lock), "r" (1) 41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_spin_trylock(raw_spinlock_t *lock) 47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long tmp; 49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" ldrex %0, [%1]\n" 52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" teq %0, #0\n" 53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" strexeq %0, %2, [%1]" 54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (tmp) 55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&lock->lock), "r" (1) 56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (tmp == 0) { 59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 1; 61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } else { 62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 0; 63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } 64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_unlock(raw_spinlock_t *lock) 67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" str %1, [%0]\n" 72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_CPU_32v6K 73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" mcr p15, 0, %1, c7, c10, 4\n" /* DSB */ 74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" sev" 75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : 77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&lock->lock), "r" (0) 78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * RWLOCKS 83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Write locks are easy - we just set bit 31. When unlocking, we can 86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * just write zero since the lock is exclusively held. 87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0) 89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_write_lock(raw_rwlock_t *rw) 91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long tmp; 93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru"1: ldrex %0, [%1]\n" 96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" teq %0, #0\n" 97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_CPU_32v6K 98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" wfene\n" 99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" strexeq %0, %2, [%1]\n" 101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" teq %0, #0\n" 102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" bne 1b" 103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (tmp) 104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&rw->lock), "r" (0x80000000) 105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_write_trylock(raw_rwlock_t *rw) 111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long tmp; 113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru"1: ldrex %0, [%1]\n" 116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" teq %0, #0\n" 117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" strexeq %0, %2, [%1]" 118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (tmp) 119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&rw->lock), "r" (0x80000000) 120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (tmp == 0) { 123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 1; 125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } else { 126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 0; 127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru } 128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_write_unlock(raw_rwlock_t *rw) 131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "str %1, [%0]\n" 136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_CPU_32v6K 137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" mcr p15, 0, %1, c7, c10, 4\n" /* DSB */ 138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" sev\n" 139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : 141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&rw->lock), "r" (0) 142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* write_can_lock - would write_trylock() succeed? */ 146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __raw_write_can_lock(x) ((x)->lock == 0x80000000) 147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Read locks are a bit more hairy: 150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * - Exclusively load the lock value. 151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * - Increment it. 152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * - Store new lock value if positive, and we still own this location. 153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * If the value is negative, we've already failed. 154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * - If we failed to store the value, we want a negative result. 155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * - If we failed, try again. 156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Unlocking is similarly hairy. We may have multiple read locks 157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * currently active. However, we know we won't have any write 158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * locks. 159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_read_lock(raw_rwlock_t *rw) 161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long tmp, tmp2; 163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru"1: ldrex %0, [%2]\n" 166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" adds %0, %0, #1\n" 167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" strexpl %1, %0, [%2]\n" 168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_CPU_32v6K 169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" wfemi\n" 170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" rsbpls %0, %1, #0\n" 172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" bmi 1b" 173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (tmp), "=&r" (tmp2) 174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&rw->lock) 175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_read_unlock(raw_rwlock_t *rw) 181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long tmp, tmp2; 183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru"1: ldrex %0, [%2]\n" 188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" sub %0, %0, #1\n" 189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" strex %1, %0, [%2]\n" 190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" teq %1, #0\n" 191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" bne 1b" 192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_CPU_32v6K 193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru"\n cmp %0, #0\n" 194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" mcreq p15, 0, %0, c7, c10, 4\n" 195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" seveq" 196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (tmp), "=&r" (tmp2) 198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&rw->lock) 199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_read_trylock(raw_rwlock_t *rw) 203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru unsigned long tmp, tmp2 = 1; 205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru __asm__ __volatile__( 207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru"1: ldrex %0, [%2]\n" 208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" adds %0, %0, #1\n" 209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru" strexpl %1, %0, [%2]\n" 210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=&r" (tmp), "+r" (tmp2) 211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "r" (&rw->lock) 212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "cc"); 213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru smp_mb(); 215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return tmp2 == 0; 216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* read_can_lock - would read_trylock() succeed? */ 219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __raw_read_can_lock(x) ((x)->lock < 0x80000000) 220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __ASM_SPINLOCK_H */ 222