[PATCH v1 4/7] clocksource/drivers/timer-probe: Add the module support for the TIMER_PDEV_DECLARE() macro

Daniel Lezcano posted 7 patches 5 days, 21 hours ago
There is a newer version of this series
[PATCH v1 4/7] clocksource/drivers/timer-probe: Add the module support for the TIMER_PDEV_DECLARE() macro
Posted by Daniel Lezcano 5 days, 21 hours ago
A driver using the macro TIMER_PDEV_DECLARE can now be compiled as a
module. When it is the case the TIMER_PDEV_DECLARE() macro will add
module_platform_driver() and MODULE_DEVICE_TABLE() automatically.

However if the early timer initialization is needed in place of the
module init section like what we have now, we should enable
CONFIG_EARLY_TIMER.

When all drivers will be converted to TIMER_PDEV_DECLARE(), the
TIMER_OF_DECLARE() can be removed and we will end up with the
following configuration:

 * On ARM architecture, we enable automatically CONFIG_EARLY_TIMER, no
   timer can be compiled as a module

 * On ARM64 architecture, we can enable as a module, otherwise it will
   be compiled-in. The CONFIG_EARLY_TIMER is not needed on this arch
   because the architected timers are always present

 * On other architecture, that needs to be defined but I suspect we
   have the same scheme

Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel.org>
---
 drivers/clocksource/Kconfig       |  7 ++++++-
 drivers/clocksource/timer-probe.c |  3 +++
 include/linux/clocksource.h       | 12 +++++++++++-
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fd9112706545..ee2372f21e78 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -2,6 +2,11 @@
 menu "Clock Source drivers"
 	depends on GENERIC_CLOCKEVENTS
 
+config EARLY_TIMER
+        bool "Early driver initialization"
+	help
+	  Enables early timer driver loading
+
 config TIMER_OF
 	bool
 	select TIMER_PROBE
@@ -100,7 +105,7 @@ config IXP4XX_TIMER
 	  Enables support for the Intel XScale IXP4xx SoC timer.
 
 config ROCKCHIP_TIMER
-	bool "Rockchip timer driver" if COMPILE_TEST
+        bool "Rockchip timer driver" if COMPILE_TEST
 	depends on ARM || ARM64
 	select TIMER_OF
 	select CLKSRC_MMIO
diff --git a/drivers/clocksource/timer-probe.c b/drivers/clocksource/timer-probe.c
index cdaceb68d356..0fc582e4afde 100644
--- a/drivers/clocksource/timer-probe.c
+++ b/drivers/clocksource/timer-probe.c
@@ -84,6 +84,9 @@ static int __init timer_pdev_probe(void)
 {
 	struct platform_driver **drv;
 
+	if (!IS_ENABLED(CONFIG_EARLY_TIMER))
+		return 0;
+
 	for_each_pdev_timer_table(drv)
 		__timer_pdev_probe(*drv);
 
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 6e05b78e64b8..6b09fe67d37f 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -299,7 +299,7 @@ static inline void timer_probe(void) {}
 extern struct platform_driver *__pdev_timer_table[];
 extern struct platform_driver *__pdev_timer_table_end[];
 
-#define TIMER_PDEV_DECLARE(__name, __probe, __remove, __match)		\
+#define __TIMER_PDEV_DECLARE(__name, __probe, __remove, __match)	\
 	static struct platform_driver __pdev_timer_table_entry_##__name = { \
 		.probe = __probe,					\
 		.remove = __remove,					\
@@ -311,6 +311,16 @@ extern struct platform_driver *__pdev_timer_table_end[];
 	static struct platform_driver *___pdev_timer_table_entry_##__name \
 	__used __section("__pdev_timer_table") = &__pdev_timer_table_entry_##__name
 
+#if !defined(CONFIG_EARLY_TIMER) || defined(MODULE)
+#define TIMER_PDEV_DECLARE(__name, __probe, __remove, __match)		\
+	MODULE_DEVICE_TABLE(of, __match);				\
+	__TIMER_PDEV_DECLARE(__name, __probe, __remove, __match);	\
+	module_platform_driver(__pdev_timer_table_entry_##__name);
+#else
+#define TIMER_PDEV_DECLARE(__name, __probe, __remove, __match)		\
+	__TIMER_PDEV_DECLARE(__name, __probe, __remove, __match)
+#endif
+
 #define for_each_pdev_timer_table(__pdev)     \
 	for (__pdev = __pdev_timer_table;     \
 	     __pdev < __pdev_timer_table_end; \
-- 
2.43.0