diff options
author | Maxim Kochetkov <fido_max@inbox.ru> | 2024-07-26 15:07:21 +0300 |
---|---|---|
committer | Leo Yu-Chi Liang <ycliang@andestech.com> | 2024-09-10 10:10:43 +0800 |
commit | bbbb2ef4a7e8ea2f0300765b4a560053e5ffa669 (patch) | |
tree | 940af483821c3cbb97593abc04328e4fcccf19f1 | |
parent | e0495c9186a429220eb342e415b9db57f097ef3d (diff) |
riscv: define find_{first,next}_zero_bit in asm/bitops.h
These seem to be missing, and trying to build fastboot cmd without
them is causing errors due to these being missing.
Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru>
Tested-by: E Shattow <lucent@gmail.com
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
-rw-r--r-- | arch/riscv/include/asm/bitops.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h index 35f1368b837..2f2994c4ddc 100644 --- a/arch/riscv/include/asm/bitops.h +++ b/arch/riscv/include/asm/bitops.h @@ -138,6 +138,43 @@ static inline unsigned long ffz(unsigned long word) return k; } +static inline int find_next_zero_bit(void *addr, int size, int offset) +{ + unsigned long *p = ((unsigned long *)addr) + (offset / BITS_PER_LONG); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= (BITS_PER_LONG - 1); + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (BITS_PER_LONG - offset); + if (size < BITS_PER_LONG) + goto found_first; + if (~tmp) + goto found_middle; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; + } + while (size & ~(BITS_PER_LONG - 1)) { + tmp = *(p++); + if (~tmp) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp |= ~0UL << size; +found_middle: + return result + ffz(tmp); +} + /* * ffs: find first bit set. This is defined the same way as * the libc and compiler builtin ffs routines, therefore @@ -158,6 +195,9 @@ static inline unsigned long ffz(unsigned long word) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + #define test_and_set_bit __test_and_set_bit #define test_and_clear_bit __test_and_clear_bit |