1573687f8SAndrew Jones /* 2573687f8SAndrew Jones * spinlocks 3573687f8SAndrew Jones * 4573687f8SAndrew Jones * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5573687f8SAndrew Jones * 6573687f8SAndrew Jones * This work is licensed under the terms of the GNU LGPL, version 2. 7573687f8SAndrew Jones */ 8573687f8SAndrew Jones #include <asm/spinlock.h> 9573687f8SAndrew Jones #include <asm/barrier.h> 10573687f8SAndrew Jones #include <asm/mmu.h> 11573687f8SAndrew Jones 12573687f8SAndrew Jones void spin_lock(struct spinlock *lock) 13573687f8SAndrew Jones { 14573687f8SAndrew Jones u32 val, fail; 15573687f8SAndrew Jones 16573687f8SAndrew Jones if (!mmu_enabled()) { 17573687f8SAndrew Jones lock->v = 1; 18*23fb3b17SAndrew Jones smp_mb(); 19573687f8SAndrew Jones return; 20573687f8SAndrew Jones } 21573687f8SAndrew Jones 22573687f8SAndrew Jones do { 23573687f8SAndrew Jones asm volatile( 24573687f8SAndrew Jones "1: ldaxr %w0, [%2]\n" 25573687f8SAndrew Jones " cbnz %w0, 1b\n" 26573687f8SAndrew Jones " mov %0, #1\n" 27573687f8SAndrew Jones " stxr %w1, %w0, [%2]\n" 28573687f8SAndrew Jones : "=&r" (val), "=&r" (fail) 29573687f8SAndrew Jones : "r" (&lock->v) 30573687f8SAndrew Jones : "cc" ); 31573687f8SAndrew Jones } while (fail); 32573687f8SAndrew Jones smp_mb(); 33573687f8SAndrew Jones } 34573687f8SAndrew Jones 35573687f8SAndrew Jones void spin_unlock(struct spinlock *lock) 36573687f8SAndrew Jones { 37*23fb3b17SAndrew Jones smp_mb(); 38573687f8SAndrew Jones if (mmu_enabled()) 39573687f8SAndrew Jones asm volatile("stlrh wzr, [%0]" :: "r" (&lock->v)); 40573687f8SAndrew Jones else 41573687f8SAndrew Jones lock->v = 0; 42573687f8SAndrew Jones } 43