11/* SPDX-License-Identifier: GPL-2.0 */
2- #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
3- #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
2+ #ifndef _TOOLS_LINUX_FIND_H_
3+ #define _TOOLS_LINUX_FIND_H_
4+
5+ #ifndef _TOOLS_LINUX_BITMAP_H
6+ #error tools: only <linux/bitmap.h> can be included directly
7+ #endif
8+
9+ #include <linux/bitops.h>
410
511extern unsigned long _find_next_bit (const unsigned long * addr1 ,
612 const unsigned long * addr2 , unsigned long nbits ,
713 unsigned long start , unsigned long invert , unsigned long le );
814extern unsigned long _find_first_bit (const unsigned long * addr , unsigned long size );
15+ extern unsigned long _find_first_and_bit (const unsigned long * addr1 ,
16+ const unsigned long * addr2 , unsigned long size );
917extern unsigned long _find_first_zero_bit (const unsigned long * addr , unsigned long size );
1018extern unsigned long _find_last_bit (const unsigned long * addr , unsigned long size );
1119
@@ -96,7 +104,6 @@ unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
96104#endif
97105
98106#ifndef find_first_bit
99-
100107/**
101108 * find_first_bit - find the first set bit in a memory region
102109 * @addr: The address to start the search at
@@ -116,11 +123,34 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
116123
117124 return _find_first_bit (addr , size );
118125}
126+ #endif
127+
128+ #ifndef find_first_and_bit
129+ /**
130+ * find_first_and_bit - find the first set bit in both memory regions
131+ * @addr1: The first address to base the search on
132+ * @addr2: The second address to base the search on
133+ * @size: The bitmap size in bits
134+ *
135+ * Returns the bit number for the next set bit
136+ * If no bits are set, returns @size.
137+ */
138+ static inline
139+ unsigned long find_first_and_bit (const unsigned long * addr1 ,
140+ const unsigned long * addr2 ,
141+ unsigned long size )
142+ {
143+ if (small_const_nbits (size )) {
144+ unsigned long val = * addr1 & * addr2 & GENMASK (size - 1 , 0 );
119145
120- #endif /* find_first_bit */
146+ return val ? __ffs (val ) : size ;
147+ }
121148
122- #ifndef find_first_zero_bit
149+ return _find_first_and_bit (addr1 , addr2 , size );
150+ }
151+ #endif
123152
153+ #ifndef find_first_zero_bit
124154/**
125155 * find_first_zero_bit - find the first cleared bit in a memory region
126156 * @addr: The address to start the search at
@@ -142,4 +172,43 @@ unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
142172}
143173#endif
144174
145- #endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
175+ #ifndef find_last_bit
176+ /**
177+ * find_last_bit - find the last set bit in a memory region
178+ * @addr: The address to start the search at
179+ * @size: The number of bits to search
180+ *
181+ * Returns the bit number of the last set bit, or size.
182+ */
183+ static inline
184+ unsigned long find_last_bit (const unsigned long * addr , unsigned long size )
185+ {
186+ if (small_const_nbits (size )) {
187+ unsigned long val = * addr & GENMASK (size - 1 , 0 );
188+
189+ return val ? __fls (val ) : size ;
190+ }
191+
192+ return _find_last_bit (addr , size );
193+ }
194+ #endif
195+
196+ /**
197+ * find_next_clump8 - find next 8-bit clump with set bits in a memory region
198+ * @clump: location to store copy of found clump
199+ * @addr: address to base the search on
200+ * @size: bitmap size in number of bits
201+ * @offset: bit offset at which to start searching
202+ *
203+ * Returns the bit offset for the next set clump; the found clump value is
204+ * copied to the location pointed by @clump. If no bits are set, returns @size.
205+ */
206+ extern unsigned long find_next_clump8 (unsigned long * clump ,
207+ const unsigned long * addr ,
208+ unsigned long size , unsigned long offset );
209+
210+ #define find_first_clump8 (clump , bits , size ) \
211+ find_next_clump8((clump), (bits), (size), 0)
212+
213+
214+ #endif /*__LINUX_FIND_H_ */
0 commit comments