summaryrefslogtreecommitdiffstats
path: root/include/linux/bug.h
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2016-08-31 12:46:44 +0100
committerKalle Valo <kvalo@codeaurora.org>2016-09-09 12:09:24 +0300
commit3e9b3112ec74f192eaab976c3889e34255cae940 (patch)
tree8c0b1eb296017b9f33a234d615d3e0370ed80a37 /include/linux/bug.h
parent3935ccc14d2c68488bd96448fc073da48eaeebf0 (diff)
downloadlinux-3e9b3112ec74f192eaab976c3889e34255cae940.tar.gz
linux-3e9b3112ec74f192eaab976c3889e34255cae940.tar.bz2
linux-3e9b3112ec74f192eaab976c3889e34255cae940.zip
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>
Diffstat (limited to 'include/linux/bug.h')
-rw-r--r--include/linux/bug.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/bug.h b/include/linux/bug.h
index e51b0709e78d..292d6a10b0c2 100644
--- a/include/linux/bug.h
+++ b/include/linux/bug.h
@@ -13,6 +13,7 @@ enum bug_trap_type {
struct pt_regs;
#ifdef __CHECKER__
+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
#define BUILD_BUG_ON_ZERO(e) (0)
#define BUILD_BUG_ON_NULL(e) ((void*)0)
@@ -24,6 +25,8 @@ struct pt_regs;
#else /* __CHECKER__ */
/* Force a compilation error if a constant expression is not a power of 2 */
+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) \
+ BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
#define BUILD_BUG_ON_NOT_POWER_OF_2(n) \
BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))