^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/irqflags.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * __mips_set_bit - Atomically set a bit in memory. This is called by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * set_bit() if it cannot find a faster solution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * @nr: the bit to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * @addr: the address to start counting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) void __mips_set_bit(unsigned long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) volatile unsigned long *a = &addr[BIT_WORD(nr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned int bit = nr % BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) mask = 1UL << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) raw_local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *a |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) raw_local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) EXPORT_SYMBOL(__mips_set_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * it cannot find a faster solution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @nr: Bit to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @addr: Address to start counting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) volatile unsigned long *a = &addr[BIT_WORD(nr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int bit = nr % BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mask = 1UL << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) raw_local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *a &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) raw_local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) EXPORT_SYMBOL(__mips_clear_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * __mips_change_bit - Toggle a bit in memory. This is called by change_bit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * if it cannot find a faster solution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @nr: Bit to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @addr: Address to start counting from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void __mips_change_bit(unsigned long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) volatile unsigned long *a = &addr[BIT_WORD(nr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned int bit = nr % BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) mask = 1UL << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) raw_local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *a ^= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) raw_local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) EXPORT_SYMBOL(__mips_change_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * called by test_and_set_bit_lock() if it cannot find a faster solution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @nr: Bit to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * @addr: Address to count from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int __mips_test_and_set_bit_lock(unsigned long nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) volatile unsigned long *a = &addr[BIT_WORD(nr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int bit = nr % BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mask = 1UL << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) raw_local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) res = (mask & *a) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *a |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) raw_local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) EXPORT_SYMBOL(__mips_test_and_set_bit_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * __mips_test_and_clear_bit - Clear a bit and return its old value. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * called by test_and_clear_bit() if it cannot find a faster solution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @nr: Bit to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @addr: Address to count from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) volatile unsigned long *a = &addr[BIT_WORD(nr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned int bit = nr % BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mask = 1UL << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) raw_local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) res = (mask & *a) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *a &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) raw_local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) EXPORT_SYMBOL(__mips_test_and_clear_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * __mips_test_and_change_bit - Change a bit and return its old value. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * called by test_and_change_bit() if it cannot find a faster solution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * @nr: Bit to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @addr: Address to count from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) volatile unsigned long *a = &addr[BIT_WORD(nr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) unsigned int bit = nr % BITS_PER_LONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mask = 1UL << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) raw_local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) res = (mask & *a) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *a ^= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) raw_local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) EXPORT_SYMBOL(__mips_test_and_change_bit);