Add reverse routine for find_each_*_bit using find_last_bit and find_last_zero_bit. for correspondant usage wtih find_each_*_bit macros we use same parameters, But when we use these macro different from find_each_*_bit, @size should be a variable NOT constants. Signed-off-by: Levi Yun <ppbuk5246@xxxxxxxxx> --- include/linux/bitops.h | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 5b74bdf159d6..f6ab611ca732 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -50,6 +50,31 @@ extern unsigned long __sw_hweight64(__u64 w); (bit) < (size); \ (bit) = find_next_zero_bit((addr), (size), (bit) + 1)) +/** + * find_each_*_reverse's @size should be variable NOT constant. + */ +#define for_each_set_bit_reverse(bit, addr, size) \ + for ((bit) = find_last_bit((addr), (size)); \ + (bit) < (size) && (size); \ + (size) = (bit), (bit) = find_last_bit((addr), (size))) + +/* same as for_each_set_bit_reverse() but use bit as value to start with */ +#define for_each_set_bit_from_reverse(bit, addr, size) \ + for ((size) = (bit + 1), (bit) = find_last_bit((addr), (size)); \ + (bit) < (size) && (size); \ + (size) = (bit), (bit) = find_last_bit((addr), (size))) + +#define for_each_clear_bit_reverse(bit, addr, size) \ + for ((bit) = find_last_zero_bit((addr), (size)); \ + (bit) < (size) && (size); \ + (size) = (bit), (bit) = find_last_zero_bit((addr), (size))) + +/* same as for_each_clear_bit_reverse() but use bit as value to start with */ +#define for_each_clear_bit_from_reverse(bit, addr, size) \ + for ((size) = (bit + 1), (bit) = find_last_zero_bit((addr), (size)); \ + (bit) < (size) && (size); \ + (size) = (bit), (bit) = find_last_zero_bit((addr), (size))) + /** * for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits * @start: bit offset to start search and to store the current iteration offset @@ -283,17 +308,5 @@ static __always_inline void __assign_bit(long nr, volatile unsigned long *addr, }) #endif -#ifndef find_last_bit -/** - * find_last_bit - find the last set bit in a memory region - * @addr: The address to start the search at - * @size: The number of bits to search - * - * Returns the bit number of the last set bit, or size. - */ -extern unsigned long find_last_bit(const unsigned long *addr, - unsigned long size); -#endif - #endif /* __KERNEL__ */ #endif -- 2.27.0