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