summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorBrian Masney <bmasney@redhat.com>2026-09-08 13:47:18 -0400
committerBjorn Andersson <bjorn.andersson@oss.qualcomm.com>2026-09-23 18:24:30 -0500
commitecf877ef7c5c737b0ae874eb9521e88ab8a03a0a (patch)
tree4c8187d6f47ea7aba7e8fddd43df3241e05fe40e /include/linux
parent8d0ae69b7c8af642264e57ca61e0c1cced7de436 (diff)
driver: core: add subsys_driver() macro
Add a new macro subsys_driver() to eliminate some boilerplate code in drivers that need to register earlier in the boot at the subsys_initcall level. Signed-off-by: Brian Masney <bmasney@redhat.com> Assisted-by: Claude:claude-opus-4-8 Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com> Tested-by: Pankaj Patil <pankaj.patil@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260908-subsys_initcall-v1-1-cbccf4cd4288@redhat.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/device/driver.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h
index 768a1334c0a1..29fbc01ef06f 100644
--- a/include/linux/device/driver.h
+++ b/include/linux/device/driver.h
@@ -297,4 +297,35 @@ static int __init __driver##_init(void) \
} \
device_initcall(__driver##_init);
+/**
+ * subsys_driver() - Helper macro for drivers that don't do anything special
+ * in init/exit but have to register earlier, at subsys_initcall level, when
+ * built in. This eliminates a lot of boilerplate. Each driver may only use
+ * this macro once, and calling it replaces the init/exit boilerplate.
+ *
+ * @__driver: driver name
+ * @__register: register function for this driver type
+ * @__unregister: unregister function for this driver type
+ * @...: Additional arguments to be passed to __register and __unregister.
+ *
+ * This is meant to be a direct parallel of module_driver() above, but with
+ * the init call promoted to subsys_initcall() for built-in drivers so they
+ * are available earlier during boot. When built as a module subsys_initcall()
+ * collapses to module_init() and the normal module init/exit paths are used.
+ *
+ * Use this macro to construct bus specific macros for registering drivers,
+ * and do not use it on its own.
+ */
+#define subsys_driver(__driver, __register, __unregister, ...) \
+static int __init __driver##_init(void) \
+{ \
+ return __register(&(__driver), ##__VA_ARGS__); \
+} \
+subsys_initcall(__driver##_init) \
+static void __exit __driver##_exit(void) \
+{ \
+ __unregister(&(__driver), ##__VA_ARGS__); \
+} \
+module_exit(__driver##_exit)
+
#endif /* _DEVICE_DRIVER_H_ */