]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/blame - include/asm-generic/bitops/atomic.h
UBUNTU: Ubuntu-5.0.0-29.31
[mirror_ubuntu-disco-kernel.git] / include / asm-generic / bitops / atomic.h
CommitLineData
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 14static 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 20static 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 26static 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 32static 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 45static 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 58static 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 */