summaryrefslogtreecommitdiffstats
path: root/arch/arm64/include/asm/spinlock.h
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2016-01-25 19:46:21 +0100
committerTony Lindgren <tony@atomide.com>2016-01-25 19:46:21 +0100
commit7e3b1207705c10ada363bbc7d0235730ce1f5b79 (patch)
treecd1eb567acb4e72c1bdfbe8b59746c73b8627ee5 /arch/arm64/include/asm/spinlock.h
parentARM: omap2plus_defconfig: Enable ARM_KERNMEM_PERMS and few loadable modules (diff)
parentARM: OMAP: Add PWM dmtimer platform data quirks (diff)
downloadlinux-7e3b1207705c10ada363bbc7d0235730ce1f5b79.tar.xz
linux-7e3b1207705c10ada363bbc7d0235730ce1f5b79.zip
Merge branch 'enable-devices' into omap-for-v4.5/fixes
Diffstat (limited to 'arch/arm64/include/asm/spinlock.h')
-rw-r--r--arch/arm64/include/asm/spinlock.h23
1 files changed, 21 insertions, 2 deletions
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h
index c85e96d174a5..fc9682bfe002 100644
--- a/arch/arm64/include/asm/spinlock.h
+++ b/arch/arm64/include/asm/spinlock.h
@@ -26,9 +26,28 @@
* The memory barriers are implicit with the load-acquire and store-release
* instructions.
*/
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
+{
+ unsigned int tmp;
+ arch_spinlock_t lockval;
-#define arch_spin_unlock_wait(lock) \
- do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
+ asm volatile(
+" sevl\n"
+"1: wfe\n"
+"2: ldaxr %w0, %2\n"
+" eor %w1, %w0, %w0, ror #16\n"
+" cbnz %w1, 1b\n"
+ ARM64_LSE_ATOMIC_INSN(
+ /* LL/SC */
+" stxr %w1, %w0, %2\n"
+" cbnz %w1, 2b\n", /* Serialise against any concurrent lockers */
+ /* LSE atomics */
+" nop\n"
+" nop\n")
+ : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
+ :
+ : "memory");
+}
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)