[PATCH] ARM SMP: Fix ARMv6 spinlock and semaphore implementations
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
committed by
Russell King
parent
2c2a68b847
commit
4e8fd22bd4
@@ -61,7 +61,7 @@
|
|||||||
" strex ip, lr, [%0]\n" \
|
" strex ip, lr, [%0]\n" \
|
||||||
" teq ip, #0\n" \
|
" teq ip, #0\n" \
|
||||||
" bne 1b\n" \
|
" bne 1b\n" \
|
||||||
" teq lr, #0\n" \
|
" cmp lr, #0\n" \
|
||||||
" movle ip, %0\n" \
|
" movle ip, %0\n" \
|
||||||
" blle " #wake \
|
" blle " #wake \
|
||||||
: \
|
: \
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"@ up_op_read\n" \
|
"@ up_op_read\n" \
|
||||||
"1: ldrex lr, [%0]\n" \
|
"1: ldrex lr, [%0]\n" \
|
||||||
" add lr, lr, %1\n" \
|
" adds lr, lr, %1\n" \
|
||||||
" strex ip, lr, [%0]\n" \
|
" strex ip, lr, [%0]\n" \
|
||||||
" teq ip, #0\n" \
|
" teq ip, #0\n" \
|
||||||
" bne 1b\n" \
|
" bne 1b\n" \
|
||||||
|
@@ -79,7 +79,8 @@ typedef struct {
|
|||||||
} rwlock_t;
|
} rwlock_t;
|
||||||
|
|
||||||
#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
|
#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
|
* 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");
|
: "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)
|
static inline void _raw_write_unlock(rwlock_t *rw)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@@ -138,6 +154,8 @@ static inline void _raw_read_lock(rwlock_t *rw)
|
|||||||
|
|
||||||
static inline void _raw_read_unlock(rwlock_t *rw)
|
static inline void _raw_read_unlock(rwlock_t *rw)
|
||||||
{
|
{
|
||||||
|
unsigned long tmp, tmp2;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"1: ldrex %0, [%2]\n"
|
"1: ldrex %0, [%2]\n"
|
||||||
" sub %0, %0, #1\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)
|
#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 */
|
#endif /* __ASM_SPINLOCK_H */
|
||||||
|
Reference in New Issue
Block a user