aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorPaul Cercueil <paul@crapouillou.net>2020-12-13 23:54:46 +0000
committerLinus Walleij <linus.walleij@linaro.org>2021-01-18 16:13:51 +0100
commit1b399bb04837183cecdc1b32ef1cfc7fcfa75d32 (patch)
tree1f10e4e0cd7d9621da2a129cc09cf95524522925
parentMerge tag 'renesas-pinctrl-for-v5.12-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into devel (diff)
downloadwireguard-linux-1b399bb04837183cecdc1b32ef1cfc7fcfa75d32.tar.xz
wireguard-linux-1b399bb04837183cecdc1b32ef1cfc7fcfa75d32.zip
kconfig.h: Add IF_ENABLED() macro
IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set to 'y' or 'm', NULL otherwise. The (ptr) argument must be a pointer. The IF_ENABLED() macro can be very useful to help GCC drop dead code. For instance, consider the following: #ifdef CONFIG_FOO_SUSPEND static int foo_suspend(struct device *dev) { ... } #endif static struct pm_ops foo_ops = { #ifdef CONFIG_FOO_SUSPEND .suspend = foo_suspend, #endif }; While this works, the foo_suspend() macro is compiled conditionally, only when CONFIG_FOO_SUSPEND is set. This is problematic, as there could be a build bug in this function, we wouldn't have a way to know unless the config option is set. An alternative is to declare foo_suspend() always, but mark it as maybe unused: static int __maybe_unused foo_suspend(struct device *dev) { ... } static struct pm_ops foo_ops = { #ifdef CONFIG_FOO_SUSPEND .suspend = foo_suspend, #endif }; Again, this works, but the __maybe_unused attribute is required to instruct the compiler that the function may not be referenced anywhere, and is safe to remove without making a fuss about it. This makes the programmer responsible for tagging the functions that can be garbage-collected. With this patch, it is now possible to write the following: static int foo_suspend(struct device *dev) { ... } static struct pm_ops foo_ops = { .suspend = IF_ENABLED(CONFIG_FOO_SUSPEND, foo_suspend), }; The foo_suspend() function will now be automatically dropped by the compiler, and it does not require any specific attribute. Signed-off-by: Paul Cercueil <paul@crapouillou.net> Acked-by: Arnd Bergmann <arnd@arndb.de> Link: https://lore.kernel.org/r/20201213235447.138271-1-paul@crapouillou.net Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--include/linux/kconfig.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h
index 9d12c970f18f..e78e17a76dc9 100644
--- a/include/linux/kconfig.h
+++ b/include/linux/kconfig.h
@@ -72,4 +72,10 @@
*/
#define IS_ENABLED(option) __or(IS_BUILTIN(option), IS_MODULE(option))
+/*
+ * IF_ENABLED(CONFIG_FOO, ptr) evaluates to (ptr) if CONFIG_FOO is set to 'y'
+ * or 'm', NULL otherwise.
+ */
+#define IF_ENABLED(option, ptr) (IS_ENABLED(option) ? (ptr) : NULL)
+
#endif /* __LINUX_KCONFIG_H */