Message ID | 20200525113959.11886-7-s.nawrocki@samsung.com |
---|---|
State | Accepted |
Delegated to: | Matthias Brugger |
Headers | show |
Series | USB host support for Raspberry Pi 4 board (64-bit) | expand |
On 25/05/2020 13:39, Sylwester Nawrocki wrote: > From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> > > Imports Al Viro's original Linux commit 00b0c9b82663a, which contains > an in depth explanation and two fixes from Johannes Berg: > e7d4a95da86e0 "bitfield: fix *_encode_bits()", > 37a3862e12382 "bitfield: add u8 helpers". > > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> > [s.nawrocki: added empty lines between functions and macros] > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> This seems to break compilation of arch/arm/mach-uniphier/clk/pll-base-ld20.c https://gitlab.denx.de/u-boot/custodians/u-boot-raspberrypi/-/jobs/121248 Nicolas, Sylwester, can you please have a look. Regards, Matthias > --- > Changes since v3: > - none. > Changes since v2: > - added some more missing whitespaces as pointed out by checkpatch.pl. > Changes since v1: > - added empty lines between functions and macros. > Changes since RFC: > - new patch. > --- > include/linux/bitfield.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 52 insertions(+) > > diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h > index 8b9d6ff..7ad8b08 100644 > --- a/include/linux/bitfield.h > +++ b/include/linux/bitfield.h > @@ -103,4 +103,56 @@ > (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ > }) > > +extern void __compiletime_error("value doesn't fit into mask") > +__field_overflow(void); > +extern void __compiletime_error("bad bitfield mask") > +__bad_mask(void); > + > +static __always_inline u64 field_multiplier(u64 field) > +{ > + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) > + __bad_mask(); > + return field & -field; > +} > + > +static __always_inline u64 field_mask(u64 field) > +{ > + return field / field_multiplier(field); > +} > + > +#define ____MAKE_OP(type, base, to, from) \ > +static __always_inline __##type type##_encode_bits(base v, base field) \ > +{ \ > + if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ > + __field_overflow(); \ > + return to((v & field_mask(field)) * field_multiplier(field)); \ > +} \ > +static __always_inline __##type type##_replace_bits(__##type old, \ > + base val, base field) \ > +{ \ > + return (old & ~to(field)) | type##_encode_bits(val, field); \ > +} \ > +static __always_inline void type##p_replace_bits(__##type * p, \ > + base val, base field) \ > +{ \ > + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ > +} \ > +static __always_inline base type##_get_bits(__##type v, base field) \ > +{ \ > + return (from(v) & field) / field_multiplier(field); \ > +} > + > +#define __MAKE_OP(size) \ > + ____MAKE_OP(le##size, u##size, cpu_to_le##size, le##size##_to_cpu) \ > + ____MAKE_OP(be##size, u##size, cpu_to_be##size, be##size##_to_cpu) \ > + ____MAKE_OP(u##size, u##size, ,) > + > +____MAKE_OP(u8, u8, ,) > +__MAKE_OP(16) > +__MAKE_OP(32) > +__MAKE_OP(64) > + > +#undef __MAKE_OP > +#undef ____MAKE_OP > + > #endif >
On 09/07/2020 17:35, Matthias Brugger wrote: > > > On 25/05/2020 13:39, Sylwester Nawrocki wrote: >> From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> >> >> Imports Al Viro's original Linux commit 00b0c9b82663a, which contains >> an in depth explanation and two fixes from Johannes Berg: >> e7d4a95da86e0 "bitfield: fix *_encode_bits()", >> 37a3862e12382 "bitfield: add u8 helpers". >> >> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> >> [s.nawrocki: added empty lines between functions and macros] >> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> > > This seems to break compilation of > arch/arm/mach-uniphier/clk/pll-base-ld20.c > > https://gitlab.denx.de/u-boot/custodians/u-boot-raspberrypi/-/jobs/121248 > > Nicolas, Sylwester, can you please have a look. > Just in case you can't access the URL: https://pastebin.com/KhDHf8e1 > Regards, > Matthias > >> --- >> Changes since v3: >> - none. >> Changes since v2: >> - added some more missing whitespaces as pointed out by checkpatch.pl. >> Changes since v1: >> - added empty lines between functions and macros. >> Changes since RFC: >> - new patch. >> --- >> include/linux/bitfield.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 52 insertions(+) >> >> diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h >> index 8b9d6ff..7ad8b08 100644 >> --- a/include/linux/bitfield.h >> +++ b/include/linux/bitfield.h >> @@ -103,4 +103,56 @@ >> (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ >> }) >> +extern void __compiletime_error("value doesn't fit into mask") >> +__field_overflow(void); >> +extern void __compiletime_error("bad bitfield mask") >> +__bad_mask(void); >> + >> +static __always_inline u64 field_multiplier(u64 field) >> +{ >> + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) >> + __bad_mask(); >> + return field & -field; >> +} >> + >> +static __always_inline u64 field_mask(u64 field) >> +{ >> + return field / field_multiplier(field); >> +} >> + >> +#define ____MAKE_OP(type, base, to, from) \ >> +static __always_inline __##type type##_encode_bits(base v, base field) \ >> +{ \ >> + if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ >> + __field_overflow(); \ >> + return to((v & field_mask(field)) * field_multiplier(field)); \ >> +} \ >> +static __always_inline __##type type##_replace_bits(__##type old, \ >> + base val, base field) \ >> +{ \ >> + return (old & ~to(field)) | type##_encode_bits(val, field); \ >> +} \ >> +static __always_inline void type##p_replace_bits(__##type * p, \ >> + base val, base field) \ >> +{ \ >> + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ >> +} \ >> +static __always_inline base type##_get_bits(__##type v, base field) \ >> +{ \ >> + return (from(v) & field) / field_multiplier(field); \ >> +} >> + >> +#define __MAKE_OP(size) \ >> + ____MAKE_OP(le##size, u##size, cpu_to_le##size, le##size##_to_cpu) \ >> + ____MAKE_OP(be##size, u##size, cpu_to_be##size, be##size##_to_cpu) \ >> + ____MAKE_OP(u##size, u##size, ,) >> + >> +____MAKE_OP(u8, u8, ,) >> +__MAKE_OP(16) >> +__MAKE_OP(32) >> +__MAKE_OP(64) >> + >> +#undef __MAKE_OP >> +#undef ____MAKE_OP >> + >> #endif >>
diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 8b9d6ff..7ad8b08 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -103,4 +103,56 @@ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ }) +extern void __compiletime_error("value doesn't fit into mask") +__field_overflow(void); +extern void __compiletime_error("bad bitfield mask") +__bad_mask(void); + +static __always_inline u64 field_multiplier(u64 field) +{ + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) + __bad_mask(); + return field & -field; +} + +static __always_inline u64 field_mask(u64 field) +{ + return field / field_multiplier(field); +} + +#define ____MAKE_OP(type, base, to, from) \ +static __always_inline __##type type##_encode_bits(base v, base field) \ +{ \ + if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ + __field_overflow(); \ + return to((v & field_mask(field)) * field_multiplier(field)); \ +} \ +static __always_inline __##type type##_replace_bits(__##type old, \ + base val, base field) \ +{ \ + return (old & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline void type##p_replace_bits(__##type * p, \ + base val, base field) \ +{ \ + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline base type##_get_bits(__##type v, base field) \ +{ \ + return (from(v) & field) / field_multiplier(field); \ +} + +#define __MAKE_OP(size) \ + ____MAKE_OP(le##size, u##size, cpu_to_le##size, le##size##_to_cpu) \ + ____MAKE_OP(be##size, u##size, cpu_to_be##size, be##size##_to_cpu) \ + ____MAKE_OP(u##size, u##size, ,) + +____MAKE_OP(u8, u8, ,) +__MAKE_OP(16) +__MAKE_OP(32) +__MAKE_OP(64) + +#undef __MAKE_OP +#undef ____MAKE_OP + #endif