Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
0007  * Copyright (c) 1999, 2000  Silicon Graphics, Inc.
0008  */
0009 #include <linux/bitops.h>
0010 #include <linux/bits.h>
0011 #include <linux/irqflags.h>
0012 #include <linux/export.h>
0013 
0014 
0015 /**
0016  * __mips_set_bit - Atomically set a bit in memory.  This is called by
0017  * set_bit() if it cannot find a faster solution.
0018  * @nr: the bit to set
0019  * @addr: the address to start counting from
0020  */
0021 void __mips_set_bit(unsigned long nr, volatile unsigned long *addr)
0022 {
0023     volatile unsigned long *a = &addr[BIT_WORD(nr)];
0024     unsigned int bit = nr % BITS_PER_LONG;
0025     unsigned long mask;
0026     unsigned long flags;
0027 
0028     mask = 1UL << bit;
0029     raw_local_irq_save(flags);
0030     *a |= mask;
0031     raw_local_irq_restore(flags);
0032 }
0033 EXPORT_SYMBOL(__mips_set_bit);
0034 
0035 
0036 /**
0037  * __mips_clear_bit - Clears a bit in memory.  This is called by clear_bit() if
0038  * it cannot find a faster solution.
0039  * @nr: Bit to clear
0040  * @addr: Address to start counting from
0041  */
0042 void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr)
0043 {
0044     volatile unsigned long *a = &addr[BIT_WORD(nr)];
0045     unsigned int bit = nr % BITS_PER_LONG;
0046     unsigned long mask;
0047     unsigned long flags;
0048 
0049     mask = 1UL << bit;
0050     raw_local_irq_save(flags);
0051     *a &= ~mask;
0052     raw_local_irq_restore(flags);
0053 }
0054 EXPORT_SYMBOL(__mips_clear_bit);
0055 
0056 
0057 /**
0058  * __mips_change_bit - Toggle a bit in memory.  This is called by change_bit()
0059  * if it cannot find a faster solution.
0060  * @nr: Bit to change
0061  * @addr: Address to start counting from
0062  */
0063 void __mips_change_bit(unsigned long nr, volatile unsigned long *addr)
0064 {
0065     volatile unsigned long *a = &addr[BIT_WORD(nr)];
0066     unsigned int bit = nr % BITS_PER_LONG;
0067     unsigned long mask;
0068     unsigned long flags;
0069 
0070     mask = 1UL << bit;
0071     raw_local_irq_save(flags);
0072     *a ^= mask;
0073     raw_local_irq_restore(flags);
0074 }
0075 EXPORT_SYMBOL(__mips_change_bit);
0076 
0077 
0078 /**
0079  * __mips_test_and_set_bit_lock - Set a bit and return its old value.  This is
0080  * called by test_and_set_bit_lock() if it cannot find a faster solution.
0081  * @nr: Bit to set
0082  * @addr: Address to count from
0083  */
0084 int __mips_test_and_set_bit_lock(unsigned long nr,
0085                  volatile unsigned long *addr)
0086 {
0087     volatile unsigned long *a = &addr[BIT_WORD(nr)];
0088     unsigned int bit = nr % BITS_PER_LONG;
0089     unsigned long mask;
0090     unsigned long flags;
0091     int res;
0092 
0093     mask = 1UL << bit;
0094     raw_local_irq_save(flags);
0095     res = (mask & *a) != 0;
0096     *a |= mask;
0097     raw_local_irq_restore(flags);
0098     return res;
0099 }
0100 EXPORT_SYMBOL(__mips_test_and_set_bit_lock);
0101 
0102 
0103 /**
0104  * __mips_test_and_clear_bit - Clear a bit and return its old value.  This is
0105  * called by test_and_clear_bit() if it cannot find a faster solution.
0106  * @nr: Bit to clear
0107  * @addr: Address to count from
0108  */
0109 int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr)
0110 {
0111     volatile unsigned long *a = &addr[BIT_WORD(nr)];
0112     unsigned int bit = nr % BITS_PER_LONG;
0113     unsigned long mask;
0114     unsigned long flags;
0115     int res;
0116 
0117     mask = 1UL << bit;
0118     raw_local_irq_save(flags);
0119     res = (mask & *a) != 0;
0120     *a &= ~mask;
0121     raw_local_irq_restore(flags);
0122     return res;
0123 }
0124 EXPORT_SYMBOL(__mips_test_and_clear_bit);
0125 
0126 
0127 /**
0128  * __mips_test_and_change_bit - Change a bit and return its old value.  This is
0129  * called by test_and_change_bit() if it cannot find a faster solution.
0130  * @nr: Bit to change
0131  * @addr: Address to count from
0132  */
0133 int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr)
0134 {
0135     volatile unsigned long *a = &addr[BIT_WORD(nr)];
0136     unsigned int bit = nr % BITS_PER_LONG;
0137     unsigned long mask;
0138     unsigned long flags;
0139     int res;
0140 
0141     mask = 1UL << bit;
0142     raw_local_irq_save(flags);
0143     res = (mask & *a) != 0;
0144     *a ^= mask;
0145     raw_local_irq_restore(flags);
0146     return res;
0147 }
0148 EXPORT_SYMBOL(__mips_test_and_change_bit);