xref: /openbmc/linux/arch/openrisc/include/asm/bitops/atomic.h (revision 0337966d121ebebf73a1c346123e8112796e684e)
1*0e9f9fd2SStefan Kristiansson /*
2*0e9f9fd2SStefan Kristiansson  * Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
3*0e9f9fd2SStefan Kristiansson  *
4*0e9f9fd2SStefan Kristiansson  * This file is licensed under the terms of the GNU General Public License
5*0e9f9fd2SStefan Kristiansson  * version 2.  This program is licensed "as is" without any warranty of any
6*0e9f9fd2SStefan Kristiansson  * kind, whether express or implied.
7*0e9f9fd2SStefan Kristiansson  */
8*0e9f9fd2SStefan Kristiansson 
9*0e9f9fd2SStefan Kristiansson #ifndef __ASM_OPENRISC_BITOPS_ATOMIC_H
10*0e9f9fd2SStefan Kristiansson #define __ASM_OPENRISC_BITOPS_ATOMIC_H
11*0e9f9fd2SStefan Kristiansson 
set_bit(int nr,volatile unsigned long * addr)12*0e9f9fd2SStefan Kristiansson static inline void set_bit(int nr, volatile unsigned long *addr)
13*0e9f9fd2SStefan Kristiansson {
14*0e9f9fd2SStefan Kristiansson 	unsigned long mask = BIT_MASK(nr);
15*0e9f9fd2SStefan Kristiansson 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
16*0e9f9fd2SStefan Kristiansson 	unsigned long tmp;
17*0e9f9fd2SStefan Kristiansson 
18*0e9f9fd2SStefan Kristiansson 	__asm__ __volatile__(
19*0e9f9fd2SStefan Kristiansson 		"1:	l.lwa	%0,0(%1)	\n"
20*0e9f9fd2SStefan Kristiansson 		"	l.or	%0,%0,%2	\n"
21*0e9f9fd2SStefan Kristiansson 		"	l.swa	0(%1),%0	\n"
22*0e9f9fd2SStefan Kristiansson 		"	l.bnf	1b		\n"
23*0e9f9fd2SStefan Kristiansson 		"	 l.nop			\n"
24*0e9f9fd2SStefan Kristiansson 		: "=&r"(tmp)
25*0e9f9fd2SStefan Kristiansson 		: "r"(p), "r"(mask)
26*0e9f9fd2SStefan Kristiansson 		: "cc", "memory");
27*0e9f9fd2SStefan Kristiansson }
28*0e9f9fd2SStefan Kristiansson 
clear_bit(int nr,volatile unsigned long * addr)29*0e9f9fd2SStefan Kristiansson static inline void clear_bit(int nr, volatile unsigned long *addr)
30*0e9f9fd2SStefan Kristiansson {
31*0e9f9fd2SStefan Kristiansson 	unsigned long mask = BIT_MASK(nr);
32*0e9f9fd2SStefan Kristiansson 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
33*0e9f9fd2SStefan Kristiansson 	unsigned long tmp;
34*0e9f9fd2SStefan Kristiansson 
35*0e9f9fd2SStefan Kristiansson 	__asm__ __volatile__(
36*0e9f9fd2SStefan Kristiansson 		"1:	l.lwa	%0,0(%1)	\n"
37*0e9f9fd2SStefan Kristiansson 		"	l.and	%0,%0,%2	\n"
38*0e9f9fd2SStefan Kristiansson 		"	l.swa	0(%1),%0	\n"
39*0e9f9fd2SStefan Kristiansson 		"	l.bnf	1b		\n"
40*0e9f9fd2SStefan Kristiansson 		"	 l.nop			\n"
41*0e9f9fd2SStefan Kristiansson 		: "=&r"(tmp)
42*0e9f9fd2SStefan Kristiansson 		: "r"(p), "r"(~mask)
43*0e9f9fd2SStefan Kristiansson 		: "cc", "memory");
44*0e9f9fd2SStefan Kristiansson }
45*0e9f9fd2SStefan Kristiansson 
change_bit(int nr,volatile unsigned long * addr)46*0e9f9fd2SStefan Kristiansson static inline void change_bit(int nr, volatile unsigned long *addr)
47*0e9f9fd2SStefan Kristiansson {
48*0e9f9fd2SStefan Kristiansson 	unsigned long mask = BIT_MASK(nr);
49*0e9f9fd2SStefan Kristiansson 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
50*0e9f9fd2SStefan Kristiansson 	unsigned long tmp;
51*0e9f9fd2SStefan Kristiansson 
52*0e9f9fd2SStefan Kristiansson 	__asm__ __volatile__(
53*0e9f9fd2SStefan Kristiansson 		"1:	l.lwa	%0,0(%1)	\n"
54*0e9f9fd2SStefan Kristiansson 		"	l.xor	%0,%0,%2	\n"
55*0e9f9fd2SStefan Kristiansson 		"	l.swa	0(%1),%0	\n"
56*0e9f9fd2SStefan Kristiansson 		"	l.bnf	1b		\n"
57*0e9f9fd2SStefan Kristiansson 		"	 l.nop			\n"
58*0e9f9fd2SStefan Kristiansson 		: "=&r"(tmp)
59*0e9f9fd2SStefan Kristiansson 		: "r"(p), "r"(mask)
60*0e9f9fd2SStefan Kristiansson 		: "cc", "memory");
61*0e9f9fd2SStefan Kristiansson }
62*0e9f9fd2SStefan Kristiansson 
test_and_set_bit(int nr,volatile unsigned long * addr)63*0e9f9fd2SStefan Kristiansson static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
64*0e9f9fd2SStefan Kristiansson {
65*0e9f9fd2SStefan Kristiansson 	unsigned long mask = BIT_MASK(nr);
66*0e9f9fd2SStefan Kristiansson 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
67*0e9f9fd2SStefan Kristiansson 	unsigned long old;
68*0e9f9fd2SStefan Kristiansson 	unsigned long tmp;
69*0e9f9fd2SStefan Kristiansson 
70*0e9f9fd2SStefan Kristiansson 	__asm__ __volatile__(
71*0e9f9fd2SStefan Kristiansson 		"1:	l.lwa	%0,0(%2)	\n"
72*0e9f9fd2SStefan Kristiansson 		"	l.or	%1,%0,%3	\n"
73*0e9f9fd2SStefan Kristiansson 		"	l.swa	0(%2),%1	\n"
74*0e9f9fd2SStefan Kristiansson 		"	l.bnf	1b		\n"
75*0e9f9fd2SStefan Kristiansson 		"	 l.nop			\n"
76*0e9f9fd2SStefan Kristiansson 		: "=&r"(old), "=&r"(tmp)
77*0e9f9fd2SStefan Kristiansson 		: "r"(p), "r"(mask)
78*0e9f9fd2SStefan Kristiansson 		: "cc", "memory");
79*0e9f9fd2SStefan Kristiansson 
80*0e9f9fd2SStefan Kristiansson 	return (old & mask) != 0;
81*0e9f9fd2SStefan Kristiansson }
82*0e9f9fd2SStefan Kristiansson 
test_and_clear_bit(int nr,volatile unsigned long * addr)83*0e9f9fd2SStefan Kristiansson static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
84*0e9f9fd2SStefan Kristiansson {
85*0e9f9fd2SStefan Kristiansson 	unsigned long mask = BIT_MASK(nr);
86*0e9f9fd2SStefan Kristiansson 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
87*0e9f9fd2SStefan Kristiansson 	unsigned long old;
88*0e9f9fd2SStefan Kristiansson 	unsigned long tmp;
89*0e9f9fd2SStefan Kristiansson 
90*0e9f9fd2SStefan Kristiansson 	__asm__ __volatile__(
91*0e9f9fd2SStefan Kristiansson 		"1:	l.lwa	%0,0(%2)	\n"
92*0e9f9fd2SStefan Kristiansson 		"	l.and	%1,%0,%3	\n"
93*0e9f9fd2SStefan Kristiansson 		"	l.swa	0(%2),%1	\n"
94*0e9f9fd2SStefan Kristiansson 		"	l.bnf	1b		\n"
95*0e9f9fd2SStefan Kristiansson 		"	 l.nop			\n"
96*0e9f9fd2SStefan Kristiansson 		: "=&r"(old), "=&r"(tmp)
97*0e9f9fd2SStefan Kristiansson 		: "r"(p), "r"(~mask)
98*0e9f9fd2SStefan Kristiansson 		: "cc", "memory");
99*0e9f9fd2SStefan Kristiansson 
100*0e9f9fd2SStefan Kristiansson 	return (old & mask) != 0;
101*0e9f9fd2SStefan Kristiansson }
102*0e9f9fd2SStefan Kristiansson 
test_and_change_bit(int nr,volatile unsigned long * addr)103*0e9f9fd2SStefan Kristiansson static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
104*0e9f9fd2SStefan Kristiansson {
105*0e9f9fd2SStefan Kristiansson 	unsigned long mask = BIT_MASK(nr);
106*0e9f9fd2SStefan Kristiansson 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
107*0e9f9fd2SStefan Kristiansson 	unsigned long old;
108*0e9f9fd2SStefan Kristiansson 	unsigned long tmp;
109*0e9f9fd2SStefan Kristiansson 
110*0e9f9fd2SStefan Kristiansson 	__asm__ __volatile__(
111*0e9f9fd2SStefan Kristiansson 		"1:	l.lwa	%0,0(%2)	\n"
112*0e9f9fd2SStefan Kristiansson 		"	l.xor	%1,%0,%3	\n"
113*0e9f9fd2SStefan Kristiansson 		"	l.swa	0(%2),%1	\n"
114*0e9f9fd2SStefan Kristiansson 		"	l.bnf	1b		\n"
115*0e9f9fd2SStefan Kristiansson 		"	 l.nop			\n"
116*0e9f9fd2SStefan Kristiansson 		: "=&r"(old), "=&r"(tmp)
117*0e9f9fd2SStefan Kristiansson 		: "r"(p), "r"(mask)
118*0e9f9fd2SStefan Kristiansson 		: "cc", "memory");
119*0e9f9fd2SStefan Kristiansson 
120*0e9f9fd2SStefan Kristiansson 	return (old & mask) != 0;
121*0e9f9fd2SStefan Kristiansson }
122*0e9f9fd2SStefan Kristiansson 
123*0e9f9fd2SStefan Kristiansson #endif /* __ASM_OPENRISC_BITOPS_ATOMIC_H */
124