]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
7a8a2429 AM |
2 | #ifndef _ASM_GENERIC_BITOPS_ATOMIC_H_ |
3 | #define _ASM_GENERIC_BITOPS_ATOMIC_H_ | |
4 | ||
e986a0d6 WD |
5 | #include <linux/atomic.h> |
6 | #include <linux/compiler.h> | |
7 | #include <asm/barrier.h> | |
7a8a2429 AM |
8 | |
9 | /* | |
e986a0d6 WD |
10 | * Implementation of atomic bitops using atomic-fetch ops. |
11 | * See Documentation/atomic_bitops.txt for details. | |
7a8a2429 AM |
12 | */ |
13 | ||
e986a0d6 | 14 | static inline void set_bit(unsigned int nr, volatile unsigned long *p) |
7a8a2429 | 15 | { |
e986a0d6 WD |
16 | p += BIT_WORD(nr); |
17 | atomic_long_or(BIT_MASK(nr), (atomic_long_t *)p); | |
7a8a2429 AM |
18 | } |
19 | ||
e986a0d6 | 20 | static inline void clear_bit(unsigned int nr, volatile unsigned long *p) |
7a8a2429 | 21 | { |
e986a0d6 WD |
22 | p += BIT_WORD(nr); |
23 | atomic_long_andnot(BIT_MASK(nr), (atomic_long_t *)p); | |
7a8a2429 AM |
24 | } |
25 | ||
e986a0d6 | 26 | static inline void change_bit(unsigned int nr, volatile unsigned long *p) |
7a8a2429 | 27 | { |
e986a0d6 WD |
28 | p += BIT_WORD(nr); |
29 | atomic_long_xor(BIT_MASK(nr), (atomic_long_t *)p); | |
7a8a2429 AM |
30 | } |
31 | ||
e986a0d6 | 32 | static inline int test_and_set_bit(unsigned int nr, volatile unsigned long *p) |
7a8a2429 | 33 | { |
e986a0d6 | 34 | long old; |
d05be13b | 35 | unsigned long mask = BIT_MASK(nr); |
7a8a2429 | 36 | |
e986a0d6 WD |
37 | p += BIT_WORD(nr); |
38 | if (READ_ONCE(*p) & mask) | |
39 | return 1; | |
7a8a2429 | 40 | |
e986a0d6 WD |
41 | old = atomic_long_fetch_or(mask, (atomic_long_t *)p); |
42 | return !!(old & mask); | |
7a8a2429 AM |
43 | } |
44 | ||
e986a0d6 | 45 | static inline int test_and_clear_bit(unsigned int nr, volatile unsigned long *p) |
7a8a2429 | 46 | { |
e986a0d6 | 47 | long old; |
d05be13b | 48 | unsigned long mask = BIT_MASK(nr); |
7a8a2429 | 49 | |
e986a0d6 WD |
50 | p += BIT_WORD(nr); |
51 | if (!(READ_ONCE(*p) & mask)) | |
52 | return 0; | |
7a8a2429 | 53 | |
e986a0d6 WD |
54 | old = atomic_long_fetch_andnot(mask, (atomic_long_t *)p); |
55 | return !!(old & mask); | |
7a8a2429 AM |
56 | } |
57 | ||
e986a0d6 | 58 | static inline int test_and_change_bit(unsigned int nr, volatile unsigned long *p) |
7a8a2429 | 59 | { |
e986a0d6 | 60 | long old; |
d05be13b | 61 | unsigned long mask = BIT_MASK(nr); |
7a8a2429 | 62 | |
e986a0d6 WD |
63 | p += BIT_WORD(nr); |
64 | old = atomic_long_fetch_xor(mask, (atomic_long_t *)p); | |
65 | return !!(old & mask); | |
7a8a2429 AM |
66 | } |
67 | ||
68 | #endif /* _ASM_GENERIC_BITOPS_ATOMIC_H */ |