From: Russell King Date: Sun, 24 Jul 2005 11:13:40 +0000 (+0100) Subject: [PATCH] ARM SMP: Fix ARMv6 spinlock and semaphore implementations X-Git-Tag: v2.6.13-rc4~78 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e8fd22bd421d7aa279bcb76189505a1f96bb7bf;p=linux-2.6 [PATCH] ARM SMP: Fix ARMv6 spinlock and semaphore implementations Signed-off-by: Russell King --- diff --git a/include/asm-arm/locks.h b/include/asm-arm/locks.h index c26298f389..9cb33fcc06 100644 --- a/include/asm-arm/locks.h +++ b/include/asm-arm/locks.h @@ -61,7 +61,7 @@ " strex ip, lr, [%0]\n" \ " teq ip, #0\n" \ " bne 1b\n" \ -" teq lr, #0\n" \ +" cmp lr, #0\n" \ " movle ip, %0\n" \ " blle " #wake \ : \ @@ -100,7 +100,7 @@ __asm__ __volatile__( \ "@ up_op_read\n" \ "1: ldrex lr, [%0]\n" \ -" add lr, lr, %1\n" \ +" adds lr, lr, %1\n" \ " strex ip, lr, [%0]\n" \ " teq ip, #0\n" \ " bne 1b\n" \ diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h index 182323619c..9705d5eec9 100644 --- a/include/asm-arm/spinlock.h +++ b/include/asm-arm/spinlock.h @@ -79,7 +79,8 @@ typedef struct { } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } -#define rwlock_init(x) do { *(x) + RW_LOCK_UNLOCKED; } while (0) +#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while (0) +#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0) /* * Write locks are easy - we just set bit 31. When unlocking, we can @@ -100,6 +101,21 @@ static inline void _raw_write_lock(rwlock_t *rw) : "cc", "memory"); } +static inline int _raw_write_trylock(rwlock_t *rw) +{ + unsigned long tmp; + + __asm__ __volatile__( +"1: ldrex %0, [%1]\n" +" teq %0, #0\n" +" strexeq %0, %2, [%1]" + : "=&r" (tmp) + : "r" (&rw->lock), "r" (0x80000000) + : "cc", "memory"); + + return tmp == 0; +} + static inline void _raw_write_unlock(rwlock_t *rw) { __asm__ __volatile__( @@ -138,6 +154,8 @@ static inline void _raw_read_lock(rwlock_t *rw) static inline void _raw_read_unlock(rwlock_t *rw) { + unsigned long tmp, tmp2; + __asm__ __volatile__( "1: ldrex %0, [%2]\n" " sub %0, %0, #1\n" @@ -151,19 +169,4 @@ static inline void _raw_read_unlock(rwlock_t *rw) #define _raw_read_trylock(lock) generic_raw_read_trylock(lock) -static inline int _raw_write_trylock(rwlock_t *rw) -{ - unsigned long tmp; - - __asm__ __volatile__( -"1: ldrex %0, [%1]\n" -" teq %0, #0\n" -" strexeq %0, %2, [%1]" - : "=&r" (tmp) - : "r" (&rw->lock), "r" (0x80000000) - : "cc", "memory"); - - return tmp == 0; -} - #endif /* __ASM_SPINLOCK_H */