]> git.baikalelectronics.ru Git - kernel.git/commit
add basic register-field manipulation macros
authorJakub Kicinski <jakub.kicinski@netronome.com>
Wed, 31 Aug 2016 11:46:44 +0000 (12:46 +0100)
committerKalle Valo <kvalo@codeaurora.org>
Fri, 9 Sep 2016 09:09:24 +0000 (12:09 +0300)
commite8332df9b5e2076cdb67c7a09ff50b1cc70334c1
tree8c0b1eb296017b9f33a234d615d3e0370ed80a37
parentc8cdb48fbd0bd2f299b8769104eac38c011b5de9
add basic register-field manipulation macros

Common approach to accessing register fields is to define
structures or sets of macros containing mask and shift pair.
Operations on the register are then performed as follows:

 field = (reg >> shift) & mask;

 reg &= ~(mask << shift);
 reg |= (field & mask) << shift;

Defining shift and mask separately is tedious.  Ivo van Doorn
came up with an idea of computing them at compilation time
based on a single shifted mask (later refined by Felix) which
can be used like this:

 #define REG_FIELD 0x000ff000

 field = FIELD_GET(REG_FIELD, reg);

 reg &= ~REG_FIELD;
 reg |= FIELD_PREP(REG_FIELD, field);

FIELD_{GET,PREP} macros take care of finding out what the
appropriate shift is based on compilation time ffs operation.

GENMASK can be used to define registers (which is usually
less error-prone and easier to match with datasheets).

This approach is the most convenient I've seen so to limit code
multiplication let's move the macros to a global header file.
Attempts to use static inlines instead of macros failed due
to false positive triggering of BUILD_BUG_ON()s, especially with
GCC < 6.0.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dinan Gunawardena <dinan.gunawardena@netronome.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
include/linux/bitfield.h [new file with mode: 0644]
include/linux/bug.h