diff mbox series

[1/1] riscv: define find_{first,next}_zero_bit in asm/bitops.h

Message ID 20240726120721.150484-1-fido_max@inbox.ru
State New
Delegated to: Andes
Headers show
Series [1/1] riscv: define find_{first,next}_zero_bit in asm/bitops.h | expand

Commit Message

Maxim Kochetkov July 26, 2024, 12:07 p.m. UTC
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>
---
 arch/riscv/include/asm/bitops.h | 40 +++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

Comments

E Shattow July 27, 2024, 10:35 a.m. UTC | #1
Is this a problem in Linux upstream? or specific to U-Boot, and is it
a regression?

refrerence https://lore.kernel.org/u-boot/20240504183354.GL2568172@bill-the-cat/
and reference https://lore.kernel.org/u-boot/BJXPR01MB0855813DD38EF86CCA6DD5C8E6E92@BJXPR01MB0855.CHNPR01.prod.partner.outlook.cn/

On Fri, Jul 26, 2024 at 5:44 AM Maxim Kochetkov <fido_max@inbox.ru> wrote:
>
> 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>
> ---
>  arch/riscv/include/asm/bitops.h | 40 +++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
>
> diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
> index 35f1368b83..2f2994c4dd 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
>
> --
> 2.45.2
>

-E
Maxim Kochetkov July 29, 2024, 5:47 a.m. UTC | #2
27.07.2024 13:35, E Shattow wrote:
> Is this a problem in Linux upstream? or specific to U-Boot, and is it
> a regression?
> 
> refrerence https://lore.kernel.org/u-boot/20240504183354.GL2568172@bill-the-cat/
> and reference https://lore.kernel.org/u-boot/BJXPR01MB0855813DD38EF86CCA6DD5C8E6E92@BJXPR01MB0855.CHNPR01.prod.partner.outlook.cn/
> 

It is very similar. But it comes from

In file included from 
/home/maximus/git/yadro/ymp-build/u-boot/include/linux/usb/composite.h:26,
                  from 
/home/maximus/git/yadro/ymp-build/u-boot/include/g_dnl.h:12,
                  from 
/home/maximus/git/yadro/ymp-build/u-boot/cmd/fastboot.c:12:
/home/maximus/git/yadro/ymp-build/u-boot/include/linux/bitmap.h: In 
function ‘bitmap_find_next_zero_area’:
/home/maximus/git/yadro/ymp-build/u-boot/include/linux/bitmap.h:170:17: 
error: implicit declaration of function ‘find_next_zero_bit’; did you 
mean ‘find_next_bit’? [-Wimplicit-function-declaration]
   170 |         index = find_next_zero_bit(map, size, start);
       |                 ^~~~~~~~~~~~~~~~~~
       |                 find_next_bit

I've just tried v2024.07 and master.

I tried to drop #include <linux/bitmap.h> from composite.h, but it fails 
on usb gadget compilation:

   CC      drivers/usb/gadget/g_dnl.o
In file included from 
/home/maximus/git/yadro/ymp-build/u-boot/drivers/usb/gadget/g_dnl.c:24:
/home/maximus/git/yadro/ymp-build/u-boot/drivers/usb/gadget/composite.c: 
In function ‘reset_config’:
/home/maximus/git/yadro/ymp-build/u-boot/drivers/usb/gadget/composite.c:362:17: 
error: implicit declaration of function ‘bitmap_zero’ 
[-Wimplicit-function-declaration]
   362 |                 bitmap_zero(f->endpoints, 32);
       |                 ^~~~~~~~~~~
E Shattow Aug. 30, 2024, 2:28 a.m. UTC | #3
Series https://patchwork.ozlabs.org/project/uboot/list/?series=421417
Add Starfive JH7110 Cadence USB driver fails to compile anymore
without this patch.

With that,

Tested-by: E Shattow <lucent@gmail.com

On Sun, Jul 28, 2024 at 10:47 PM Maxim Kochetkov <fido_max@inbox.ru> wrote:
>
> 27.07.2024 13:35, E Shattow wrote:
> > Is this a problem in Linux upstream? or specific to U-Boot, and is it
> > a regression?
> >
> > refrerence https://lore.kernel.org/u-boot/20240504183354.GL2568172@bill-the-cat/
> > and reference https://lore.kernel.org/u-boot/BJXPR01MB0855813DD38EF86CCA6DD5C8E6E92@BJXPR01MB0855.CHNPR01.prod.partner.outlook.cn/
> >
>
> It is very similar. But it comes from
>
> In file included from
> /home/maximus/git/yadro/ymp-build/u-boot/include/linux/usb/composite.h:26,
>                   from
> /home/maximus/git/yadro/ymp-build/u-boot/include/g_dnl.h:12,
>                   from
> /home/maximus/git/yadro/ymp-build/u-boot/cmd/fastboot.c:12:
> /home/maximus/git/yadro/ymp-build/u-boot/include/linux/bitmap.h: In
> function ‘bitmap_find_next_zero_area’:
> /home/maximus/git/yadro/ymp-build/u-boot/include/linux/bitmap.h:170:17:
> error: implicit declaration of function ‘find_next_zero_bit’; did you
> mean ‘find_next_bit’? [-Wimplicit-function-declaration]
>    170 |         index = find_next_zero_bit(map, size, start);
>        |                 ^~~~~~~~~~~~~~~~~~
>        |                 find_next_bit
>
> I've just tried v2024.07 and master.
>
> I tried to drop #include <linux/bitmap.h> from composite.h, but it fails
> on usb gadget compilation:
>
>    CC      drivers/usb/gadget/g_dnl.o
> In file included from
> /home/maximus/git/yadro/ymp-build/u-boot/drivers/usb/gadget/g_dnl.c:24:
> /home/maximus/git/yadro/ymp-build/u-boot/drivers/usb/gadget/composite.c:
> In function ‘reset_config’:
> /home/maximus/git/yadro/ymp-build/u-boot/drivers/usb/gadget/composite.c:362:17:
> error: implicit declaration of function ‘bitmap_zero’
> [-Wimplicit-function-declaration]
>    362 |                 bitmap_zero(f->endpoints, 32);
>        |                 ^~~~~~~~~~~
>
>
>
>
diff mbox series

Patch

diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index 35f1368b83..2f2994c4dd 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