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 */
83c36da79SAndrew Jones #include <libcflat.h>
9573687f8SAndrew Jones #include <asm/spinlock.h>
10573687f8SAndrew Jones #include <asm/barrier.h>
11573687f8SAndrew Jones #include <asm/mmu.h>
12573687f8SAndrew Jones
spin_lock(struct spinlock * lock)13573687f8SAndrew Jones void spin_lock(struct spinlock *lock)
14573687f8SAndrew Jones {
15573687f8SAndrew Jones u32 val, fail;
16573687f8SAndrew Jones
17573687f8SAndrew Jones if (!mmu_enabled()) {
18573687f8SAndrew Jones lock->v = 1;
1923fb3b17SAndrew Jones smp_mb();
20573687f8SAndrew Jones return;
21573687f8SAndrew Jones }
22573687f8SAndrew Jones
23573687f8SAndrew Jones do {
24573687f8SAndrew Jones asm volatile(
25573687f8SAndrew Jones "1: ldaxr %w0, [%2]\n"
26573687f8SAndrew Jones " cbnz %w0, 1b\n"
27*d864b580SThomas Huth " mov %w0, #1\n"
28573687f8SAndrew Jones " stxr %w1, %w0, [%2]\n"
29573687f8SAndrew Jones : "=&r" (val), "=&r" (fail)
30573687f8SAndrew Jones : "r" (&lock->v)
31573687f8SAndrew Jones : "cc" );
32573687f8SAndrew Jones } while (fail);
33573687f8SAndrew Jones smp_mb();
34573687f8SAndrew Jones }
35573687f8SAndrew Jones
spin_unlock(struct spinlock * lock)36573687f8SAndrew Jones void spin_unlock(struct spinlock *lock)
37573687f8SAndrew Jones {
3823fb3b17SAndrew Jones smp_mb();
39573687f8SAndrew Jones if (mmu_enabled())
40573687f8SAndrew Jones asm volatile("stlrh wzr, [%0]" :: "r" (&lock->v));
41573687f8SAndrew Jones else
42573687f8SAndrew Jones lock->v = 0;
43573687f8SAndrew Jones }
44