bitops.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /* asm/bitops.h for Linux/CRIS
  2. *
  3. * TODO: asm versions if speed is needed
  4. *
  5. * All bit operations return 0 if the bit was cleared before the
  6. * operation and != 0 if it was not.
  7. *
  8. * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  9. */
  10. #ifndef _CRIS_BITOPS_H
  11. #define _CRIS_BITOPS_H
  12. /* Currently this is unsuitable for consumption outside the kernel. */
  13. #ifdef __KERNEL__
  14. #include <asm/arch/bitops.h>
  15. #include <asm/system.h>
  16. #include <asm/atomic.h>
  17. #include <linux/compiler.h>
  18. /*
  19. * Some hacks to defeat gcc over-optimizations..
  20. */
  21. struct __dummy { unsigned long a[100]; };
  22. #define ADDR (*(struct __dummy *) addr)
  23. #define CONST_ADDR (*(const struct __dummy *) addr)
  24. /*
  25. * set_bit - Atomically set a bit in memory
  26. * @nr: the bit to set
  27. * @addr: the address to start counting from
  28. *
  29. * This function is atomic and may not be reordered. See __set_bit()
  30. * if you do not require the atomic guarantees.
  31. * Note that @nr may be almost arbitrarily large; this function is not
  32. * restricted to acting on a single-word quantity.
  33. */
  34. #define set_bit(nr, addr) (void)test_and_set_bit(nr, addr)
  35. /*
  36. * clear_bit - Clears a bit in memory
  37. * @nr: Bit to clear
  38. * @addr: Address to start counting from
  39. *
  40. * clear_bit() is atomic and may not be reordered. However, it does
  41. * not contain a memory barrier, so if it is used for locking purposes,
  42. * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  43. * in order to ensure changes are visible on other processors.
  44. */
  45. #define clear_bit(nr, addr) (void)test_and_clear_bit(nr, addr)
  46. /*
  47. * change_bit - Toggle a bit in memory
  48. * @nr: Bit to change
  49. * @addr: Address to start counting from
  50. *
  51. * change_bit() is atomic and may not be reordered.
  52. * Note that @nr may be almost arbitrarily large; this function is not
  53. * restricted to acting on a single-word quantity.
  54. */
  55. #define change_bit(nr, addr) (void)test_and_change_bit(nr, addr)
  56. /**
  57. * test_and_set_bit - Set a bit and return its old value
  58. * @nr: Bit to set
  59. * @addr: Address to count from
  60. *
  61. * This operation is atomic and cannot be reordered.
  62. * It also implies a memory barrier.
  63. */
  64. static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
  65. {
  66. unsigned int mask, retval;
  67. unsigned long flags;
  68. unsigned int *adr = (unsigned int *)addr;
  69. adr += nr >> 5;
  70. mask = 1 << (nr & 0x1f);
  71. cris_atomic_save(addr, flags);
  72. retval = (mask & *adr) != 0;
  73. *adr |= mask;
  74. cris_atomic_restore(addr, flags);
  75. return retval;
  76. }
  77. /*
  78. * clear_bit() doesn't provide any barrier for the compiler.
  79. */
  80. #define smp_mb__before_clear_bit() barrier()
  81. #define smp_mb__after_clear_bit() barrier()
  82. /**
  83. * test_and_clear_bit - Clear a bit and return its old value
  84. * @nr: Bit to clear
  85. * @addr: Address to count from
  86. *
  87. * This operation is atomic and cannot be reordered.
  88. * It also implies a memory barrier.
  89. */
  90. static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  91. {
  92. unsigned int mask, retval;
  93. unsigned long flags;
  94. unsigned int *adr = (unsigned int *)addr;
  95. adr += nr >> 5;
  96. mask = 1 << (nr & 0x1f);
  97. cris_atomic_save(addr, flags);
  98. retval = (mask & *adr) != 0;
  99. *adr &= ~mask;
  100. cris_atomic_restore(addr, flags);
  101. return retval;
  102. }
  103. /**
  104. * test_and_change_bit - Change a bit and return its old value
  105. * @nr: Bit to change
  106. * @addr: Address to count from
  107. *
  108. * This operation is atomic and cannot be reordered.
  109. * It also implies a memory barrier.
  110. */
  111. static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
  112. {
  113. unsigned int mask, retval;
  114. unsigned long flags;
  115. unsigned int *adr = (unsigned int *)addr;
  116. adr += nr >> 5;
  117. mask = 1 << (nr & 0x1f);
  118. cris_atomic_save(addr, flags);
  119. retval = (mask & *adr) != 0;
  120. *adr ^= mask;
  121. cris_atomic_restore(addr, flags);
  122. return retval;
  123. }
  124. #include <asm-generic/bitops/non-atomic.h>
  125. /*
  126. * Since we define it "external", it collides with the built-in
  127. * definition, which doesn't have the same semantics. We don't want to
  128. * use -fno-builtin, so just hide the name ffs.
  129. */
  130. #define ffs kernel_ffs
  131. #include <asm-generic/bitops/fls.h>
  132. #include <asm-generic/bitops/fls64.h>
  133. #include <asm-generic/bitops/hweight.h>
  134. #include <asm-generic/bitops/find.h>
  135. #include <asm-generic/bitops/ext2-non-atomic.h>
  136. #define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a)
  137. #define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a)
  138. #include <asm-generic/bitops/minix.h>
  139. #include <asm-generic/bitops/sched.h>
  140. #endif /* __KERNEL__ */
  141. #endif /* _CRIS_BITOPS_H */