diff options
author | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 12:17:53 -0700 |
---|---|---|
committer | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 15:44:42 -0700 |
commit | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (patch) | |
tree | 1c9cafbcd35f783a87880a10f85d1a060db1a563 /kernel/arch/metag/include/asm/spinlock_lnkget.h | |
parent | 98260f3884f4a202f9ca5eabed40b1354c489b29 (diff) |
Add the rt linux 4.1.3-rt3 as base
Import the rt linux 4.1.3-rt3 as OPNFV kvm base.
It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and
the base is:
commit 0917f823c59692d751951bf5ea699a2d1e2f26a2
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Sat Jul 25 12:13:34 2015 +0200
Prepare v4.1.3-rt3
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
We lose all the git history this way and it's not good. We
should apply another opnfv project repo in future.
Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Diffstat (limited to 'kernel/arch/metag/include/asm/spinlock_lnkget.h')
-rw-r--r-- | kernel/arch/metag/include/asm/spinlock_lnkget.h | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/kernel/arch/metag/include/asm/spinlock_lnkget.h b/kernel/arch/metag/include/asm/spinlock_lnkget.h new file mode 100644 index 000000000..ad8436fee --- /dev/null +++ b/kernel/arch/metag/include/asm/spinlock_lnkget.h @@ -0,0 +1,249 @@ +#ifndef __ASM_SPINLOCK_LNKGET_H +#define __ASM_SPINLOCK_LNKGET_H + +/* + * None of these asm statements clobber memory as LNKSET writes around + * the cache so the memory it modifies cannot safely be read by any means + * other than these accessors. + */ + +static inline int arch_spin_is_locked(arch_spinlock_t *lock) +{ + int ret; + + asm volatile ("LNKGETD %0, [%1]\n" + "TST %0, #1\n" + "MOV %0, #1\n" + "XORZ %0, %0, %0\n" + : "=&d" (ret) + : "da" (&lock->lock) + : "cc"); + return ret; +} + +static inline void arch_spin_lock(arch_spinlock_t *lock) +{ + int tmp; + + asm volatile ("1: LNKGETD %0,[%1]\n" + " TST %0, #1\n" + " ADD %0, %0, #1\n" + " LNKSETDZ [%1], %0\n" + " BNZ 1b\n" + " DEFR %0, TXSTAT\n" + " ANDT %0, %0, #HI(0x3f000000)\n" + " CMPT %0, #HI(0x02000000)\n" + " BNZ 1b\n" + : "=&d" (tmp) + : "da" (&lock->lock) + : "cc"); + + smp_mb(); +} + +/* Returns 0 if failed to acquire lock */ +static inline int arch_spin_trylock(arch_spinlock_t *lock) +{ + int tmp; + + asm volatile (" LNKGETD %0,[%1]\n" + " TST %0, #1\n" + " ADD %0, %0, #1\n" + " LNKSETDZ [%1], %0\n" + " BNZ 1f\n" + " DEFR %0, TXSTAT\n" + " ANDT %0, %0, #HI(0x3f000000)\n" + " CMPT %0, #HI(0x02000000)\n" + " MOV %0, #1\n" + "1: XORNZ %0, %0, %0\n" + : "=&d" (tmp) + : "da" (&lock->lock) + : "cc"); + + smp_mb(); + + return tmp; +} + +static inline void arch_spin_unlock(arch_spinlock_t *lock) +{ + smp_mb(); + + asm volatile (" SETD [%0], %1\n" + : + : "da" (&lock->lock), "da" (0) + : "memory"); +} + +/* + * RWLOCKS + * + * + * Write locks are easy - we just set bit 31. When unlocking, we can + * just write zero since the lock is exclusively held. + */ + +static inline void arch_write_lock(arch_rwlock_t *rw) +{ + int tmp; + + asm volatile ("1: LNKGETD %0,[%1]\n" + " CMP %0, #0\n" + " ADD %0, %0, %2\n" + " LNKSETDZ [%1], %0\n" + " BNZ 1b\n" + " DEFR %0, TXSTAT\n" + " ANDT %0, %0, #HI(0x3f000000)\n" + " CMPT %0, #HI(0x02000000)\n" + " BNZ 1b\n" + : "=&d" (tmp) + : "da" (&rw->lock), "bd" (0x80000000) + : "cc"); + + smp_mb(); +} + +static inline int arch_write_trylock(arch_rwlock_t *rw) +{ + int tmp; + + asm volatile (" LNKGETD %0,[%1]\n" + " CMP %0, #0\n" + " ADD %0, %0, %2\n" + " LNKSETDZ [%1], %0\n" + " BNZ 1f\n" + " DEFR %0, TXSTAT\n" + " ANDT %0, %0, #HI(0x3f000000)\n" + " CMPT %0, #HI(0x02000000)\n" + " MOV %0,#1\n" + "1: XORNZ %0, %0, %0\n" + : "=&d" (tmp) + : "da" (&rw->lock), "bd" (0x80000000) + : "cc"); + + smp_mb(); + + return tmp; +} + +static inline void arch_write_unlock(arch_rwlock_t *rw) +{ + smp_mb(); + + asm volatile (" SETD [%0], %1\n" + : + : "da" (&rw->lock), "da" (0) + : "memory"); +} + +/* write_can_lock - would write_trylock() succeed? */ +static inline int arch_write_can_lock(arch_rwlock_t *rw) +{ + int ret; + + asm volatile ("LNKGETD %0, [%1]\n" + "CMP %0, #0\n" + "MOV %0, #1\n" + "XORNZ %0, %0, %0\n" + : "=&d" (ret) + : "da" (&rw->lock) + : "cc"); + return ret; +} + +/* + * Read locks are a bit more hairy: + * - Exclusively load the lock value. + * - Increment it. + * - Store new lock value if positive, and we still own this location. + * If the value is negative, we've already failed. + * - If we failed to store the value, we want a negative result. + * - If we failed, try again. + * Unlocking is similarly hairy. We may have multiple read locks + * currently active. However, we know we won't have any write + * locks. + */ +static inline void arch_read_lock(arch_rwlock_t *rw) +{ + int tmp; + + asm volatile ("1: LNKGETD %0,[%1]\n" + " ADDS %0, %0, #1\n" + " LNKSETDPL [%1], %0\n" + " BMI 1b\n" + " DEFR %0, TXSTAT\n" + " ANDT %0, %0, #HI(0x3f000000)\n" + " CMPT %0, #HI(0x02000000)\n" + " BNZ 1b\n" + : "=&d" (tmp) + : "da" (&rw->lock) + : "cc"); + + smp_mb(); +} + +static inline void arch_read_unlock(arch_rwlock_t *rw) +{ + int tmp; + + smp_mb(); + + asm volatile ("1: LNKGETD %0,[%1]\n" + " SUB %0, %0, #1\n" + " LNKSETD [%1], %0\n" + " DEFR %0, TXSTAT\n" + " ANDT %0, %0, #HI(0x3f000000)\n" + " CMPT %0, #HI(0x02000000)\n" + " BNZ 1b\n" + : "=&d" (tmp) + : "da" (&rw->lock) + : "cc", "memory"); +} + +static inline int arch_read_trylock(arch_rwlock_t *rw) +{ + int tmp; + + asm volatile (" LNKGETD %0,[%1]\n" + " ADDS %0, %0, #1\n" + " LNKSETDPL [%1], %0\n" + " BMI 1f\n" + " DEFR %0, TXSTAT\n" + " ANDT %0, %0, #HI(0x3f000000)\n" + " CMPT %0, #HI(0x02000000)\n" + " MOV %0,#1\n" + " BZ 2f\n" + "1: MOV %0,#0\n" + "2:\n" + : "=&d" (tmp) + : "da" (&rw->lock) + : "cc"); + + smp_mb(); + + return tmp; +} + +/* read_can_lock - would read_trylock() succeed? */ +static inline int arch_read_can_lock(arch_rwlock_t *rw) +{ + int tmp; + + asm volatile ("LNKGETD %0, [%1]\n" + "CMP %0, %2\n" + "MOV %0, #1\n" + "XORZ %0, %0, %0\n" + : "=&d" (tmp) + : "da" (&rw->lock), "bd" (0x80000000) + : "cc"); + return tmp; +} + +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) + +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() + +#endif /* __ASM_SPINLOCK_LNKGET_H */ |