|
@@ -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)
|
|
|
|