at v5.13 188 lines 5.3 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _ASM_GENERIC_BITOPS_FIND_H_ 3#define _ASM_GENERIC_BITOPS_FIND_H_ 4 5extern unsigned long _find_next_bit(const unsigned long *addr1, 6 const unsigned long *addr2, unsigned long nbits, 7 unsigned long start, unsigned long invert, unsigned long le); 8extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size); 9extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size); 10extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size); 11 12#ifndef find_next_bit 13/** 14 * find_next_bit - find the next set bit in a memory region 15 * @addr: The address to base the search on 16 * @offset: The bitnumber to start searching at 17 * @size: The bitmap size in bits 18 * 19 * Returns the bit number for the next set bit 20 * If no bits are set, returns @size. 21 */ 22static inline 23unsigned long find_next_bit(const unsigned long *addr, unsigned long size, 24 unsigned long offset) 25{ 26 if (small_const_nbits(size)) { 27 unsigned long val; 28 29 if (unlikely(offset >= size)) 30 return size; 31 32 val = *addr & GENMASK(size - 1, offset); 33 return val ? __ffs(val) : size; 34 } 35 36 return _find_next_bit(addr, NULL, size, offset, 0UL, 0); 37} 38#endif 39 40#ifndef find_next_and_bit 41/** 42 * find_next_and_bit - find the next set bit in both memory regions 43 * @addr1: The first address to base the search on 44 * @addr2: The second address to base the search on 45 * @offset: The bitnumber to start searching at 46 * @size: The bitmap size in bits 47 * 48 * Returns the bit number for the next set bit 49 * If no bits are set, returns @size. 50 */ 51static inline 52unsigned long find_next_and_bit(const unsigned long *addr1, 53 const unsigned long *addr2, unsigned long size, 54 unsigned long offset) 55{ 56 if (small_const_nbits(size)) { 57 unsigned long val; 58 59 if (unlikely(offset >= size)) 60 return size; 61 62 val = *addr1 & *addr2 & GENMASK(size - 1, offset); 63 return val ? __ffs(val) : size; 64 } 65 66 return _find_next_bit(addr1, addr2, size, offset, 0UL, 0); 67} 68#endif 69 70#ifndef find_next_zero_bit 71/** 72 * find_next_zero_bit - find the next cleared bit in a memory region 73 * @addr: The address to base the search on 74 * @offset: The bitnumber to start searching at 75 * @size: The bitmap size in bits 76 * 77 * Returns the bit number of the next zero bit 78 * If no bits are zero, returns @size. 79 */ 80static inline 81unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, 82 unsigned long offset) 83{ 84 if (small_const_nbits(size)) { 85 unsigned long val; 86 87 if (unlikely(offset >= size)) 88 return size; 89 90 val = *addr | ~GENMASK(size - 1, offset); 91 return val == ~0UL ? size : ffz(val); 92 } 93 94 return _find_next_bit(addr, NULL, size, offset, ~0UL, 0); 95} 96#endif 97 98#ifdef CONFIG_GENERIC_FIND_FIRST_BIT 99 100/** 101 * find_first_bit - find the first set bit in a memory region 102 * @addr: The address to start the search at 103 * @size: The maximum number of bits to search 104 * 105 * Returns the bit number of the first set bit. 106 * If no bits are set, returns @size. 107 */ 108static inline 109unsigned long find_first_bit(const unsigned long *addr, unsigned long size) 110{ 111 if (small_const_nbits(size)) { 112 unsigned long val = *addr & GENMASK(size - 1, 0); 113 114 return val ? __ffs(val) : size; 115 } 116 117 return _find_first_bit(addr, size); 118} 119 120/** 121 * find_first_zero_bit - find the first cleared bit in a memory region 122 * @addr: The address to start the search at 123 * @size: The maximum number of bits to search 124 * 125 * Returns the bit number of the first cleared bit. 126 * If no bits are zero, returns @size. 127 */ 128static inline 129unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) 130{ 131 if (small_const_nbits(size)) { 132 unsigned long val = *addr | ~GENMASK(size - 1, 0); 133 134 return val == ~0UL ? size : ffz(val); 135 } 136 137 return _find_first_zero_bit(addr, size); 138} 139#else /* CONFIG_GENERIC_FIND_FIRST_BIT */ 140 141#ifndef find_first_bit 142#define find_first_bit(addr, size) find_next_bit((addr), (size), 0) 143#endif 144#ifndef find_first_zero_bit 145#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0) 146#endif 147 148#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ 149 150#ifndef find_last_bit 151/** 152 * find_last_bit - find the last set bit in a memory region 153 * @addr: The address to start the search at 154 * @size: The number of bits to search 155 * 156 * Returns the bit number of the last set bit, or size. 157 */ 158static inline 159unsigned long find_last_bit(const unsigned long *addr, unsigned long size) 160{ 161 if (small_const_nbits(size)) { 162 unsigned long val = *addr & GENMASK(size - 1, 0); 163 164 return val ? __fls(val) : size; 165 } 166 167 return _find_last_bit(addr, size); 168} 169#endif 170 171/** 172 * find_next_clump8 - find next 8-bit clump with set bits in a memory region 173 * @clump: location to store copy of found clump 174 * @addr: address to base the search on 175 * @size: bitmap size in number of bits 176 * @offset: bit offset at which to start searching 177 * 178 * Returns the bit offset for the next set clump; the found clump value is 179 * copied to the location pointed by @clump. If no bits are set, returns @size. 180 */ 181extern unsigned long find_next_clump8(unsigned long *clump, 182 const unsigned long *addr, 183 unsigned long size, unsigned long offset); 184 185#define find_first_clump8(clump, bits, size) \ 186 find_next_clump8((clump), (bits), (size), 0) 187 188#endif /*_ASM_GENERIC_BITOPS_FIND_H_ */