blob: 258303dabb98d5f530fccbfedd7e976d972a1e0f [file] [log] [blame]
/*
* 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;
}