1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
27a8a2429SAkinobu Mita #ifndef _ASM_GENERIC_BITOPS_ATOMIC_H_
37a8a2429SAkinobu Mita #define _ASM_GENERIC_BITOPS_ATOMIC_H_
47a8a2429SAkinobu Mita
5e986a0d6SWill Deacon #include <linux/atomic.h>
6e986a0d6SWill Deacon #include <linux/compiler.h>
7e986a0d6SWill Deacon #include <asm/barrier.h>
87a8a2429SAkinobu Mita
97a8a2429SAkinobu Mita /*
10e986a0d6SWill Deacon * Implementation of atomic bitops using atomic-fetch ops.
11e986a0d6SWill Deacon * See Documentation/atomic_bitops.txt for details.
127a8a2429SAkinobu Mita */
137a8a2429SAkinobu Mita
14cf3ee3c8SMark Rutland static __always_inline void
arch_set_bit(unsigned int nr,volatile unsigned long * p)15cf3ee3c8SMark Rutland arch_set_bit(unsigned int nr, volatile unsigned long *p)
167a8a2429SAkinobu Mita {
17e986a0d6SWill Deacon p += BIT_WORD(nr);
18*0f613bfaSMark Rutland raw_atomic_long_or(BIT_MASK(nr), (atomic_long_t *)p);
197a8a2429SAkinobu Mita }
207a8a2429SAkinobu Mita
21cf3ee3c8SMark Rutland static __always_inline void
arch_clear_bit(unsigned int nr,volatile unsigned long * p)22cf3ee3c8SMark Rutland arch_clear_bit(unsigned int nr, volatile unsigned long *p)
237a8a2429SAkinobu Mita {
24e986a0d6SWill Deacon p += BIT_WORD(nr);
25*0f613bfaSMark Rutland raw_atomic_long_andnot(BIT_MASK(nr), (atomic_long_t *)p);
267a8a2429SAkinobu Mita }
277a8a2429SAkinobu Mita
28cf3ee3c8SMark Rutland static __always_inline void
arch_change_bit(unsigned int nr,volatile unsigned long * p)29cf3ee3c8SMark Rutland arch_change_bit(unsigned int nr, volatile unsigned long *p)
307a8a2429SAkinobu Mita {
31e986a0d6SWill Deacon p += BIT_WORD(nr);
32*0f613bfaSMark Rutland raw_atomic_long_xor(BIT_MASK(nr), (atomic_long_t *)p);
337a8a2429SAkinobu Mita }
347a8a2429SAkinobu Mita
35cf3ee3c8SMark Rutland static __always_inline int
arch_test_and_set_bit(unsigned int nr,volatile unsigned long * p)36cf3ee3c8SMark Rutland arch_test_and_set_bit(unsigned int nr, volatile unsigned long *p)
377a8a2429SAkinobu Mita {
38e986a0d6SWill Deacon long old;
39d05be13bSJiri Slaby unsigned long mask = BIT_MASK(nr);
407a8a2429SAkinobu Mita
41e986a0d6SWill Deacon p += BIT_WORD(nr);
42*0f613bfaSMark Rutland old = raw_atomic_long_fetch_or(mask, (atomic_long_t *)p);
43e986a0d6SWill Deacon return !!(old & mask);
447a8a2429SAkinobu Mita }
457a8a2429SAkinobu Mita
46cf3ee3c8SMark Rutland static __always_inline int
arch_test_and_clear_bit(unsigned int nr,volatile unsigned long * p)47cf3ee3c8SMark Rutland arch_test_and_clear_bit(unsigned int nr, volatile unsigned long *p)
487a8a2429SAkinobu Mita {
49e986a0d6SWill Deacon long old;
50d05be13bSJiri Slaby unsigned long mask = BIT_MASK(nr);
517a8a2429SAkinobu Mita
52e986a0d6SWill Deacon p += BIT_WORD(nr);
53*0f613bfaSMark Rutland old = raw_atomic_long_fetch_andnot(mask, (atomic_long_t *)p);
54e986a0d6SWill Deacon return !!(old & mask);
557a8a2429SAkinobu Mita }
567a8a2429SAkinobu Mita
57cf3ee3c8SMark Rutland static __always_inline int
arch_test_and_change_bit(unsigned int nr,volatile unsigned long * p)58cf3ee3c8SMark Rutland arch_test_and_change_bit(unsigned int nr, volatile unsigned long *p)
597a8a2429SAkinobu Mita {
60e986a0d6SWill Deacon long old;
61d05be13bSJiri Slaby unsigned long mask = BIT_MASK(nr);
627a8a2429SAkinobu Mita
63e986a0d6SWill Deacon p += BIT_WORD(nr);
64*0f613bfaSMark Rutland old = raw_atomic_long_fetch_xor(mask, (atomic_long_t *)p);
65e986a0d6SWill Deacon return !!(old & mask);
667a8a2429SAkinobu Mita }
677a8a2429SAkinobu Mita
68cf3ee3c8SMark Rutland #include <asm-generic/bitops/instrumented-atomic.h>
69cf3ee3c8SMark Rutland
707a8a2429SAkinobu Mita #endif /* _ASM_GENERIC_BITOPS_ATOMIC_H */
71