summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-07-24 12:13:40 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-07-24 12:13:40 +0100
commit4e8fd22bd421d7aa279bcb76189505a1f96bb7bf (patch)
treef23106b362b242eec555b16b34f8ad22f035c65a
parent2c2a68b84752cb1090fd2456e8b83e5bcc0e73c4 (diff)
[PATCH] ARM SMP: Fix ARMv6 spinlock and semaphore implementations
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--include/asm-arm/locks.h4
-rw-r--r--include/asm-arm/spinlock.h35
2 files changed, 21 insertions, 18 deletions
diff --git a/include/asm-arm/locks.h b/include/asm-arm/locks.h
index c26298f3891..9cb33fcc06c 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 182323619ca..9705d5eec94 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 */