Import FIELD_PREP_CONST macro from Linux Kernel to permit usage of FIELD_PREP with scenario where a constant value is needed.
Refer to commit e2192de59e45 ("bitfield: add FIELD_PREP_CONST()") in Linux kernel for extensive explaination of why this is useful. This is also to better align with the Linux Kernel for easier porting of driver. Signed-off-by: Christian Marangi <ansuels...@gmail.com> --- include/linux/bitfield.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 7ad02f8cbb9..1b73ba6f9fa 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -90,6 +90,32 @@ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ }) +#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0) + +/** + * FIELD_PREP_CONST() - prepare a constant bitfield element + * @_mask: shifted mask defining the field's length and position + * @_val: value to put in the field + * + * FIELD_PREP_CONST() masks and shifts up the value. The result should + * be combined with other fields of the bitfield using logical OR. + * + * Unlike FIELD_PREP() this is a constant expression and can therefore + * be used in initializers. Error checking is less comfortable for this + * version, and non-constant masks cannot be used. + */ +#define FIELD_PREP_CONST(_mask, _val) \ + ( \ + /* mask must be non-zero */ \ + BUILD_BUG_ON_ZERO((_mask) == 0) + \ + /* check if value fits */ \ + BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \ + /* check if mask is contiguous */ \ + __BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \ + /* and create the value */ \ + (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \ + ) + /** * FIELD_GET() - extract a bitfield element * @_mask: shifted mask defining the field's length and position -- 2.48.1