147d8c156SYury Norov /* SPDX-License-Identifier: GPL-2.0 */
247d8c156SYury Norov #ifndef __LINUX_FIND_H_
347d8c156SYury Norov #define __LINUX_FIND_H_
447d8c156SYury Norov
547d8c156SYury Norov #ifndef __LINUX_BITMAP_H
647d8c156SYury Norov #error only <linux/bitmap.h> can be included directly
747d8c156SYury Norov #endif
847d8c156SYury Norov
947d8c156SYury Norov #include <linux/bitops.h>
1047d8c156SYury Norov
11e79864f3SYury Norov unsigned long _find_next_bit(const unsigned long *addr1, unsigned long nbits,
12e79864f3SYury Norov unsigned long start);
13e79864f3SYury Norov unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2,
14e79864f3SYury Norov unsigned long nbits, unsigned long start);
1590d48290SValentin Schneider unsigned long _find_next_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
1690d48290SValentin Schneider unsigned long nbits, unsigned long start);
171470afefSDave Chinner unsigned long _find_next_or_bit(const unsigned long *addr1, const unsigned long *addr2,
181470afefSDave Chinner unsigned long nbits, unsigned long start);
19e79864f3SYury Norov unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,
20e79864f3SYury Norov unsigned long start);
2147d8c156SYury Norov extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size);
223cea8d47SYury Norov unsigned long __find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n);
233cea8d47SYury Norov unsigned long __find_nth_and_bit(const unsigned long *addr1, const unsigned long *addr2,
243cea8d47SYury Norov unsigned long size, unsigned long n);
253cea8d47SYury Norov unsigned long __find_nth_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
263cea8d47SYury Norov unsigned long size, unsigned long n);
2743245117SYury Norov unsigned long __find_nth_and_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
2843245117SYury Norov const unsigned long *addr3, unsigned long size,
2943245117SYury Norov unsigned long n);
30f68edc92SYury Norov extern unsigned long _find_first_and_bit(const unsigned long *addr1,
31f68edc92SYury Norov const unsigned long *addr2, unsigned long size);
32cdc66553SDawei Li unsigned long _find_first_and_and_bit(const unsigned long *addr1, const unsigned long *addr2,
33cdc66553SDawei Li const unsigned long *addr3, unsigned long size);
3447d8c156SYury Norov extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size);
3547d8c156SYury Norov extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size);
3647d8c156SYury Norov
3714a99e13SYury Norov #ifdef __BIG_ENDIAN
3814a99e13SYury Norov unsigned long _find_first_zero_bit_le(const unsigned long *addr, unsigned long size);
39e79864f3SYury Norov unsigned long _find_next_zero_bit_le(const unsigned long *addr, unsigned
40e79864f3SYury Norov long size, unsigned long offset);
41e79864f3SYury Norov unsigned long _find_next_bit_le(const unsigned long *addr, unsigned
42e79864f3SYury Norov long size, unsigned long offset);
4314a99e13SYury Norov #endif
4414a99e13SYury Norov
4547d8c156SYury Norov #ifndef find_next_bit
4647d8c156SYury Norov /**
4747d8c156SYury Norov * find_next_bit - find the next set bit in a memory region
4847d8c156SYury Norov * @addr: The address to base the search on
4947d8c156SYury Norov * @size: The bitmap size in bits
506d7131bdSAnna-Maria Behnsen * @offset: The bitnumber to start searching at
5147d8c156SYury Norov *
5247d8c156SYury Norov * Returns the bit number for the next set bit
5347d8c156SYury Norov * If no bits are set, returns @size.
5447d8c156SYury Norov */
55*fda1dd3cSYury Norov static __always_inline
find_next_bit(const unsigned long * addr,unsigned long size,unsigned long offset)5647d8c156SYury Norov unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
5747d8c156SYury Norov unsigned long offset)
5847d8c156SYury Norov {
5947d8c156SYury Norov if (small_const_nbits(size)) {
6047d8c156SYury Norov unsigned long val;
6147d8c156SYury Norov
6247d8c156SYury Norov if (unlikely(offset >= size))
6347d8c156SYury Norov return size;
6447d8c156SYury Norov
6547d8c156SYury Norov val = *addr & GENMASK(size - 1, offset);
6647d8c156SYury Norov return val ? __ffs(val) : size;
6747d8c156SYury Norov }
6847d8c156SYury Norov
69e79864f3SYury Norov return _find_next_bit(addr, size, offset);
7047d8c156SYury Norov }
7147d8c156SYury Norov #endif
7247d8c156SYury Norov
7347d8c156SYury Norov #ifndef find_next_and_bit
7447d8c156SYury Norov /**
7547d8c156SYury Norov * find_next_and_bit - find the next set bit in both memory regions
7647d8c156SYury Norov * @addr1: The first address to base the search on
7747d8c156SYury Norov * @addr2: The second address to base the search on
7847d8c156SYury Norov * @size: The bitmap size in bits
796d7131bdSAnna-Maria Behnsen * @offset: The bitnumber to start searching at
8047d8c156SYury Norov *
8147d8c156SYury Norov * Returns the bit number for the next set bit
8247d8c156SYury Norov * If no bits are set, returns @size.
8347d8c156SYury Norov */
84*fda1dd3cSYury Norov static __always_inline
find_next_and_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)8547d8c156SYury Norov unsigned long find_next_and_bit(const unsigned long *addr1,
8647d8c156SYury Norov const unsigned long *addr2, unsigned long size,
8747d8c156SYury Norov unsigned long offset)
8847d8c156SYury Norov {
8947d8c156SYury Norov if (small_const_nbits(size)) {
9047d8c156SYury Norov unsigned long val;
9147d8c156SYury Norov
9247d8c156SYury Norov if (unlikely(offset >= size))
9347d8c156SYury Norov return size;
9447d8c156SYury Norov
9547d8c156SYury Norov val = *addr1 & *addr2 & GENMASK(size - 1, offset);
9647d8c156SYury Norov return val ? __ffs(val) : size;
9747d8c156SYury Norov }
9847d8c156SYury Norov
99e79864f3SYury Norov return _find_next_and_bit(addr1, addr2, size, offset);
10047d8c156SYury Norov }
10147d8c156SYury Norov #endif
10247d8c156SYury Norov
10390d48290SValentin Schneider #ifndef find_next_andnot_bit
10490d48290SValentin Schneider /**
10590d48290SValentin Schneider * find_next_andnot_bit - find the next set bit in *addr1 excluding all the bits
10690d48290SValentin Schneider * in *addr2
10790d48290SValentin Schneider * @addr1: The first address to base the search on
10890d48290SValentin Schneider * @addr2: The second address to base the search on
10990d48290SValentin Schneider * @size: The bitmap size in bits
11090d48290SValentin Schneider * @offset: The bitnumber to start searching at
11190d48290SValentin Schneider *
11290d48290SValentin Schneider * Returns the bit number for the next set bit
11390d48290SValentin Schneider * If no bits are set, returns @size.
11490d48290SValentin Schneider */
115*fda1dd3cSYury Norov static __always_inline
find_next_andnot_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)11690d48290SValentin Schneider unsigned long find_next_andnot_bit(const unsigned long *addr1,
11790d48290SValentin Schneider const unsigned long *addr2, unsigned long size,
11890d48290SValentin Schneider unsigned long offset)
11990d48290SValentin Schneider {
12090d48290SValentin Schneider if (small_const_nbits(size)) {
12190d48290SValentin Schneider unsigned long val;
12290d48290SValentin Schneider
12390d48290SValentin Schneider if (unlikely(offset >= size))
12490d48290SValentin Schneider return size;
12590d48290SValentin Schneider
12690d48290SValentin Schneider val = *addr1 & ~*addr2 & GENMASK(size - 1, offset);
12790d48290SValentin Schneider return val ? __ffs(val) : size;
12890d48290SValentin Schneider }
12990d48290SValentin Schneider
13090d48290SValentin Schneider return _find_next_andnot_bit(addr1, addr2, size, offset);
13190d48290SValentin Schneider }
13290d48290SValentin Schneider #endif
13390d48290SValentin Schneider
1341470afefSDave Chinner #ifndef find_next_or_bit
1351470afefSDave Chinner /**
1361470afefSDave Chinner * find_next_or_bit - find the next set bit in either memory regions
1371470afefSDave Chinner * @addr1: The first address to base the search on
1381470afefSDave Chinner * @addr2: The second address to base the search on
1391470afefSDave Chinner * @size: The bitmap size in bits
1401470afefSDave Chinner * @offset: The bitnumber to start searching at
1411470afefSDave Chinner *
1421470afefSDave Chinner * Returns the bit number for the next set bit
1431470afefSDave Chinner * If no bits are set, returns @size.
1441470afefSDave Chinner */
145*fda1dd3cSYury Norov static __always_inline
find_next_or_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)1461470afefSDave Chinner unsigned long find_next_or_bit(const unsigned long *addr1,
1471470afefSDave Chinner const unsigned long *addr2, unsigned long size,
1481470afefSDave Chinner unsigned long offset)
1491470afefSDave Chinner {
1501470afefSDave Chinner if (small_const_nbits(size)) {
1511470afefSDave Chinner unsigned long val;
1521470afefSDave Chinner
1531470afefSDave Chinner if (unlikely(offset >= size))
1541470afefSDave Chinner return size;
1551470afefSDave Chinner
1561470afefSDave Chinner val = (*addr1 | *addr2) & GENMASK(size - 1, offset);
1571470afefSDave Chinner return val ? __ffs(val) : size;
1581470afefSDave Chinner }
1591470afefSDave Chinner
1601470afefSDave Chinner return _find_next_or_bit(addr1, addr2, size, offset);
1611470afefSDave Chinner }
1621470afefSDave Chinner #endif
1631470afefSDave Chinner
16447d8c156SYury Norov #ifndef find_next_zero_bit
16547d8c156SYury Norov /**
16647d8c156SYury Norov * find_next_zero_bit - find the next cleared bit in a memory region
16747d8c156SYury Norov * @addr: The address to base the search on
16847d8c156SYury Norov * @size: The bitmap size in bits
1696d7131bdSAnna-Maria Behnsen * @offset: The bitnumber to start searching at
17047d8c156SYury Norov *
17147d8c156SYury Norov * Returns the bit number of the next zero bit
17247d8c156SYury Norov * If no bits are zero, returns @size.
17347d8c156SYury Norov */
174*fda1dd3cSYury Norov static __always_inline
find_next_zero_bit(const unsigned long * addr,unsigned long size,unsigned long offset)17547d8c156SYury Norov unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
17647d8c156SYury Norov unsigned long offset)
17747d8c156SYury Norov {
17847d8c156SYury Norov if (small_const_nbits(size)) {
17947d8c156SYury Norov unsigned long val;
18047d8c156SYury Norov
18147d8c156SYury Norov if (unlikely(offset >= size))
18247d8c156SYury Norov return size;
18347d8c156SYury Norov
18447d8c156SYury Norov val = *addr | ~GENMASK(size - 1, offset);
18547d8c156SYury Norov return val == ~0UL ? size : ffz(val);
18647d8c156SYury Norov }
18747d8c156SYury Norov
188e79864f3SYury Norov return _find_next_zero_bit(addr, size, offset);
18947d8c156SYury Norov }
19047d8c156SYury Norov #endif
19147d8c156SYury Norov
19247d8c156SYury Norov #ifndef find_first_bit
19347d8c156SYury Norov /**
19447d8c156SYury Norov * find_first_bit - find the first set bit in a memory region
19547d8c156SYury Norov * @addr: The address to start the search at
19647d8c156SYury Norov * @size: The maximum number of bits to search
19747d8c156SYury Norov *
19847d8c156SYury Norov * Returns the bit number of the first set bit.
19947d8c156SYury Norov * If no bits are set, returns @size.
20047d8c156SYury Norov */
201*fda1dd3cSYury Norov static __always_inline
find_first_bit(const unsigned long * addr,unsigned long size)20247d8c156SYury Norov unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
20347d8c156SYury Norov {
20447d8c156SYury Norov if (small_const_nbits(size)) {
20547d8c156SYury Norov unsigned long val = *addr & GENMASK(size - 1, 0);
20647d8c156SYury Norov
20747d8c156SYury Norov return val ? __ffs(val) : size;
20847d8c156SYury Norov }
20947d8c156SYury Norov
21047d8c156SYury Norov return _find_first_bit(addr, size);
21147d8c156SYury Norov }
21247d8c156SYury Norov #endif
21347d8c156SYury Norov
2143cea8d47SYury Norov /**
2153cea8d47SYury Norov * find_nth_bit - find N'th set bit in a memory region
2163cea8d47SYury Norov * @addr: The address to start the search at
2173cea8d47SYury Norov * @size: The maximum number of bits to search
2183cea8d47SYury Norov * @n: The number of set bit, which position is needed, counting from 0
2193cea8d47SYury Norov *
2203cea8d47SYury Norov * The following is semantically equivalent:
2213cea8d47SYury Norov * idx = find_nth_bit(addr, size, 0);
2223cea8d47SYury Norov * idx = find_first_bit(addr, size);
2233cea8d47SYury Norov *
2243cea8d47SYury Norov * Returns the bit number of the N'th set bit.
2250b2811baSYury Norov * If no such, returns >= @size.
2263cea8d47SYury Norov */
227*fda1dd3cSYury Norov static __always_inline
find_nth_bit(const unsigned long * addr,unsigned long size,unsigned long n)2283cea8d47SYury Norov unsigned long find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n)
2293cea8d47SYury Norov {
2303cea8d47SYury Norov if (n >= size)
2313cea8d47SYury Norov return size;
2323cea8d47SYury Norov
2333cea8d47SYury Norov if (small_const_nbits(size)) {
2343cea8d47SYury Norov unsigned long val = *addr & GENMASK(size - 1, 0);
2353cea8d47SYury Norov
2363cea8d47SYury Norov return val ? fns(val, n) : size;
2373cea8d47SYury Norov }
2383cea8d47SYury Norov
2393cea8d47SYury Norov return __find_nth_bit(addr, size, n);
2403cea8d47SYury Norov }
2413cea8d47SYury Norov
2423cea8d47SYury Norov /**
2433cea8d47SYury Norov * find_nth_and_bit - find N'th set bit in 2 memory regions
2443cea8d47SYury Norov * @addr1: The 1st address to start the search at
2453cea8d47SYury Norov * @addr2: The 2nd address to start the search at
2463cea8d47SYury Norov * @size: The maximum number of bits to search
2473cea8d47SYury Norov * @n: The number of set bit, which position is needed, counting from 0
2483cea8d47SYury Norov *
2493cea8d47SYury Norov * Returns the bit number of the N'th set bit.
2503cea8d47SYury Norov * If no such, returns @size.
2513cea8d47SYury Norov */
252*fda1dd3cSYury Norov static __always_inline
find_nth_and_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long n)2533cea8d47SYury Norov unsigned long find_nth_and_bit(const unsigned long *addr1, const unsigned long *addr2,
2543cea8d47SYury Norov unsigned long size, unsigned long n)
2553cea8d47SYury Norov {
2563cea8d47SYury Norov if (n >= size)
2573cea8d47SYury Norov return size;
2583cea8d47SYury Norov
2593cea8d47SYury Norov if (small_const_nbits(size)) {
2603cea8d47SYury Norov unsigned long val = *addr1 & *addr2 & GENMASK(size - 1, 0);
2613cea8d47SYury Norov
2623cea8d47SYury Norov return val ? fns(val, n) : size;
2633cea8d47SYury Norov }
2643cea8d47SYury Norov
2653cea8d47SYury Norov return __find_nth_and_bit(addr1, addr2, size, n);
2663cea8d47SYury Norov }
2673cea8d47SYury Norov
2683cea8d47SYury Norov /**
2693cea8d47SYury Norov * find_nth_andnot_bit - find N'th set bit in 2 memory regions,
2703cea8d47SYury Norov * flipping bits in 2nd region
2713cea8d47SYury Norov * @addr1: The 1st address to start the search at
2723cea8d47SYury Norov * @addr2: The 2nd address to start the search at
2733cea8d47SYury Norov * @size: The maximum number of bits to search
2743cea8d47SYury Norov * @n: The number of set bit, which position is needed, counting from 0
2753cea8d47SYury Norov *
2763cea8d47SYury Norov * Returns the bit number of the N'th set bit.
2773cea8d47SYury Norov * If no such, returns @size.
2783cea8d47SYury Norov */
279*fda1dd3cSYury Norov static __always_inline
find_nth_andnot_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long n)2803cea8d47SYury Norov unsigned long find_nth_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
2813cea8d47SYury Norov unsigned long size, unsigned long n)
2823cea8d47SYury Norov {
2833cea8d47SYury Norov if (n >= size)
2843cea8d47SYury Norov return size;
2853cea8d47SYury Norov
2863cea8d47SYury Norov if (small_const_nbits(size)) {
2873cea8d47SYury Norov unsigned long val = *addr1 & (~*addr2) & GENMASK(size - 1, 0);
2883cea8d47SYury Norov
2893cea8d47SYury Norov return val ? fns(val, n) : size;
2903cea8d47SYury Norov }
2913cea8d47SYury Norov
2923cea8d47SYury Norov return __find_nth_andnot_bit(addr1, addr2, size, n);
2933cea8d47SYury Norov }
2943cea8d47SYury Norov
29543245117SYury Norov /**
29643245117SYury Norov * find_nth_and_andnot_bit - find N'th set bit in 2 memory regions,
29743245117SYury Norov * excluding those set in 3rd region
29843245117SYury Norov * @addr1: The 1st address to start the search at
29943245117SYury Norov * @addr2: The 2nd address to start the search at
30043245117SYury Norov * @addr3: The 3rd address to start the search at
30143245117SYury Norov * @size: The maximum number of bits to search
30243245117SYury Norov * @n: The number of set bit, which position is needed, counting from 0
30343245117SYury Norov *
30443245117SYury Norov * Returns the bit number of the N'th set bit.
30543245117SYury Norov * If no such, returns @size.
30643245117SYury Norov */
30743245117SYury Norov static __always_inline
find_nth_and_andnot_bit(const unsigned long * addr1,const unsigned long * addr2,const unsigned long * addr3,unsigned long size,unsigned long n)30843245117SYury Norov unsigned long find_nth_and_andnot_bit(const unsigned long *addr1,
30943245117SYury Norov const unsigned long *addr2,
31043245117SYury Norov const unsigned long *addr3,
31143245117SYury Norov unsigned long size, unsigned long n)
31243245117SYury Norov {
31343245117SYury Norov if (n >= size)
31443245117SYury Norov return size;
31543245117SYury Norov
31643245117SYury Norov if (small_const_nbits(size)) {
31743245117SYury Norov unsigned long val = *addr1 & *addr2 & (~*addr3) & GENMASK(size - 1, 0);
31843245117SYury Norov
31943245117SYury Norov return val ? fns(val, n) : size;
32043245117SYury Norov }
32143245117SYury Norov
32243245117SYury Norov return __find_nth_and_andnot_bit(addr1, addr2, addr3, size, n);
32343245117SYury Norov }
32443245117SYury Norov
325f68edc92SYury Norov #ifndef find_first_and_bit
326f68edc92SYury Norov /**
327f68edc92SYury Norov * find_first_and_bit - find the first set bit in both memory regions
328f68edc92SYury Norov * @addr1: The first address to base the search on
329f68edc92SYury Norov * @addr2: The second address to base the search on
330f68edc92SYury Norov * @size: The bitmap size in bits
331f68edc92SYury Norov *
332f68edc92SYury Norov * Returns the bit number for the next set bit
333f68edc92SYury Norov * If no bits are set, returns @size.
334f68edc92SYury Norov */
335*fda1dd3cSYury Norov static __always_inline
find_first_and_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size)336f68edc92SYury Norov unsigned long find_first_and_bit(const unsigned long *addr1,
337f68edc92SYury Norov const unsigned long *addr2,
338f68edc92SYury Norov unsigned long size)
339f68edc92SYury Norov {
340f68edc92SYury Norov if (small_const_nbits(size)) {
341f68edc92SYury Norov unsigned long val = *addr1 & *addr2 & GENMASK(size - 1, 0);
342f68edc92SYury Norov
343f68edc92SYury Norov return val ? __ffs(val) : size;
344f68edc92SYury Norov }
345f68edc92SYury Norov
346f68edc92SYury Norov return _find_first_and_bit(addr1, addr2, size);
347f68edc92SYury Norov }
348f68edc92SYury Norov #endif
349f68edc92SYury Norov
350cdc66553SDawei Li /**
351cdc66553SDawei Li * find_first_and_and_bit - find the first set bit in 3 memory regions
352cdc66553SDawei Li * @addr1: The first address to base the search on
353cdc66553SDawei Li * @addr2: The second address to base the search on
354cdc66553SDawei Li * @addr3: The third address to base the search on
355cdc66553SDawei Li * @size: The bitmap size in bits
356cdc66553SDawei Li *
357cdc66553SDawei Li * Returns the bit number for the first set bit
358cdc66553SDawei Li * If no bits are set, returns @size.
359cdc66553SDawei Li */
360*fda1dd3cSYury Norov static __always_inline
find_first_and_and_bit(const unsigned long * addr1,const unsigned long * addr2,const unsigned long * addr3,unsigned long size)361cdc66553SDawei Li unsigned long find_first_and_and_bit(const unsigned long *addr1,
362cdc66553SDawei Li const unsigned long *addr2,
363cdc66553SDawei Li const unsigned long *addr3,
364cdc66553SDawei Li unsigned long size)
365cdc66553SDawei Li {
366cdc66553SDawei Li if (small_const_nbits(size)) {
367cdc66553SDawei Li unsigned long val = *addr1 & *addr2 & *addr3 & GENMASK(size - 1, 0);
368cdc66553SDawei Li
369cdc66553SDawei Li return val ? __ffs(val) : size;
370cdc66553SDawei Li }
371cdc66553SDawei Li
372cdc66553SDawei Li return _find_first_and_and_bit(addr1, addr2, addr3, size);
373cdc66553SDawei Li }
374cdc66553SDawei Li
37547d8c156SYury Norov #ifndef find_first_zero_bit
37647d8c156SYury Norov /**
37747d8c156SYury Norov * find_first_zero_bit - find the first cleared bit in a memory region
37847d8c156SYury Norov * @addr: The address to start the search at
37947d8c156SYury Norov * @size: The maximum number of bits to search
38047d8c156SYury Norov *
38147d8c156SYury Norov * Returns the bit number of the first cleared bit.
38247d8c156SYury Norov * If no bits are zero, returns @size.
38347d8c156SYury Norov */
384*fda1dd3cSYury Norov static __always_inline
find_first_zero_bit(const unsigned long * addr,unsigned long size)38547d8c156SYury Norov unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
38647d8c156SYury Norov {
38747d8c156SYury Norov if (small_const_nbits(size)) {
38847d8c156SYury Norov unsigned long val = *addr | ~GENMASK(size - 1, 0);
38947d8c156SYury Norov
39047d8c156SYury Norov return val == ~0UL ? size : ffz(val);
39147d8c156SYury Norov }
39247d8c156SYury Norov
39347d8c156SYury Norov return _find_first_zero_bit(addr, size);
39447d8c156SYury Norov }
39547d8c156SYury Norov #endif
39647d8c156SYury Norov
39747d8c156SYury Norov #ifndef find_last_bit
39847d8c156SYury Norov /**
39947d8c156SYury Norov * find_last_bit - find the last set bit in a memory region
40047d8c156SYury Norov * @addr: The address to start the search at
40147d8c156SYury Norov * @size: The number of bits to search
40247d8c156SYury Norov *
40347d8c156SYury Norov * Returns the bit number of the last set bit, or size.
40447d8c156SYury Norov */
405*fda1dd3cSYury Norov static __always_inline
find_last_bit(const unsigned long * addr,unsigned long size)40647d8c156SYury Norov unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
40747d8c156SYury Norov {
40847d8c156SYury Norov if (small_const_nbits(size)) {
40947d8c156SYury Norov unsigned long val = *addr & GENMASK(size - 1, 0);
41047d8c156SYury Norov
41147d8c156SYury Norov return val ? __fls(val) : size;
41247d8c156SYury Norov }
41347d8c156SYury Norov
41447d8c156SYury Norov return _find_last_bit(addr, size);
41547d8c156SYury Norov }
41647d8c156SYury Norov #endif
41747d8c156SYury Norov
41847d8c156SYury Norov /**
4196cc18331SYury Norov * find_next_and_bit_wrap - find the next set bit in both memory regions
4206cc18331SYury Norov * @addr1: The first address to base the search on
4216cc18331SYury Norov * @addr2: The second address to base the search on
4226cc18331SYury Norov * @size: The bitmap size in bits
4236cc18331SYury Norov * @offset: The bitnumber to start searching at
4246cc18331SYury Norov *
4256cc18331SYury Norov * Returns the bit number for the next set bit, or first set bit up to @offset
4266cc18331SYury Norov * If no bits are set, returns @size.
4276cc18331SYury Norov */
428*fda1dd3cSYury Norov static __always_inline
find_next_and_bit_wrap(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)4296cc18331SYury Norov unsigned long find_next_and_bit_wrap(const unsigned long *addr1,
4306cc18331SYury Norov const unsigned long *addr2,
4316cc18331SYury Norov unsigned long size, unsigned long offset)
4326cc18331SYury Norov {
4336cc18331SYury Norov unsigned long bit = find_next_and_bit(addr1, addr2, size, offset);
4346cc18331SYury Norov
43527c82f14SYury Norov if (bit < size || offset == 0)
4366cc18331SYury Norov return bit;
4376cc18331SYury Norov
4386cc18331SYury Norov bit = find_first_and_bit(addr1, addr2, offset);
4396cc18331SYury Norov return bit < offset ? bit : size;
4406cc18331SYury Norov }
4416cc18331SYury Norov
4426cc18331SYury Norov /**
44392697139SGuanjun * find_next_bit_wrap - find the next set bit in a memory region
44492697139SGuanjun * @addr: The address to base the search on
4456cc18331SYury Norov * @size: The bitmap size in bits
4466cc18331SYury Norov * @offset: The bitnumber to start searching at
4476cc18331SYury Norov *
4486cc18331SYury Norov * Returns the bit number for the next set bit, or first set bit up to @offset
4496cc18331SYury Norov * If no bits are set, returns @size.
4506cc18331SYury Norov */
451*fda1dd3cSYury Norov static __always_inline
find_next_bit_wrap(const unsigned long * addr,unsigned long size,unsigned long offset)4526cc18331SYury Norov unsigned long find_next_bit_wrap(const unsigned long *addr,
4536cc18331SYury Norov unsigned long size, unsigned long offset)
4546cc18331SYury Norov {
4556cc18331SYury Norov unsigned long bit = find_next_bit(addr, size, offset);
4566cc18331SYury Norov
45727c82f14SYury Norov if (bit < size || offset == 0)
4586cc18331SYury Norov return bit;
4596cc18331SYury Norov
4606cc18331SYury Norov bit = find_first_bit(addr, offset);
4616cc18331SYury Norov return bit < offset ? bit : size;
4626cc18331SYury Norov }
4636cc18331SYury Norov
4644fe49b3bSYury Norov /*
4654fe49b3bSYury Norov * Helper for for_each_set_bit_wrap(). Make sure you're doing right thing
4664fe49b3bSYury Norov * before using it alone.
4674fe49b3bSYury Norov */
468*fda1dd3cSYury Norov static __always_inline
__for_each_wrap(const unsigned long * bitmap,unsigned long size,unsigned long start,unsigned long n)4694fe49b3bSYury Norov unsigned long __for_each_wrap(const unsigned long *bitmap, unsigned long size,
4704fe49b3bSYury Norov unsigned long start, unsigned long n)
4714fe49b3bSYury Norov {
4724fe49b3bSYury Norov unsigned long bit;
4734fe49b3bSYury Norov
4744fe49b3bSYury Norov /* If not wrapped around */
4754fe49b3bSYury Norov if (n > start) {
4764fe49b3bSYury Norov /* and have a bit, just return it. */
4774fe49b3bSYury Norov bit = find_next_bit(bitmap, size, n);
4784fe49b3bSYury Norov if (bit < size)
4794fe49b3bSYury Norov return bit;
4804fe49b3bSYury Norov
4814fe49b3bSYury Norov /* Otherwise, wrap around and ... */
4824fe49b3bSYury Norov n = 0;
4834fe49b3bSYury Norov }
4844fe49b3bSYury Norov
4854fe49b3bSYury Norov /* Search the other part. */
4864fe49b3bSYury Norov bit = find_next_bit(bitmap, start, n);
4874fe49b3bSYury Norov return bit < start ? bit : size;
4884fe49b3bSYury Norov }
4894fe49b3bSYury Norov
4906cc18331SYury Norov /**
49147d8c156SYury Norov * find_next_clump8 - find next 8-bit clump with set bits in a memory region
49247d8c156SYury Norov * @clump: location to store copy of found clump
49347d8c156SYury Norov * @addr: address to base the search on
49447d8c156SYury Norov * @size: bitmap size in number of bits
49547d8c156SYury Norov * @offset: bit offset at which to start searching
49647d8c156SYury Norov *
49747d8c156SYury Norov * Returns the bit offset for the next set clump; the found clump value is
49847d8c156SYury Norov * copied to the location pointed by @clump. If no bits are set, returns @size.
49947d8c156SYury Norov */
50047d8c156SYury Norov extern unsigned long find_next_clump8(unsigned long *clump,
50147d8c156SYury Norov const unsigned long *addr,
50247d8c156SYury Norov unsigned long size, unsigned long offset);
50347d8c156SYury Norov
50447d8c156SYury Norov #define find_first_clump8(clump, bits, size) \
50547d8c156SYury Norov find_next_clump8((clump), (bits), (size), 0)
50647d8c156SYury Norov
50747d8c156SYury Norov #if defined(__LITTLE_ENDIAN)
50847d8c156SYury Norov
509*fda1dd3cSYury Norov static __always_inline
find_next_zero_bit_le(const void * addr,unsigned long size,unsigned long offset)510*fda1dd3cSYury Norov unsigned long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset)
51147d8c156SYury Norov {
51247d8c156SYury Norov return find_next_zero_bit(addr, size, offset);
51347d8c156SYury Norov }
51447d8c156SYury Norov
515*fda1dd3cSYury Norov static __always_inline
find_next_bit_le(const void * addr,unsigned long size,unsigned long offset)516*fda1dd3cSYury Norov unsigned long find_next_bit_le(const void *addr, unsigned long size, unsigned long offset)
51747d8c156SYury Norov {
51847d8c156SYury Norov return find_next_bit(addr, size, offset);
51947d8c156SYury Norov }
52047d8c156SYury Norov
521*fda1dd3cSYury Norov static __always_inline
find_first_zero_bit_le(const void * addr,unsigned long size)522*fda1dd3cSYury Norov unsigned long find_first_zero_bit_le(const void *addr, unsigned long size)
52347d8c156SYury Norov {
52447d8c156SYury Norov return find_first_zero_bit(addr, size);
52547d8c156SYury Norov }
52647d8c156SYury Norov
52747d8c156SYury Norov #elif defined(__BIG_ENDIAN)
52847d8c156SYury Norov
52947d8c156SYury Norov #ifndef find_next_zero_bit_le
530*fda1dd3cSYury Norov static __always_inline
find_next_zero_bit_le(const void * addr,unsigned long size,unsigned long offset)53147d8c156SYury Norov unsigned long find_next_zero_bit_le(const void *addr, unsigned
53247d8c156SYury Norov long size, unsigned long offset)
53347d8c156SYury Norov {
53447d8c156SYury Norov if (small_const_nbits(size)) {
53547d8c156SYury Norov unsigned long val = *(const unsigned long *)addr;
53647d8c156SYury Norov
53747d8c156SYury Norov if (unlikely(offset >= size))
53847d8c156SYury Norov return size;
53947d8c156SYury Norov
54047d8c156SYury Norov val = swab(val) | ~GENMASK(size - 1, offset);
54147d8c156SYury Norov return val == ~0UL ? size : ffz(val);
54247d8c156SYury Norov }
54347d8c156SYury Norov
544e79864f3SYury Norov return _find_next_zero_bit_le(addr, size, offset);
54547d8c156SYury Norov }
54647d8c156SYury Norov #endif
54747d8c156SYury Norov
54814a99e13SYury Norov #ifndef find_first_zero_bit_le
549*fda1dd3cSYury Norov static __always_inline
find_first_zero_bit_le(const void * addr,unsigned long size)55014a99e13SYury Norov unsigned long find_first_zero_bit_le(const void *addr, unsigned long size)
55114a99e13SYury Norov {
55214a99e13SYury Norov if (small_const_nbits(size)) {
55314a99e13SYury Norov unsigned long val = swab(*(const unsigned long *)addr) | ~GENMASK(size - 1, 0);
55414a99e13SYury Norov
55514a99e13SYury Norov return val == ~0UL ? size : ffz(val);
55614a99e13SYury Norov }
55714a99e13SYury Norov
55814a99e13SYury Norov return _find_first_zero_bit_le(addr, size);
55914a99e13SYury Norov }
56014a99e13SYury Norov #endif
56114a99e13SYury Norov
56247d8c156SYury Norov #ifndef find_next_bit_le
563*fda1dd3cSYury Norov static __always_inline
find_next_bit_le(const void * addr,unsigned long size,unsigned long offset)56447d8c156SYury Norov unsigned long find_next_bit_le(const void *addr, unsigned
56547d8c156SYury Norov long size, unsigned long offset)
56647d8c156SYury Norov {
56747d8c156SYury Norov if (small_const_nbits(size)) {
56847d8c156SYury Norov unsigned long val = *(const unsigned long *)addr;
56947d8c156SYury Norov
57047d8c156SYury Norov if (unlikely(offset >= size))
57147d8c156SYury Norov return size;
57247d8c156SYury Norov
57347d8c156SYury Norov val = swab(val) & GENMASK(size - 1, offset);
57447d8c156SYury Norov return val ? __ffs(val) : size;
57547d8c156SYury Norov }
57647d8c156SYury Norov
577e79864f3SYury Norov return _find_next_bit_le(addr, size, offset);
57847d8c156SYury Norov }
57947d8c156SYury Norov #endif
58047d8c156SYury Norov
58147d8c156SYury Norov #else
58247d8c156SYury Norov #error "Please fix <asm/byteorder.h>"
58347d8c156SYury Norov #endif
58447d8c156SYury Norov
585bc9d6635SYury Norov #define for_each_set_bit(bit, addr, size) \
586fdae96a3SYury Norov for ((bit) = 0; (bit) = find_next_bit((addr), (size), (bit)), (bit) < (size); (bit)++)
587bc9d6635SYury Norov
58833e67710SYury Norov #define for_each_and_bit(bit, addr1, addr2, size) \
589fdae96a3SYury Norov for ((bit) = 0; \
590fdae96a3SYury Norov (bit) = find_next_and_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
591fdae96a3SYury Norov (bit)++)
59233e67710SYury Norov
5935f75ff29SValentin Schneider #define for_each_andnot_bit(bit, addr1, addr2, size) \
5945f75ff29SValentin Schneider for ((bit) = 0; \
5955f75ff29SValentin Schneider (bit) = find_next_andnot_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
5965f75ff29SValentin Schneider (bit)++)
5975f75ff29SValentin Schneider
5981470afefSDave Chinner #define for_each_or_bit(bit, addr1, addr2, size) \
5991470afefSDave Chinner for ((bit) = 0; \
6001470afefSDave Chinner (bit) = find_next_or_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
6011470afefSDave Chinner (bit)++)
6021470afefSDave Chinner
603bc9d6635SYury Norov /* same as for_each_set_bit() but use bit as value to start with */
604bc9d6635SYury Norov #define for_each_set_bit_from(bit, addr, size) \
605fdae96a3SYury Norov for (; (bit) = find_next_bit((addr), (size), (bit)), (bit) < (size); (bit)++)
606bc9d6635SYury Norov
607bc9d6635SYury Norov #define for_each_clear_bit(bit, addr, size) \
608fdae96a3SYury Norov for ((bit) = 0; \
609fdae96a3SYury Norov (bit) = find_next_zero_bit((addr), (size), (bit)), (bit) < (size); \
610fdae96a3SYury Norov (bit)++)
611bc9d6635SYury Norov
612bc9d6635SYury Norov /* same as for_each_clear_bit() but use bit as value to start with */
613bc9d6635SYury Norov #define for_each_clear_bit_from(bit, addr, size) \
614fdae96a3SYury Norov for (; (bit) = find_next_zero_bit((addr), (size), (bit)), (bit) < (size); (bit)++)
615bc9d6635SYury Norov
616bc9d6635SYury Norov /**
617ec288a2cSYury Norov * for_each_set_bitrange - iterate over all set bit ranges [b; e)
618ec288a2cSYury Norov * @b: bit offset of start of current bitrange (first set bit)
619ec288a2cSYury Norov * @e: bit offset of end of current bitrange (first unset bit)
620ec288a2cSYury Norov * @addr: bitmap address to base the search on
621ec288a2cSYury Norov * @size: bitmap size in number of bits
622ec288a2cSYury Norov */
623ec288a2cSYury Norov #define for_each_set_bitrange(b, e, addr, size) \
624fdae96a3SYury Norov for ((b) = 0; \
625fdae96a3SYury Norov (b) = find_next_bit((addr), (size), b), \
626fdae96a3SYury Norov (e) = find_next_zero_bit((addr), (size), (b) + 1), \
627ec288a2cSYury Norov (b) < (size); \
628fdae96a3SYury Norov (b) = (e) + 1)
629ec288a2cSYury Norov
630ec288a2cSYury Norov /**
631ec288a2cSYury Norov * for_each_set_bitrange_from - iterate over all set bit ranges [b; e)
632ec288a2cSYury Norov * @b: bit offset of start of current bitrange (first set bit); must be initialized
633ec288a2cSYury Norov * @e: bit offset of end of current bitrange (first unset bit)
634ec288a2cSYury Norov * @addr: bitmap address to base the search on
635ec288a2cSYury Norov * @size: bitmap size in number of bits
636ec288a2cSYury Norov */
637ec288a2cSYury Norov #define for_each_set_bitrange_from(b, e, addr, size) \
638fdae96a3SYury Norov for (; \
639fdae96a3SYury Norov (b) = find_next_bit((addr), (size), (b)), \
640fdae96a3SYury Norov (e) = find_next_zero_bit((addr), (size), (b) + 1), \
641ec288a2cSYury Norov (b) < (size); \
642fdae96a3SYury Norov (b) = (e) + 1)
643ec288a2cSYury Norov
644ec288a2cSYury Norov /**
645ec288a2cSYury Norov * for_each_clear_bitrange - iterate over all unset bit ranges [b; e)
646ec288a2cSYury Norov * @b: bit offset of start of current bitrange (first unset bit)
647ec288a2cSYury Norov * @e: bit offset of end of current bitrange (first set bit)
648ec288a2cSYury Norov * @addr: bitmap address to base the search on
649ec288a2cSYury Norov * @size: bitmap size in number of bits
650ec288a2cSYury Norov */
651ec288a2cSYury Norov #define for_each_clear_bitrange(b, e, addr, size) \
652fdae96a3SYury Norov for ((b) = 0; \
653fdae96a3SYury Norov (b) = find_next_zero_bit((addr), (size), (b)), \
654fdae96a3SYury Norov (e) = find_next_bit((addr), (size), (b) + 1), \
655ec288a2cSYury Norov (b) < (size); \
656fdae96a3SYury Norov (b) = (e) + 1)
657ec288a2cSYury Norov
658ec288a2cSYury Norov /**
659ec288a2cSYury Norov * for_each_clear_bitrange_from - iterate over all unset bit ranges [b; e)
660ec288a2cSYury Norov * @b: bit offset of start of current bitrange (first set bit); must be initialized
661ec288a2cSYury Norov * @e: bit offset of end of current bitrange (first unset bit)
662ec288a2cSYury Norov * @addr: bitmap address to base the search on
663ec288a2cSYury Norov * @size: bitmap size in number of bits
664ec288a2cSYury Norov */
665ec288a2cSYury Norov #define for_each_clear_bitrange_from(b, e, addr, size) \
666fdae96a3SYury Norov for (; \
667fdae96a3SYury Norov (b) = find_next_zero_bit((addr), (size), (b)), \
668fdae96a3SYury Norov (e) = find_next_bit((addr), (size), (b) + 1), \
669ec288a2cSYury Norov (b) < (size); \
670fdae96a3SYury Norov (b) = (e) + 1)
671ec288a2cSYury Norov
672ec288a2cSYury Norov /**
6734fe49b3bSYury Norov * for_each_set_bit_wrap - iterate over all set bits starting from @start, and
6744fe49b3bSYury Norov * wrapping around the end of bitmap.
6754fe49b3bSYury Norov * @bit: offset for current iteration
6764fe49b3bSYury Norov * @addr: bitmap address to base the search on
6774fe49b3bSYury Norov * @size: bitmap size in number of bits
6784fe49b3bSYury Norov * @start: Starting bit for bitmap traversing, wrapping around the bitmap end
6794fe49b3bSYury Norov */
6804fe49b3bSYury Norov #define for_each_set_bit_wrap(bit, addr, size, start) \
6814fe49b3bSYury Norov for ((bit) = find_next_bit_wrap((addr), (size), (start)); \
6824fe49b3bSYury Norov (bit) < (size); \
6834fe49b3bSYury Norov (bit) = __for_each_wrap((addr), (size), (start), (bit) + 1))
6844fe49b3bSYury Norov
6854fe49b3bSYury Norov /**
686bc9d6635SYury Norov * for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
687bc9d6635SYury Norov * @start: bit offset to start search and to store the current iteration offset
688bc9d6635SYury Norov * @clump: location to store copy of current 8-bit clump
689bc9d6635SYury Norov * @bits: bitmap address to base the search on
690bc9d6635SYury Norov * @size: bitmap size in number of bits
691bc9d6635SYury Norov */
692bc9d6635SYury Norov #define for_each_set_clump8(start, clump, bits, size) \
693bc9d6635SYury Norov for ((start) = find_first_clump8(&(clump), (bits), (size)); \
694bc9d6635SYury Norov (start) < (size); \
695bc9d6635SYury Norov (start) = find_next_clump8(&(clump), (bits), (size), (start) + 8))
696bc9d6635SYury Norov
69747d8c156SYury Norov #endif /*__LINUX_FIND_H_ */
698