GNU Linux-libre 4.14.251-gnu1
[releases.git] / arch / metag / include / asm / bitops.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_METAG_BITOPS_H
3 #define __ASM_METAG_BITOPS_H
4
5 #include <linux/compiler.h>
6 #include <asm/barrier.h>
7 #include <asm/global_lock.h>
8
9 #ifdef CONFIG_SMP
10 /*
11  * These functions are the basis of our bit ops.
12  */
13 static inline void set_bit(unsigned int bit, volatile unsigned long *p)
14 {
15         unsigned long flags;
16         unsigned long mask = 1UL << (bit & 31);
17
18         p += bit >> 5;
19
20         __global_lock1(flags);
21         fence();
22         *p |= mask;
23         __global_unlock1(flags);
24 }
25
26 static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
27 {
28         unsigned long flags;
29         unsigned long mask = 1UL << (bit & 31);
30
31         p += bit >> 5;
32
33         __global_lock1(flags);
34         fence();
35         *p &= ~mask;
36         __global_unlock1(flags);
37 }
38
39 static inline void change_bit(unsigned int bit, volatile unsigned long *p)
40 {
41         unsigned long flags;
42         unsigned long mask = 1UL << (bit & 31);
43
44         p += bit >> 5;
45
46         __global_lock1(flags);
47         fence();
48         *p ^= mask;
49         __global_unlock1(flags);
50 }
51
52 static inline int test_and_set_bit(unsigned int bit, volatile unsigned long *p)
53 {
54         unsigned long flags;
55         unsigned long old;
56         unsigned long mask = 1UL << (bit & 31);
57
58         p += bit >> 5;
59
60         __global_lock1(flags);
61         old = *p;
62         if (!(old & mask)) {
63                 fence();
64                 *p = old | mask;
65         }
66         __global_unlock1(flags);
67
68         return (old & mask) != 0;
69 }
70
71 static inline int test_and_clear_bit(unsigned int bit,
72                                      volatile unsigned long *p)
73 {
74         unsigned long flags;
75         unsigned long old;
76         unsigned long mask = 1UL << (bit & 31);
77
78         p += bit >> 5;
79
80         __global_lock1(flags);
81         old = *p;
82         if (old & mask) {
83                 fence();
84                 *p = old & ~mask;
85         }
86         __global_unlock1(flags);
87
88         return (old & mask) != 0;
89 }
90
91 static inline int test_and_change_bit(unsigned int bit,
92                                       volatile unsigned long *p)
93 {
94         unsigned long flags;
95         unsigned long old;
96         unsigned long mask = 1UL << (bit & 31);
97
98         p += bit >> 5;
99
100         __global_lock1(flags);
101         fence();
102         old = *p;
103         *p = old ^ mask;
104         __global_unlock1(flags);
105
106         return (old & mask) != 0;
107 }
108
109 #else
110 #include <asm-generic/bitops/atomic.h>
111 #endif /* CONFIG_SMP */
112
113 #include <asm-generic/bitops/non-atomic.h>
114 #include <asm-generic/bitops/find.h>
115 #include <asm-generic/bitops/ffs.h>
116 #include <asm-generic/bitops/__ffs.h>
117 #include <asm-generic/bitops/ffz.h>
118 #include <asm-generic/bitops/fls.h>
119 #include <asm-generic/bitops/__fls.h>
120 #include <asm-generic/bitops/fls64.h>
121 #include <asm-generic/bitops/hweight.h>
122 #include <asm-generic/bitops/lock.h>
123 #include <asm-generic/bitops/sched.h>
124 #include <asm-generic/bitops/le.h>
125 #include <asm-generic/bitops/ext2-atomic.h>
126
127 #endif /* __ASM_METAG_BITOPS_H */