Hi Quentin,

On 8/7/2026 10:14 AM, Quentin Schulz wrote:
> Hi Jonas,
> 
> On 8/3/26 8:43 PM, Jonas Karlman wrote:
>> Hardware of various vendors, but very notably Rockchip, often uses
>> 32-bit registers where the upper 16-bit half of the register is a
>> write-enable mask for the lower half.
>>
>> Add hw_bitfield.h with two macros: FIELD_PREP_WM16, and
>> FIELD_PREP_WM16_CONST. The latter is a version that can be used in
>> initializers, like FIELD_PREP_CONST.
>>
>> Import hw_bitfield.h from Linux commit 21368fcbb124 ("bitmap: introduce
>> hardware-specific bitfield operations"), first introduced in v6.18-rc1.
>>
>> This contains two changes compared to the Linux version:
>> - include of linux/limit.h was dropped
>> - use of const_true() in FIELD_PREP_WM16_CONST() was dropped
>>
> 
> Acked-by: Quentin Schulz <[email protected]>
> 
> The content in this patch is as described in the commit log.
> 
> I'm wondering whether we should try to get include/linux/limit.h (and 
> include/vdso/limit.h) in. Also wondering if we could also get 
> const_true() in somehow.

U16_MAX, used in FIELD_PREP_WM16_CONST(), is what would have been
imported by linux/limit.h, there is also a U-Boot specific limits.h that
defines U16_MAX but it felt wrong to depend on the U-Boot header inside
the linux header. Using the FIELD_PREP_WM16_CONST() instead of the non
const variant also never reported any missing U16_MAX define.

const_true() would have been nice to import, but that was a separate
issue, linux/compiler.h is very outdated and looks harder to sync
without risking introducing new possible issues.

Testing FIELD_PREP_WM16_CONST() without const_true() and mask > U16_MAX
do produce a compile time error, but the error message may look a little
bit strange:

  In file included from arch/arm/mach-rockchip/rk3576/rk3576.c:12:
  arch/arm/mach-rockchip/rk3576/rk3576.c: In function ‘arch_cpu_init’:
  include/linux/build_bug.h:15:50: error: negative width in bit-field 
‘<anonymous>’
     15 | #define BUILD_BUG_ON_ZERO(e) ((int)sizeof(struct { int:(-!!(e)); }))
        |                                                  ^
  ./arch/arm/include/asm/io.h:178:38: note: in definition of macro ‘writel’
    178 | #define writel(v, c)    ({ u32 __v = v; __iowmb(); 
writel_relaxed(__v, c); __v; })
        |                                      ^
  include/linux/hw_bitfield.h:56:18: note: in expansion of macro 
‘BUILD_BUG_ON_ZERO’
     56 |                 (BUILD_BUG_ON_ZERO((u64)(_mask) > U16_MAX) + \
        |                  ^~~~~~~~~~~~~~~~~
  arch/arm/mach-rockchip/rk3576/rk3576.c:200:24: note: in expansion of macro 
‘FIELD_PREP_WM16_CONST’
    200 |                 writel(FIELD_PREP_WM16_CONST(BIT(16), 0),
        |                        ^~~~~~~~~~~~~~~~~~~~~
  include/linux/hw_bitfield.h:54:9: warning: conversion from ‘long unsigned 
int’ to ‘u32’ {aka ‘unsigned int’} changes value from ‘4294967300’ to ‘4’ 
[-Woverflow]
     54 |         (                                                             
   \
        |         ^
  ./arch/arm/include/asm/io.h:178:38: note: in definition of macro ‘writel’
    178 | #define writel(v, c)    ({ u32 __v = v; __iowmb(); 
writel_relaxed(__v, c); __v; })
        |                                      ^
  arch/arm/mach-rockchip/rk3576/rk3576.c:200:24: note: in expansion of macro 
‘FIELD_PREP_WM16_CONST’
    200 |                 writel(FIELD_PREP_WM16_CONST(BIT(16), 0),
        |                        ^~~~~~~~~~~~~~~~~~~~~

> 
> No changes made to this file in Linux kernel since v6.18-rc1, so could 
> as well have said it's taken from 7.2-rc6 (which also means no missed 
> fixes).

Hum, I thought I mentioned that it has not changed up to v7.1, but looks
like that comment did not made it in.

Regards,
Jonas

> 
> I'll wait on Tom's Reviewed-by before merging this though since it's not 
> a straight import from the Linux kernel. I'm targeting the next branch 
> for this.
> 
> Cheers,
> Quentin

Reply via email to