home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-arm26 / bitops.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  5.8 KB  |  208 lines

  1. /*
  2.  * Copyright 1995, Russell King.
  3.  *
  4.  * Based on the arm32 version by RMK (and others). Their copyrights apply to
  5.  * Those parts.
  6.  * Modified for arm26 by Ian Molton on 25/11/04
  7.  *
  8.  * bit 0 is the LSB of an "unsigned long" quantity.
  9.  *
  10.  * Please note that the code in this file should never be included
  11.  * from user space.  Many of these are not implemented in assembler
  12.  * since they would be too costly.  Also, they require privileged
  13.  * instructions (which are not available from user mode) to ensure
  14.  * that they are atomic.
  15.  */
  16.  
  17. #ifndef __ASM_ARM_BITOPS_H
  18. #define __ASM_ARM_BITOPS_H
  19.  
  20. #ifdef __KERNEL__
  21.  
  22. #include <linux/compiler.h>
  23. #include <asm/system.h>
  24.  
  25. #define smp_mb__before_clear_bit()    do { } while (0)
  26. #define smp_mb__after_clear_bit()    do { } while (0)
  27.  
  28. /*
  29.  * These functions are the basis of our bit ops.
  30.  *
  31.  * First, the atomic bitops. These use native endian.
  32.  */
  33. static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
  34. {
  35.     unsigned long flags;
  36.     unsigned long mask = 1UL << (bit & 31);
  37.  
  38.     p += bit >> 5;
  39.  
  40.     local_irq_save(flags);
  41.     *p |= mask;
  42.     local_irq_restore(flags);
  43. }
  44.  
  45. static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
  46. {
  47.     unsigned long flags;
  48.     unsigned long mask = 1UL << (bit & 31);
  49.  
  50.     p += bit >> 5;
  51.  
  52.     local_irq_save(flags);
  53.     *p &= ~mask;
  54.     local_irq_restore(flags);
  55. }
  56.  
  57. static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
  58. {
  59.     unsigned long flags;
  60.     unsigned long mask = 1UL << (bit & 31);
  61.  
  62.     p += bit >> 5;
  63.  
  64.     local_irq_save(flags);
  65.     *p ^= mask;
  66.     local_irq_restore(flags);
  67. }
  68.  
  69. static inline int
  70. ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
  71. {
  72.     unsigned long flags;
  73.     unsigned int res;
  74.     unsigned long mask = 1UL << (bit & 31);
  75.  
  76.     p += bit >> 5;
  77.  
  78.     local_irq_save(flags);
  79.     res = *p;
  80.     *p = res | mask;
  81.     local_irq_restore(flags);
  82.  
  83.     return res & mask;
  84. }
  85.  
  86. static inline int
  87. ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
  88. {
  89.     unsigned long flags;
  90.     unsigned int res;
  91.     unsigned long mask = 1UL << (bit & 31);
  92.  
  93.     p += bit >> 5;
  94.  
  95.     local_irq_save(flags);
  96.     res = *p;
  97.     *p = res & ~mask;
  98.     local_irq_restore(flags);
  99.  
  100.     return res & mask;
  101. }
  102.  
  103. static inline int
  104. ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
  105. {
  106.     unsigned long flags;
  107.     unsigned int res;
  108.     unsigned long mask = 1UL << (bit & 31);
  109.  
  110.     p += bit >> 5;
  111.  
  112.     local_irq_save(flags);
  113.     res = *p;
  114.     *p = res ^ mask;
  115.     local_irq_restore(flags);
  116.  
  117.     return res & mask;
  118. }
  119.  
  120. #include <asm-generic/bitops/non-atomic.h>
  121.  
  122. /*
  123.  * Little endian assembly bitops.  nr = 0 -> byte 0 bit 0.
  124.  */
  125. extern void _set_bit_le(int nr, volatile unsigned long * p);
  126. extern void _clear_bit_le(int nr, volatile unsigned long * p);
  127. extern void _change_bit_le(int nr, volatile unsigned long * p);
  128. extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
  129. extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
  130. extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
  131. extern int _find_first_zero_bit_le(const unsigned long * p, unsigned size);
  132. extern int _find_next_zero_bit_le(void * p, int size, int offset);
  133. extern int _find_first_bit_le(const unsigned long *p, unsigned size);
  134. extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
  135.  
  136. /*
  137.  * The __* form of bitops are non-atomic and may be reordered.
  138.  */
  139. #define    ATOMIC_BITOP_LE(name,nr,p)        \
  140.     (__builtin_constant_p(nr) ?        \
  141.      ____atomic_##name(nr, p) :        \
  142.      _##name##_le(nr,p))
  143.  
  144. #define NONATOMIC_BITOP(name,nr,p)        \
  145.     (____nonatomic_##name(nr, p))
  146.  
  147. /*
  148.  * These are the little endian, atomic definitions.
  149.  */
  150. #define set_bit(nr,p)            ATOMIC_BITOP_LE(set_bit,nr,p)
  151. #define clear_bit(nr,p)            ATOMIC_BITOP_LE(clear_bit,nr,p)
  152. #define change_bit(nr,p)        ATOMIC_BITOP_LE(change_bit,nr,p)
  153. #define test_and_set_bit(nr,p)        ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
  154. #define test_and_clear_bit(nr,p)    ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
  155. #define test_and_change_bit(nr,p)    ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
  156. #define find_first_zero_bit(p,sz)    _find_first_zero_bit_le(p,sz)
  157. #define find_next_zero_bit(p,sz,off)    _find_next_zero_bit_le(p,sz,off)
  158. #define find_first_bit(p,sz)        _find_first_bit_le(p,sz)
  159. #define find_next_bit(p,sz,off)        _find_next_bit_le(p,sz,off)
  160.  
  161. #define WORD_BITOFF_TO_LE(x)        ((x))
  162.  
  163. #include <asm-generic/bitops/ffz.h>
  164. #include <asm-generic/bitops/__ffs.h>
  165. #include <asm-generic/bitops/fls.h>
  166. #include <asm-generic/bitops/fls64.h>
  167. #include <asm-generic/bitops/ffs.h>
  168. #include <asm-generic/bitops/sched.h>
  169. #include <asm-generic/bitops/hweight.h>
  170.  
  171. /*
  172.  * Ext2 is defined to use little-endian byte ordering.
  173.  * These do not need to be atomic.
  174.  */
  175. #define ext2_set_bit(nr,p)            \
  176.         __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  177. #define ext2_set_bit_atomic(lock,nr,p)          \
  178.                 test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  179. #define ext2_clear_bit(nr,p)            \
  180.         __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  181. #define ext2_clear_bit_atomic(lock,nr,p)        \
  182.                 test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  183. #define ext2_test_bit(nr,p)            \
  184.         test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  185. #define ext2_find_first_zero_bit(p,sz)        \
  186.         _find_first_zero_bit_le(p,sz)
  187. #define ext2_find_next_zero_bit(p,sz,off)    \
  188.         _find_next_zero_bit_le(p,sz,off)
  189.  
  190. /*
  191.  * Minix is defined to use little-endian byte ordering.
  192.  * These do not need to be atomic.
  193.  */
  194. #define minix_set_bit(nr,p)            \
  195.         __set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  196. #define minix_test_bit(nr,p)            \
  197.         test_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  198. #define minix_test_and_set_bit(nr,p)        \
  199.         __test_and_set_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  200. #define minix_test_and_clear_bit(nr,p)        \
  201.         __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), (unsigned long *)(p))
  202. #define minix_find_first_zero_bit(p,sz)        \
  203.         _find_first_zero_bit_le((unsigned long *)(p),sz)
  204.  
  205. #endif /* __KERNEL__ */
  206.  
  207. #endif /* _ARM_BITOPS_H */
  208.