/* | |
* spinlocks | |
* | |
* Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com> | |
* | |
* This work is licensed under the terms of the GNU LGPL, version 2. | |
*/ | |
#include <libcflat.h> | |
#include <asm/spinlock.h> | |
#include <asm/barrier.h> | |
#include <asm/mmu.h> | |
void spin_lock(struct spinlock *lock) | |
{ | |
u32 val, fail; | |
if (!mmu_enabled()) { | |
lock->v = 1; | |
smp_mb(); | |
return; | |
} | |
do { | |
asm volatile( | |
"1: ldaxr %w0, [%2]\n" | |
" cbnz %w0, 1b\n" | |
" mov %w0, #1\n" | |
" stxr %w1, %w0, [%2]\n" | |
: "=&r" (val), "=&r" (fail) | |
: "r" (&lock->v) | |
: "cc" ); | |
} while (fail); | |
smp_mb(); | |
} | |
void spin_unlock(struct spinlock *lock) | |
{ | |
smp_mb(); | |
if (mmu_enabled()) | |
asm volatile("stlrh wzr, [%0]" :: "r" (&lock->v)); | |
else | |
lock->v = 0; | |
} |