Skip to content

Commit c320592

Browse files
Wolfram Sangalexandrebelloni
authored andcommitted
bitops: add generic parity calculation for u8
There are multiple open coded implementations for getting the parity of a byte in the kernel, even using different approaches. Take the pretty efficient version from SPD5118 driver and make it generally available by putting it into the bitops header. As long as there is just one parity calculation helper, the creation of a distinct 'parity.h' header was discarded. Also, the usage of hweight8() for architectures having a popcnt instruction is postponed until a use case within hot paths is desired. The motivation for this patch is the frequent use of odd parity in the I3C specification and to simplify drivers there. Changes compared to the original SPD5118 version are the addition of kernel documentation, switching the return type from bool to int, and renaming the argument of the function. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Tested-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Yury Norov <yury.norov@gmail.com> Reviewed-by: Kuan-Wei Chiu <visitorckw@gmail.com> Tested-by: Kuan-Wei Chiu <visitorckw@gmail.com> Link: https://lore.kernel.org/r/20250107090204.6593-2-wsa+renesas@sang-engineering.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
1 parent 30bb1ce commit c320592

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

include/linux/bitops.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,37 @@ static inline int get_count_order_long(unsigned long l)
229229
return (int)fls_long(--l);
230230
}
231231

232+
/**
233+
* parity8 - get the parity of an u8 value
234+
* @value: the value to be examined
235+
*
236+
* Determine the parity of the u8 argument.
237+
*
238+
* Returns:
239+
* 0 for even parity, 1 for odd parity
240+
*
241+
* Note: This function informs you about the current parity. Example to bail
242+
* out when parity is odd:
243+
*
244+
* if (parity8(val) == 1)
245+
* return -EBADMSG;
246+
*
247+
* If you need to calculate a parity bit, you need to draw the conclusion from
248+
* this result yourself. Example to enforce odd parity, parity bit is bit 7:
249+
*
250+
* if (parity8(val) == 0)
251+
* val ^= BIT(7);
252+
*/
253+
static inline int parity8(u8 val)
254+
{
255+
/*
256+
* One explanation of this algorithm:
257+
* https://funloop.org/codex/problem/parity/README.html
258+
*/
259+
val ^= val >> 4;
260+
return (0x6996 >> (val & 0xf)) & 1;
261+
}
262+
232263
/**
233264
* __ffs64 - find first set bit in a 64 bit word
234265
* @word: The 64 bit word

0 commit comments

Comments
 (0)