14117b021SAkinobu Mita #ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
24117b021SAkinobu Mita #define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
34117b021SAkinobu Mita 
44117b021SAkinobu Mita #include <asm/types.h>
54117b021SAkinobu Mita 
64117b021SAkinobu Mita /**
74117b021SAkinobu Mita  * __set_bit - Set a bit in memory
84117b021SAkinobu Mita  * @nr: the bit to set
94117b021SAkinobu Mita  * @addr: the address to start counting from
104117b021SAkinobu Mita  *
114117b021SAkinobu Mita  * Unlike set_bit(), this function is non-atomic and may be reordered.
124117b021SAkinobu Mita  * If it's called on the same region of memory simultaneously, the effect
134117b021SAkinobu Mita  * may be that only one operation succeeds.
144117b021SAkinobu Mita  */
154117b021SAkinobu Mita static inline void __set_bit(int nr, volatile unsigned long *addr)
164117b021SAkinobu Mita {
17d05be13bSJiri Slaby 	unsigned long mask = BIT_MASK(nr);
18d05be13bSJiri Slaby 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
194117b021SAkinobu Mita 
204117b021SAkinobu Mita 	*p  |= mask;
214117b021SAkinobu Mita }
224117b021SAkinobu Mita 
234117b021SAkinobu Mita static inline void __clear_bit(int nr, volatile unsigned long *addr)
244117b021SAkinobu Mita {
25d05be13bSJiri Slaby 	unsigned long mask = BIT_MASK(nr);
26d05be13bSJiri Slaby 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
274117b021SAkinobu Mita 
284117b021SAkinobu Mita 	*p &= ~mask;
294117b021SAkinobu Mita }
304117b021SAkinobu Mita 
314117b021SAkinobu Mita /**
324117b021SAkinobu Mita  * __change_bit - Toggle a bit in memory
334117b021SAkinobu Mita  * @nr: the bit to change
344117b021SAkinobu Mita  * @addr: the address to start counting from
354117b021SAkinobu Mita  *
364117b021SAkinobu Mita  * Unlike change_bit(), this function is non-atomic and may be reordered.
374117b021SAkinobu Mita  * If it's called on the same region of memory simultaneously, the effect
384117b021SAkinobu Mita  * may be that only one operation succeeds.
394117b021SAkinobu Mita  */
404117b021SAkinobu Mita static inline void __change_bit(int nr, volatile unsigned long *addr)
414117b021SAkinobu Mita {
42d05be13bSJiri Slaby 	unsigned long mask = BIT_MASK(nr);
43d05be13bSJiri Slaby 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
444117b021SAkinobu Mita 
454117b021SAkinobu Mita 	*p ^= mask;
464117b021SAkinobu Mita }
474117b021SAkinobu Mita 
484117b021SAkinobu Mita /**
494117b021SAkinobu Mita  * __test_and_set_bit - Set a bit and return its old value
504117b021SAkinobu Mita  * @nr: Bit to set
514117b021SAkinobu Mita  * @addr: Address to count from
524117b021SAkinobu Mita  *
534117b021SAkinobu Mita  * This operation is non-atomic and can be reordered.
544117b021SAkinobu Mita  * If two examples of this operation race, one can appear to succeed
554117b021SAkinobu Mita  * but actually fail.  You must protect multiple accesses with a lock.
564117b021SAkinobu Mita  */
574117b021SAkinobu Mita static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
584117b021SAkinobu Mita {
59d05be13bSJiri Slaby 	unsigned long mask = BIT_MASK(nr);
60d05be13bSJiri Slaby 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
614117b021SAkinobu Mita 	unsigned long old = *p;
624117b021SAkinobu Mita 
634117b021SAkinobu Mita 	*p = old | mask;
644117b021SAkinobu Mita 	return (old & mask) != 0;
654117b021SAkinobu Mita }
664117b021SAkinobu Mita 
674117b021SAkinobu Mita /**
684117b021SAkinobu Mita  * __test_and_clear_bit - Clear a bit and return its old value
694117b021SAkinobu Mita  * @nr: Bit to clear
704117b021SAkinobu Mita  * @addr: Address to count from
714117b021SAkinobu Mita  *
724117b021SAkinobu Mita  * This operation is non-atomic and can be reordered.
734117b021SAkinobu Mita  * If two examples of this operation race, one can appear to succeed
744117b021SAkinobu Mita  * but actually fail.  You must protect multiple accesses with a lock.
754117b021SAkinobu Mita  */
764117b021SAkinobu Mita static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
774117b021SAkinobu Mita {
78d05be13bSJiri Slaby 	unsigned long mask = BIT_MASK(nr);
79d05be13bSJiri Slaby 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
804117b021SAkinobu Mita 	unsigned long old = *p;
814117b021SAkinobu Mita 
824117b021SAkinobu Mita 	*p = old & ~mask;
834117b021SAkinobu Mita 	return (old & mask) != 0;
844117b021SAkinobu Mita }
854117b021SAkinobu Mita 
864117b021SAkinobu Mita /* WARNING: non atomic and it can be reordered! */
874117b021SAkinobu Mita static inline int __test_and_change_bit(int nr,
884117b021SAkinobu Mita 					    volatile unsigned long *addr)
894117b021SAkinobu Mita {
90d05be13bSJiri Slaby 	unsigned long mask = BIT_MASK(nr);
91d05be13bSJiri Slaby 	unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
924117b021SAkinobu Mita 	unsigned long old = *p;
934117b021SAkinobu Mita 
944117b021SAkinobu Mita 	*p = old ^ mask;
954117b021SAkinobu Mita 	return (old & mask) != 0;
964117b021SAkinobu Mita }
974117b021SAkinobu Mita 
984117b021SAkinobu Mita /**
994117b021SAkinobu Mita  * test_bit - Determine whether a bit is set
1004117b021SAkinobu Mita  * @nr: bit number to test
1014117b021SAkinobu Mita  * @addr: Address to start counting from
1024117b021SAkinobu Mita  */
1034117b021SAkinobu Mita static inline int test_bit(int nr, const volatile unsigned long *addr)
1044117b021SAkinobu Mita {
105d05be13bSJiri Slaby 	return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
1064117b021SAkinobu Mita }
1074117b021SAkinobu Mita 
1084117b021SAkinobu Mita #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
109