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