Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | From | AngeloGioacchino Del Regno <> | Subject | [PATCH RFC] RFC: clocksource: timer-mediatek: Add means to register as platform_driver | Date | Thu, 9 Mar 2023 14:21:19 +0100 |
| |
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(-)
diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c index 7bcb4a3f26fb..eda7f60475b6 100644 --- a/drivers/clocksource/timer-mediatek.c +++ b/drivers/clocksource/timer-mediatek.c @@ -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 diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 1d42d4b17327..a5d61a1099e4 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -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) -- 2.39.2
| ![\](/images/icornerr.gif) |