* [PATCH v5 1/4] clocksource/drivers/mmio: Export clocksource_mmio_init()
2026-03-06 8:50 [PATCH v5 0/4] clocksource: Add module support for timer drivers Zhipeng Wang
@ 2026-03-06 8:50 ` Zhipeng Wang
2026-03-06 8:50 ` [PATCH v5 2/4] clocksource/drivers/timer-of: Remove __init markings Zhipeng Wang
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Zhipeng Wang @ 2026-03-06 8:50 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: shawnguo, s.hauer, kernel, festevam, matthias.bgg,
angelogioacchino.delregno, linux-kernel, imx, linux-arm-kernel,
linux-mediatek, chun-hung.wu, walter.chang, jstultz, amergnat,
aisheng.dong, jindong.yue, xuegang.liu
From: Chun-Hung Wu <chun-hung.wu@mediatek.com>
Export clocksource_mmio_init() and clocksource_mmio_readl_up()
to support building clocksource driver as module,
such as timer-mediatek.c.
Signed-off-by: Chun-Hung Wu <chun-hung.wu@mediatek.com>
Signed-off-by: Walter Chang <walter.chang@mediatek.com>
Acked-by: John Stultz <jstultz@google.com>
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
---
drivers/clocksource/mmio.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/clocksource/mmio.c b/drivers/clocksource/mmio.c
index cd5fbf49ac29..238bf29db6f7 100644
--- a/drivers/clocksource/mmio.c
+++ b/drivers/clocksource/mmio.c
@@ -21,6 +21,7 @@ u64 clocksource_mmio_readl_up(struct clocksource *c)
{
return (u64)readl_relaxed(to_mmio_clksrc(c)->reg);
}
+EXPORT_SYMBOL_GPL(clocksource_mmio_readl_up);
u64 clocksource_mmio_readl_down(struct clocksource *c)
{
@@ -46,9 +47,9 @@ u64 clocksource_mmio_readw_down(struct clocksource *c)
* @bits: Number of valid bits
* @read: One of clocksource_mmio_read*() above
*/
-int __init clocksource_mmio_init(void __iomem *base, const char *name,
- unsigned long hz, int rating, unsigned bits,
- u64 (*read)(struct clocksource *))
+int clocksource_mmio_init(void __iomem *base, const char *name,
+ unsigned long hz, int rating, unsigned int bits,
+ u64 (*read)(struct clocksource *))
{
struct clocksource_mmio *cs;
@@ -68,3 +69,4 @@ int __init clocksource_mmio_init(void __iomem *base, const char *name,
return clocksource_register_hz(&cs->clksrc, hz);
}
+EXPORT_SYMBOL_GPL(clocksource_mmio_init);
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v5 2/4] clocksource/drivers/timer-of: Remove __init markings
2026-03-06 8:50 [PATCH v5 0/4] clocksource: Add module support for timer drivers Zhipeng Wang
2026-03-06 8:50 ` [PATCH v5 1/4] clocksource/drivers/mmio: Export clocksource_mmio_init() Zhipeng Wang
@ 2026-03-06 8:50 ` Zhipeng Wang
2026-03-06 8:50 ` [PATCH v5 3/4] clocksource/drivers/timer-mediatek: Convert timer-mediatek to a loadable module Zhipeng Wang
2026-03-06 8:50 ` [PATCH v5 4/4] clocksource/drivers/imx-tpm: Support building imx-tpm driver as module Zhipeng Wang
3 siblings, 0 replies; 7+ messages in thread
From: Zhipeng Wang @ 2026-03-06 8:50 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: shawnguo, s.hauer, kernel, festevam, matthias.bgg,
angelogioacchino.delregno, linux-kernel, imx, linux-arm-kernel,
linux-mediatek, chun-hung.wu, walter.chang, jstultz, amergnat,
aisheng.dong, jindong.yue, xuegang.liu
From: Chun-Hung Wu <chun-hung.wu@mediatek.com>
Remove __init markings to allow timer drivers
can be compiled as modules.
Signed-off-by: Chun-Hung Wu <chun-hung.wu@mediatek.com>
Signed-off-by: Walter Chang <walter.chang@mediatek.com>
Acked-by: John Stultz <jstultz@google.com>
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
---
drivers/clocksource/timer-of.c | 23 ++++++++++++-----------
drivers/clocksource/timer-of.h | 6 +++---
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/clocksource/timer-of.c b/drivers/clocksource/timer-of.c
index 420202bf76e4..b7c186dc83da 100644
--- a/drivers/clocksource/timer-of.c
+++ b/drivers/clocksource/timer-of.c
@@ -19,7 +19,7 @@
*
* Free the irq resource
*/
-static __init void timer_of_irq_exit(struct of_timer_irq *of_irq)
+static void timer_of_irq_exit(struct of_timer_irq *of_irq)
{
struct timer_of *to = container_of(of_irq, struct timer_of, of_irq);
@@ -41,8 +41,8 @@ static __init void timer_of_irq_exit(struct of_timer_irq *of_irq)
*
* Returns 0 on success, < 0 otherwise
*/
-static __init int timer_of_irq_init(struct device_node *np,
- struct of_timer_irq *of_irq)
+static int timer_of_irq_init(struct device_node *np,
+ struct of_timer_irq *of_irq)
{
int ret;
struct timer_of *to = container_of(of_irq, struct timer_of, of_irq);
@@ -82,7 +82,7 @@ static __init int timer_of_irq_init(struct device_node *np,
*
* Disables and releases the refcount on the clk
*/
-static __init void timer_of_clk_exit(struct of_timer_clk *of_clk)
+static void timer_of_clk_exit(struct of_timer_clk *of_clk)
{
of_clk->rate = 0;
clk_disable_unprepare(of_clk->clk);
@@ -98,8 +98,8 @@ static __init void timer_of_clk_exit(struct of_timer_clk *of_clk)
*
* Returns 0 on success, < 0 otherwise
*/
-static __init int timer_of_clk_init(struct device_node *np,
- struct of_timer_clk *of_clk)
+static int timer_of_clk_init(struct device_node *np,
+ struct of_timer_clk *of_clk)
{
int ret;
@@ -137,13 +137,13 @@ static __init int timer_of_clk_init(struct device_node *np,
goto out;
}
-static __init void timer_of_base_exit(struct of_timer_base *of_base)
+static void timer_of_base_exit(struct of_timer_base *of_base)
{
iounmap(of_base->base);
}
-static __init int timer_of_base_init(struct device_node *np,
- struct of_timer_base *of_base)
+static int timer_of_base_init(struct device_node *np,
+ struct of_timer_base *of_base)
{
of_base->base = of_base->name ?
of_io_request_and_map(np, of_base->index, of_base->name) :
@@ -156,7 +156,7 @@ static __init int timer_of_base_init(struct device_node *np,
return 0;
}
-int __init timer_of_init(struct device_node *np, struct timer_of *to)
+int timer_of_init(struct device_node *np, struct timer_of *to)
{
int ret = -EINVAL;
int flags = 0;
@@ -200,6 +200,7 @@ int __init timer_of_init(struct device_node *np, struct timer_of *to)
timer_of_base_exit(&to->of_base);
return ret;
}
+EXPORT_SYMBOL_GPL(timer_of_init);
/**
* timer_of_cleanup - release timer_of resources
@@ -208,7 +209,7 @@ int __init timer_of_init(struct device_node *np, struct timer_of *to)
* Release the resources that has been used in timer_of_init().
* This function should be called in init error cases
*/
-void __init timer_of_cleanup(struct timer_of *to)
+void timer_of_cleanup(struct timer_of *to)
{
if (to->flags & TIMER_OF_IRQ)
timer_of_irq_exit(&to->of_irq);
diff --git a/drivers/clocksource/timer-of.h b/drivers/clocksource/timer-of.h
index 01a2c6b7db06..367d7023c623 100644
--- a/drivers/clocksource/timer-of.h
+++ b/drivers/clocksource/timer-of.h
@@ -65,9 +65,9 @@ static inline unsigned long timer_of_period(struct timer_of *to)
return to->of_clk.period;
}
-extern int __init timer_of_init(struct device_node *np,
- struct timer_of *to);
+extern int timer_of_init(struct device_node *np,
+ struct timer_of *to);
-extern void __init timer_of_cleanup(struct timer_of *to);
+extern void timer_of_cleanup(struct timer_of *to);
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v5 3/4] clocksource/drivers/timer-mediatek: Convert timer-mediatek to a loadable module
2026-03-06 8:50 [PATCH v5 0/4] clocksource: Add module support for timer drivers Zhipeng Wang
2026-03-06 8:50 ` [PATCH v5 1/4] clocksource/drivers/mmio: Export clocksource_mmio_init() Zhipeng Wang
2026-03-06 8:50 ` [PATCH v5 2/4] clocksource/drivers/timer-of: Remove __init markings Zhipeng Wang
@ 2026-03-06 8:50 ` Zhipeng Wang
2026-03-06 16:51 ` Frank Li
2026-03-06 8:50 ` [PATCH v5 4/4] clocksource/drivers/imx-tpm: Support building imx-tpm driver as module Zhipeng Wang
3 siblings, 1 reply; 7+ messages in thread
From: Zhipeng Wang @ 2026-03-06 8:50 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: shawnguo, s.hauer, kernel, festevam, matthias.bgg,
angelogioacchino.delregno, linux-kernel, imx, linux-arm-kernel,
linux-mediatek, chun-hung.wu, walter.chang, jstultz, amergnat,
aisheng.dong, jindong.yue, xuegang.liu
From: Chun-Hung Wu <chun-hung.wu@mediatek.com>
Convert the timer-mediatek driver into a loadable module so that it
can register an always-on timer as the tick_broadcast_device on
MediaTek SoCs. This helps support GKI(Generic Kernel Image) modular
configurations.
Signed-off-by: Chun-Hung Wu <chun-hung.wu@mediatek.com>
Signed-off-by: Walter Chang <walter.chang@mediatek.com>
Tested-by: Walter Chang <walter.chang@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
---
drivers/clocksource/Kconfig | 2 +-
drivers/clocksource/timer-mediatek.c | 33 ++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fd9112706545..2112efb85029 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -488,7 +488,7 @@ config SYS_SUPPORTS_SH_CMT
bool
config MTK_TIMER
- bool "Mediatek timer driver" if COMPILE_TEST
+ tristate "MediaTek timer driver"
depends on HAS_IOMEM
select TIMER_OF
select CLKSRC_MMIO
diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 7bcb4a3f26fb..4ad4bac6f34b 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -13,6 +13,9 @@
#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
#include <linux/sched_clock.h>
#include <linux/slab.h>
#include "timer-of.h"
@@ -337,5 +340,35 @@ static int __init mtk_gpt_init(struct device_node *node)
return 0;
}
+
+#ifndef MODULE
TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
+#else
+static int mtk_timer_probe(struct platform_device *pdev)
+{
+ int (*timer_init)(struct device_node *node);
+ struct device_node *np = pdev->dev.of_node;
+
+ timer_init = of_device_get_match_data(&pdev->dev);
+ return timer_init(np);
+}
+
+static const struct of_device_id mtk_timer_match_table[] = {
+ { .compatible = "mediatek,mt6577-timer", .data = mtk_gpt_init },
+ { .compatible = "mediatek,mt6765-timer", .data = mtk_syst_init },
+ { /* sentinel */ }
+};
+
+static struct platform_driver mtk_timer_driver = {
+ .probe = mtk_timer_probe,
+ .driver = {
+ .name = "mediatek-timer",
+ .of_match_table = mtk_timer_match_table,
+ },
+};
+module_platform_driver(mtk_timer_driver);
+
+MODULE_DESCRIPTION("MediaTek Timer driver");
+MODULE_LICENSE("GPL");
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v5 3/4] clocksource/drivers/timer-mediatek: Convert timer-mediatek to a loadable module
2026-03-06 8:50 ` [PATCH v5 3/4] clocksource/drivers/timer-mediatek: Convert timer-mediatek to a loadable module Zhipeng Wang
@ 2026-03-06 16:51 ` Frank Li
2026-03-06 17:33 ` Frank Li
0 siblings, 1 reply; 7+ messages in thread
From: Frank Li @ 2026-03-06 16:51 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: Frank Li, shawnguo, s.hauer, kernel, festevam, matthias.bgg,
angelogioacchino.delregno, linux-kernel, imx, linux-arm-kernel,
linux-mediatek, chun-hung.wu, walter.chang, jstultz, amergnat,
aisheng.dong, jindong.yue, xuegang.liu
From: Frank Li (AI-BOT) <frank.li@nxp.com>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
AI: Include headers should be sorted alphabetically. "of_device.h" should come
before "platform_device.h".
Frank
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 3/4] clocksource/drivers/timer-mediatek: Convert timer-mediatek to a loadable module
2026-03-06 16:51 ` Frank Li
@ 2026-03-06 17:33 ` Frank Li
0 siblings, 0 replies; 7+ messages in thread
From: Frank Li @ 2026-03-06 17:33 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: shawnguo, s.hauer, kernel, festevam, matthias.bgg,
angelogioacchino.delregno, linux-kernel, imx, linux-arm-kernel,
linux-mediatek, chun-hung.wu, walter.chang, jstultz, amergnat,
aisheng.dong, jindong.yue, xuegang.liu
On Fri, Mar 06, 2026 at 11:51:39AM -0500, Frank Li wrote:
> From: Frank Li (AI-BOT) <frank.li@nxp.com>
>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
>
> AI: Include headers should be sorted alphabetically. "of_device.h" should come
> before "platform_device.h".
Please forget it. Sorry for annoise.
Frank
>
> Frank
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 4/4] clocksource/drivers/imx-tpm: Support building imx-tpm driver as module
2026-03-06 8:50 [PATCH v5 0/4] clocksource: Add module support for timer drivers Zhipeng Wang
` (2 preceding siblings ...)
2026-03-06 8:50 ` [PATCH v5 3/4] clocksource/drivers/timer-mediatek: Convert timer-mediatek to a loadable module Zhipeng Wang
@ 2026-03-06 8:50 ` Zhipeng Wang
3 siblings, 0 replies; 7+ messages in thread
From: Zhipeng Wang @ 2026-03-06 8:50 UTC (permalink / raw)
To: daniel.lezcano, tglx
Cc: shawnguo, s.hauer, kernel, festevam, matthias.bgg,
angelogioacchino.delregno, linux-kernel, imx, linux-arm-kernel,
linux-mediatek, chun-hung.wu, walter.chang, jstultz, amergnat,
aisheng.dong, jindong.yue, xuegang.liu
From: Jindong Yue <jindong.yue@nxp.com>
Change defconfig as tristate type and add platform driver
to support building it as a module.
Signed-off-by: Jindong Yue <jindong.yue@nxp.com>
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
---
drivers/clocksource/Kconfig | 2 +-
drivers/clocksource/timer-imx-tpm.c | 40 +++++++++++++++++++++++++----
2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 2112efb85029..1ba3e9bca3db 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -613,7 +613,7 @@ config CLKSRC_IMX_GPT
select CLKSRC_MMIO
config CLKSRC_IMX_TPM
- bool "Clocksource using i.MX TPM" if COMPILE_TEST
+ tristate "Clocksource using i.MX TPM"
depends on (ARM || ARM64) && HAVE_CLK
select CLKSRC_MMIO
select TIMER_OF
diff --git a/drivers/clocksource/timer-imx-tpm.c b/drivers/clocksource/timer-imx-tpm.c
index 92c025b70eb6..1d593b6f0c37 100644
--- a/drivers/clocksource/timer-imx-tpm.c
+++ b/drivers/clocksource/timer-imx-tpm.c
@@ -8,6 +8,8 @@
#include <linux/clocksource.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/sched_clock.h>
#include "timer-of.h"
@@ -66,7 +68,7 @@ static inline unsigned long tpm_read_counter(void)
return readl(timer_base + TPM_CNT);
}
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) && !defined(MODULE)
static struct delay_timer tpm_delay_timer;
static unsigned long tpm_read_current_timer(void)
@@ -152,9 +154,9 @@ static struct timer_of to_tpm = {
},
};
-static int __init tpm_clocksource_init(void)
+static int tpm_clocksource_init(void)
{
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) && !defined(MODULE)
tpm_delay_timer.read_current_timer = &tpm_read_current_timer;
tpm_delay_timer.freq = timer_of_rate(&to_tpm) >> 3;
register_current_timer_delay(&tpm_delay_timer);
@@ -171,7 +173,7 @@ static int __init tpm_clocksource_init(void)
clocksource_mmio_readl_up);
}
-static void __init tpm_clockevent_init(void)
+static void tpm_clockevent_init(void)
{
clockevents_config_and_register(&to_tpm.clkevt,
timer_of_rate(&to_tpm) >> 3,
@@ -180,7 +182,7 @@ static void __init tpm_clockevent_init(void)
1));
}
-static int __init tpm_timer_init(struct device_node *np)
+static int tpm_timer_init(struct device_node *np)
{
struct clk *ipg;
int ret;
@@ -241,4 +243,32 @@ static int __init tpm_timer_init(struct device_node *np)
return tpm_clocksource_init();
}
+#ifdef MODULE
+static int tpm_timer_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+
+ return tpm_timer_init(np);
+}
+
+static const struct of_device_id tpm_timer_match_table[] = {
+ { .compatible = "fsl,imx7ulp-tpm" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tpm_timer_match_table);
+
+static struct platform_driver tpm_timer_driver = {
+ .probe = tpm_timer_probe,
+ .driver = {
+ .name = "tpm-timer",
+ .of_match_table = tpm_timer_match_table,
+ },
+};
+module_platform_driver(tpm_timer_driver);
+
+#else
TIMER_OF_DECLARE(imx7ulp, "fsl,imx7ulp-tpm", tpm_timer_init);
+#endif
+
+MODULE_DESCRIPTION("i.MX TPM Timer Driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread