1 /* 2 * spinlocks 3 * 4 * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5 * 6 * This work is licensed under the terms of the GNU LGPL, version 2. 7 */ 8 #include <libcflat.h> 9 #include <asm/spinlock.h> 10 #include <asm/barrier.h> 11 #include <asm/mmu.h> 12 13 void spin_lock(struct spinlock *lock) 14 { 15 u32 val, fail; 16 17 if (!mmu_enabled()) { 18 lock->v = 1; 19 smp_mb(); 20 return; 21 } 22 23 do { 24 asm volatile( 25 "1: ldaxr %w0, [%2]\n" 26 " cbnz %w0, 1b\n" 27 " mov %w0, #1\n" 28 " stxr %w1, %w0, [%2]\n" 29 : "=&r" (val), "=&r" (fail) 30 : "r" (&lock->v) 31 : "cc" ); 32 } while (fail); 33 smp_mb(); 34 } 35 36 void spin_unlock(struct spinlock *lock) 37 { 38 smp_mb(); 39 if (mmu_enabled()) 40 asm volatile("stlrh wzr, [%0]" :: "r" (&lock->v)); 41 else 42 lock->v = 0; 43 } 44