xref: /openbmc/linux/arch/alpha/include/asm/spinlock.h (revision 024b246ed24492d6c2ee14c34d742b137fce1b94)
1*024b246eSLinus Torvalds #ifndef _ALPHA_SPINLOCK_H
2*024b246eSLinus Torvalds #define _ALPHA_SPINLOCK_H
3*024b246eSLinus Torvalds 
4*024b246eSLinus Torvalds #include <asm/system.h>
5*024b246eSLinus Torvalds #include <linux/kernel.h>
6*024b246eSLinus Torvalds #include <asm/current.h>
7*024b246eSLinus Torvalds 
8*024b246eSLinus Torvalds /*
9*024b246eSLinus Torvalds  * Simple spin lock operations.  There are two variants, one clears IRQ's
10*024b246eSLinus Torvalds  * on the local processor, one does not.
11*024b246eSLinus Torvalds  *
12*024b246eSLinus Torvalds  * We make no fairness assumptions. They have a cost.
13*024b246eSLinus Torvalds  */
14*024b246eSLinus Torvalds 
15*024b246eSLinus Torvalds #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
16*024b246eSLinus Torvalds #define __raw_spin_is_locked(x)	((x)->lock != 0)
17*024b246eSLinus Torvalds #define __raw_spin_unlock_wait(x) \
18*024b246eSLinus Torvalds 		do { cpu_relax(); } while ((x)->lock)
19*024b246eSLinus Torvalds 
20*024b246eSLinus Torvalds static inline void __raw_spin_unlock(raw_spinlock_t * lock)
21*024b246eSLinus Torvalds {
22*024b246eSLinus Torvalds 	mb();
23*024b246eSLinus Torvalds 	lock->lock = 0;
24*024b246eSLinus Torvalds }
25*024b246eSLinus Torvalds 
26*024b246eSLinus Torvalds static inline void __raw_spin_lock(raw_spinlock_t * lock)
27*024b246eSLinus Torvalds {
28*024b246eSLinus Torvalds 	long tmp;
29*024b246eSLinus Torvalds 
30*024b246eSLinus Torvalds 	__asm__ __volatile__(
31*024b246eSLinus Torvalds 	"1:	ldl_l	%0,%1\n"
32*024b246eSLinus Torvalds 	"	bne	%0,2f\n"
33*024b246eSLinus Torvalds 	"	lda	%0,1\n"
34*024b246eSLinus Torvalds 	"	stl_c	%0,%1\n"
35*024b246eSLinus Torvalds 	"	beq	%0,2f\n"
36*024b246eSLinus Torvalds 	"	mb\n"
37*024b246eSLinus Torvalds 	".subsection 2\n"
38*024b246eSLinus Torvalds 	"2:	ldl	%0,%1\n"
39*024b246eSLinus Torvalds 	"	bne	%0,2b\n"
40*024b246eSLinus Torvalds 	"	br	1b\n"
41*024b246eSLinus Torvalds 	".previous"
42*024b246eSLinus Torvalds 	: "=&r" (tmp), "=m" (lock->lock)
43*024b246eSLinus Torvalds 	: "m"(lock->lock) : "memory");
44*024b246eSLinus Torvalds }
45*024b246eSLinus Torvalds 
46*024b246eSLinus Torvalds static inline int __raw_spin_trylock(raw_spinlock_t *lock)
47*024b246eSLinus Torvalds {
48*024b246eSLinus Torvalds 	return !test_and_set_bit(0, &lock->lock);
49*024b246eSLinus Torvalds }
50*024b246eSLinus Torvalds 
51*024b246eSLinus Torvalds /***********************************************************/
52*024b246eSLinus Torvalds 
53*024b246eSLinus Torvalds static inline int __raw_read_can_lock(raw_rwlock_t *lock)
54*024b246eSLinus Torvalds {
55*024b246eSLinus Torvalds 	return (lock->lock & 1) == 0;
56*024b246eSLinus Torvalds }
57*024b246eSLinus Torvalds 
58*024b246eSLinus Torvalds static inline int __raw_write_can_lock(raw_rwlock_t *lock)
59*024b246eSLinus Torvalds {
60*024b246eSLinus Torvalds 	return lock->lock == 0;
61*024b246eSLinus Torvalds }
62*024b246eSLinus Torvalds 
63*024b246eSLinus Torvalds static inline void __raw_read_lock(raw_rwlock_t *lock)
64*024b246eSLinus Torvalds {
65*024b246eSLinus Torvalds 	long regx;
66*024b246eSLinus Torvalds 
67*024b246eSLinus Torvalds 	__asm__ __volatile__(
68*024b246eSLinus Torvalds 	"1:	ldl_l	%1,%0\n"
69*024b246eSLinus Torvalds 	"	blbs	%1,6f\n"
70*024b246eSLinus Torvalds 	"	subl	%1,2,%1\n"
71*024b246eSLinus Torvalds 	"	stl_c	%1,%0\n"
72*024b246eSLinus Torvalds 	"	beq	%1,6f\n"
73*024b246eSLinus Torvalds 	"	mb\n"
74*024b246eSLinus Torvalds 	".subsection 2\n"
75*024b246eSLinus Torvalds 	"6:	ldl	%1,%0\n"
76*024b246eSLinus Torvalds 	"	blbs	%1,6b\n"
77*024b246eSLinus Torvalds 	"	br	1b\n"
78*024b246eSLinus Torvalds 	".previous"
79*024b246eSLinus Torvalds 	: "=m" (*lock), "=&r" (regx)
80*024b246eSLinus Torvalds 	: "m" (*lock) : "memory");
81*024b246eSLinus Torvalds }
82*024b246eSLinus Torvalds 
83*024b246eSLinus Torvalds static inline void __raw_write_lock(raw_rwlock_t *lock)
84*024b246eSLinus Torvalds {
85*024b246eSLinus Torvalds 	long regx;
86*024b246eSLinus Torvalds 
87*024b246eSLinus Torvalds 	__asm__ __volatile__(
88*024b246eSLinus Torvalds 	"1:	ldl_l	%1,%0\n"
89*024b246eSLinus Torvalds 	"	bne	%1,6f\n"
90*024b246eSLinus Torvalds 	"	lda	%1,1\n"
91*024b246eSLinus Torvalds 	"	stl_c	%1,%0\n"
92*024b246eSLinus Torvalds 	"	beq	%1,6f\n"
93*024b246eSLinus Torvalds 	"	mb\n"
94*024b246eSLinus Torvalds 	".subsection 2\n"
95*024b246eSLinus Torvalds 	"6:	ldl	%1,%0\n"
96*024b246eSLinus Torvalds 	"	bne	%1,6b\n"
97*024b246eSLinus Torvalds 	"	br	1b\n"
98*024b246eSLinus Torvalds 	".previous"
99*024b246eSLinus Torvalds 	: "=m" (*lock), "=&r" (regx)
100*024b246eSLinus Torvalds 	: "m" (*lock) : "memory");
101*024b246eSLinus Torvalds }
102*024b246eSLinus Torvalds 
103*024b246eSLinus Torvalds static inline int __raw_read_trylock(raw_rwlock_t * lock)
104*024b246eSLinus Torvalds {
105*024b246eSLinus Torvalds 	long regx;
106*024b246eSLinus Torvalds 	int success;
107*024b246eSLinus Torvalds 
108*024b246eSLinus Torvalds 	__asm__ __volatile__(
109*024b246eSLinus Torvalds 	"1:	ldl_l	%1,%0\n"
110*024b246eSLinus Torvalds 	"	lda	%2,0\n"
111*024b246eSLinus Torvalds 	"	blbs	%1,2f\n"
112*024b246eSLinus Torvalds 	"	subl	%1,2,%2\n"
113*024b246eSLinus Torvalds 	"	stl_c	%2,%0\n"
114*024b246eSLinus Torvalds 	"	beq	%2,6f\n"
115*024b246eSLinus Torvalds 	"2:	mb\n"
116*024b246eSLinus Torvalds 	".subsection 2\n"
117*024b246eSLinus Torvalds 	"6:	br	1b\n"
118*024b246eSLinus Torvalds 	".previous"
119*024b246eSLinus Torvalds 	: "=m" (*lock), "=&r" (regx), "=&r" (success)
120*024b246eSLinus Torvalds 	: "m" (*lock) : "memory");
121*024b246eSLinus Torvalds 
122*024b246eSLinus Torvalds 	return success;
123*024b246eSLinus Torvalds }
124*024b246eSLinus Torvalds 
125*024b246eSLinus Torvalds static inline int __raw_write_trylock(raw_rwlock_t * lock)
126*024b246eSLinus Torvalds {
127*024b246eSLinus Torvalds 	long regx;
128*024b246eSLinus Torvalds 	int success;
129*024b246eSLinus Torvalds 
130*024b246eSLinus Torvalds 	__asm__ __volatile__(
131*024b246eSLinus Torvalds 	"1:	ldl_l	%1,%0\n"
132*024b246eSLinus Torvalds 	"	lda	%2,0\n"
133*024b246eSLinus Torvalds 	"	bne	%1,2f\n"
134*024b246eSLinus Torvalds 	"	lda	%2,1\n"
135*024b246eSLinus Torvalds 	"	stl_c	%2,%0\n"
136*024b246eSLinus Torvalds 	"	beq	%2,6f\n"
137*024b246eSLinus Torvalds 	"2:	mb\n"
138*024b246eSLinus Torvalds 	".subsection 2\n"
139*024b246eSLinus Torvalds 	"6:	br	1b\n"
140*024b246eSLinus Torvalds 	".previous"
141*024b246eSLinus Torvalds 	: "=m" (*lock), "=&r" (regx), "=&r" (success)
142*024b246eSLinus Torvalds 	: "m" (*lock) : "memory");
143*024b246eSLinus Torvalds 
144*024b246eSLinus Torvalds 	return success;
145*024b246eSLinus Torvalds }
146*024b246eSLinus Torvalds 
147*024b246eSLinus Torvalds static inline void __raw_read_unlock(raw_rwlock_t * lock)
148*024b246eSLinus Torvalds {
149*024b246eSLinus Torvalds 	long regx;
150*024b246eSLinus Torvalds 	__asm__ __volatile__(
151*024b246eSLinus Torvalds 	"	mb\n"
152*024b246eSLinus Torvalds 	"1:	ldl_l	%1,%0\n"
153*024b246eSLinus Torvalds 	"	addl	%1,2,%1\n"
154*024b246eSLinus Torvalds 	"	stl_c	%1,%0\n"
155*024b246eSLinus Torvalds 	"	beq	%1,6f\n"
156*024b246eSLinus Torvalds 	".subsection 2\n"
157*024b246eSLinus Torvalds 	"6:	br	1b\n"
158*024b246eSLinus Torvalds 	".previous"
159*024b246eSLinus Torvalds 	: "=m" (*lock), "=&r" (regx)
160*024b246eSLinus Torvalds 	: "m" (*lock) : "memory");
161*024b246eSLinus Torvalds }
162*024b246eSLinus Torvalds 
163*024b246eSLinus Torvalds static inline void __raw_write_unlock(raw_rwlock_t * lock)
164*024b246eSLinus Torvalds {
165*024b246eSLinus Torvalds 	mb();
166*024b246eSLinus Torvalds 	lock->lock = 0;
167*024b246eSLinus Torvalds }
168*024b246eSLinus Torvalds 
169*024b246eSLinus Torvalds #define _raw_spin_relax(lock)	cpu_relax()
170*024b246eSLinus Torvalds #define _raw_read_relax(lock)	cpu_relax()
171*024b246eSLinus Torvalds #define _raw_write_relax(lock)	cpu_relax()
172*024b246eSLinus Torvalds 
173*024b246eSLinus Torvalds #endif /* _ALPHA_SPINLOCK_H */
174