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 */ 33static 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 45static 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 57static 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 69static 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 86static 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 103static 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 */ 125extern void _set_bit_le(int nr, volatile unsigned long * p); 126extern void _clear_bit_le(int nr, volatile unsigned long * p); 127extern void _change_bit_le(int nr, volatile unsigned long * p); 128extern int _test_and_set_bit_le(int nr, volatile unsigned long * p); 129extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p); 130extern int _test_and_change_bit_le(int nr, volatile unsigned long * p); 131extern int _find_first_zero_bit_le(const unsigned long * p, unsigned size); 132extern int _find_next_zero_bit_le(void * p, int size, int offset); 133extern int _find_first_bit_le(const unsigned long *p, unsigned size); 134extern 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