[RFC] RFC: clocksource: timer-mediatek: Add means to register as platform_driver
Commit Message
This commit is not meant to be picked!
As some parties have some interest [1] in converting timers to
modules (for the sake of GKI), which IMO is quite tricky and hard
to do, I started some (quite fast) research on how could this be
achieved: not like that, for sure!
This kind of timers are obviously started early in the kernel init
process and as far as I saw (rightfully) even before pure_initcall,
or actually, better said, even before *any* initcall.
I fully acknowledge that this, as it is right now, is a quite big
hack... though, this actually compiles and actually... works if
timer-mediatek is compiled as built-in (so, in a way, I achieved
nothing), but the addition of the pure_initcall() there may be an
idea for others to experiment with initializing system timers at
a later stage.
This commit is practically one of the last steps involved in the
conversion, but it's meant as a conversation piece for the
interested parties.
Last thing last, after performing this research, I'm not sure
that pursuing modularization for timers is really worth it,
but I may be ignoring something :-)
[1]: https://patchwork.kernel.org/project/linux-mediatek/patch/20230214105412.5856-5-walter.chang@mediatek.com/
---
drivers/clocksource/timer-mediatek.c | 40 ++++++++++++++++++++++++++--
include/linux/clocksource.h | 8 ++++++
2 files changed, 46 insertions(+), 2 deletions(-)
@@ -13,6 +13,7 @@
#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
+#include <linux/platform_device.h>
#include <linux/sched_clock.h>
#include <linux/slab.h>
#include "timer-of.h"
@@ -337,5 +338,40 @@ static int __init mtk_gpt_init(struct device_node *node)
return 0;
}
-TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
-TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
+
+static int mtk_timer_probe(struct platform_device *pdev)
+{
+ int (*mtk_timer_init)(struct device_node *node);
+
+ mtk_timer_init = device_get_match_data(&pdev->dev);
+ if (!mtk_timer_init)
+ return -EINVAL;
+
+ return mtk_timer_init(pdev->dev.of_node);
+}
+
+static const struct of_device_id timer_mediatek_of_match[] __timer_of_section = {
+ { .compatible = "mediatek,mt6577-timer", .data = mtk_gpt_init },
+ { .compatible = "mediatek,mt6765-timer", .data = mtk_syst_init },
+#ifdef MODULE
+ { /* sentinel */ }
+#endif
+};
+MODULE_DEVICE_TABLE(of, timer_mediatek_of_match);
+
+static struct platform_driver timer_mediatek_driver __maybe_unused = {
+ .driver = {
+ .name = "mediatek-timer",
+ .of_match_table = timer_mediatek_of_match,
+ .suppress_bind_attrs = true,
+ },
+ .probe = mtk_timer_probe,
+};
+
+#ifdef MODULE
+static int __init timer_mediatek_init(void)
+{
+ return platform_driver_register(&timer_mediatek_driver);
+}
+pure_initcall(timer_mediatek_init)
+#endif
@@ -279,6 +279,14 @@ extern int clocksource_mmio_init(void __iomem *, const char *,
extern int clocksource_i8253_init(void);
+#if defined(CONFIG_OF) && !defined(MODULE)
+ #define __timer_of_section \
+ __used __section("__timer_of_table") \
+ __aligned(__alignof__(struct of_device_id))
+#else
+ #define __timer_of_section
+#endif
+
#define TIMER_OF_DECLARE(name, compat, fn) \
OF_DECLARE_1_RET(timer, name, compat, fn)