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