* [PATCH resend v1 5/7] clocksource/drivers/rockchip: Use the TIMER_PDEV_DECLARE() macro
2026-03-27 18:05 [PATCH v1 resend 0/7] Timer driver module support Daniel Lezcano
@ 2026-03-27 18:05 ` Daniel Lezcano
2026-03-27 18:05 ` [PATCH resend v1 6/7] clocksource/drivers/rockchip: Add rockchip timer module support Daniel Lezcano
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Daniel Lezcano @ 2026-03-27 18:05 UTC (permalink / raw)
To: daniel.lezcano, tglx, zhipeng.wang_1
Cc: shawnguo, jstultz, linux-kernel, Heiko Stuebner,
moderated list:ARM/Rockchip SoC support,
open list:ARM/Rockchip SoC support
The previous changes introduced the TIMER_PDEV_DECLARE() macro which
allows to use the platform driver to initialize a timer driver with
the benefit of having the devres to rollback automatically in case of
error.
Use this macro and change the function to rely on the devm_ variants,
allowing to cleanup the code.
Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel•org>
---
drivers/clocksource/timer-rockchip.c | 99 ++++++++++------------------
1 file changed, 34 insertions(+), 65 deletions(-)
diff --git a/drivers/clocksource/timer-rockchip.c b/drivers/clocksource/timer-rockchip.c
index 540a16667145..486bbffba464 100644
--- a/drivers/clocksource/timer-rockchip.c
+++ b/drivers/clocksource/timer-rockchip.c
@@ -124,18 +124,18 @@ static u64 notrace rk_timer_sched_read(void)
return ~readl_relaxed(rk_clksrc->base + TIMER_CURRENT_VALUE0);
}
-static int __init
-rk_timer_probe(struct rk_timer *timer, struct device_node *np)
+static int rk_timer_init(struct rk_timer *timer, struct device *dev)
{
+ struct device_node *np = dev->of_node;
struct clk *timer_clk;
struct clk *pclk;
- int ret = -EINVAL, irq;
+ int irq;
u32 ctrl_reg = TIMER_CONTROL_REG3288;
- timer->base = of_iomap(np, 0);
- if (!timer->base) {
+ timer->base = devm_of_iomap(dev, np, 0, NULL);
+ if (IS_ERR(timer->base)) {
pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
- return -ENXIO;
+ return PTR_ERR(timer->base);
}
if (of_device_is_compatible(np, "rockchip,rk3399-timer"))
@@ -143,31 +143,17 @@ rk_timer_probe(struct rk_timer *timer, struct device_node *np)
timer->ctrl = timer->base + ctrl_reg;
- pclk = of_clk_get_by_name(np, "pclk");
+ pclk = devm_clk_get_enabled(dev, "pclk");
if (IS_ERR(pclk)) {
- ret = PTR_ERR(pclk);
pr_err("Failed to get pclk for '%s'\n", TIMER_NAME);
- goto out_unmap;
- }
-
- ret = clk_prepare_enable(pclk);
- if (ret) {
- pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME);
- goto out_unmap;
+ return PTR_ERR(pclk);
}
timer->pclk = pclk;
- timer_clk = of_clk_get_by_name(np, "timer");
+ timer_clk = devm_clk_get_enabled(dev, "timer");
if (IS_ERR(timer_clk)) {
- ret = PTR_ERR(timer_clk);
pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME);
- goto out_timer_clk;
- }
-
- ret = clk_prepare_enable(timer_clk);
- if (ret) {
- pr_err("Failed to enable timer clock\n");
- goto out_timer_clk;
+ return PTR_ERR(timer_clk);
}
timer->clk = timer_clk;
@@ -175,47 +161,32 @@ rk_timer_probe(struct rk_timer *timer, struct device_node *np)
irq = irq_of_parse_and_map(np, 0);
if (!irq) {
- ret = -EINVAL;
pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME);
- goto out_irq;
+ return -EINVAL;
}
timer->irq = irq;
rk_timer_interrupt_clear(timer);
rk_timer_disable(timer);
- return 0;
-
-out_irq:
- clk_disable_unprepare(timer_clk);
-out_timer_clk:
- clk_disable_unprepare(pclk);
-out_unmap:
- iounmap(timer->base);
-
- return ret;
-}
-static void __init rk_timer_cleanup(struct rk_timer *timer)
-{
- clk_disable_unprepare(timer->clk);
- clk_disable_unprepare(timer->pclk);
- iounmap(timer->base);
+ return 0;
}
-static int __init rk_clkevt_init(struct device_node *np)
+static int rk_clkevt_init(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct clock_event_device *ce;
int ret = -EINVAL;
- rk_clkevt = kzalloc_obj(struct rk_clkevt);
+ rk_clkevt = devm_kzalloc(dev, sizeof(*rk_clkevt), GFP_KERNEL);
if (!rk_clkevt) {
ret = -ENOMEM;
goto out;
}
- ret = rk_timer_probe(&rk_clkevt->timer, np);
+ ret = rk_timer_init(&rk_clkevt->timer, dev);
if (ret)
- goto out_probe;
+ goto out;
ce = &rk_clkevt->ce;
ce->name = TIMER_NAME;
@@ -233,36 +204,33 @@ static int __init rk_clkevt_init(struct device_node *np)
if (ret) {
pr_err("Failed to initialize '%s': %d\n",
TIMER_NAME, ret);
- goto out_irq;
+ goto out;
}
clockevents_config_and_register(&rk_clkevt->ce,
rk_clkevt->timer.freq, 1, UINT_MAX);
return 0;
-out_irq:
- rk_timer_cleanup(&rk_clkevt->timer);
-out_probe:
- kfree(rk_clkevt);
out:
/* Leave rk_clkevt not NULL to prevent future init */
rk_clkevt = ERR_PTR(ret);
return ret;
}
-static int __init rk_clksrc_init(struct device_node *np)
+static int rk_clksrc_init(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret = -EINVAL;
- rk_clksrc = kzalloc_obj(struct rk_timer);
+ rk_clksrc = devm_kzalloc(dev, sizeof(*rk_clksrc), GFP_KERNEL);
if (!rk_clksrc) {
ret = -ENOMEM;
goto out;
}
- ret = rk_timer_probe(rk_clksrc, np);
+ ret = rk_timer_init(rk_clksrc, dev);
if (ret)
- goto out_probe;
+ goto out;
rk_timer_update_counter(UINT_MAX, rk_clksrc);
rk_timer_enable(rk_clksrc, 0);
@@ -272,33 +240,34 @@ static int __init rk_clksrc_init(struct device_node *np)
clocksource_mmio_readl_down);
if (ret) {
pr_err("Failed to register clocksource\n");
- goto out_clocksource;
+ goto out;
}
sched_clock_register(rk_timer_sched_read, 32, rk_clksrc->freq);
return 0;
-out_clocksource:
- rk_timer_cleanup(rk_clksrc);
-out_probe:
- kfree(rk_clksrc);
out:
/* Leave rk_clksrc not NULL to prevent future init */
rk_clksrc = ERR_PTR(ret);
return ret;
}
-static int __init rk_timer_init(struct device_node *np)
+static int rk_timer_probe(struct platform_device *pdev)
{
if (!rk_clkevt)
- return rk_clkevt_init(np);
+ return rk_clkevt_init(pdev);
if (!rk_clksrc)
- return rk_clksrc_init(np);
+ return rk_clksrc_init(pdev);
pr_err("Too many timer definitions for '%s'\n", TIMER_NAME);
return -EINVAL;
}
-TIMER_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_init);
-TIMER_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_init);
+static const struct of_device_id rk_timer_match_table[] = {
+ { .compatible = "rockchip,rk3288-timer" },
+ { .compatible = "rockchip,rk3399-timer" },
+ { /* sentinel */ }
+};
+
+TIMER_PDEV_DECLARE(rk_timer, rk_timer_probe, NULL, rk_timer_match_table);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH resend v1 6/7] clocksource/drivers/rockchip: Add rockchip timer module support
2026-03-27 18:05 [PATCH v1 resend 0/7] Timer driver module support Daniel Lezcano
2026-03-27 18:05 ` [PATCH resend v1 5/7] clocksource/drivers/rockchip: Use the TIMER_PDEV_DECLARE() macro Daniel Lezcano
@ 2026-03-27 18:05 ` Daniel Lezcano
2026-03-27 18:05 ` [PATCH resend v1 7/7] clocksource/drivers/mediatek: Convert to " Daniel Lezcano
2026-04-03 7:59 ` [EXT] [PATCH v1 resend 0/7] Timer driver " Zhipeng Wang
3 siblings, 0 replies; 6+ messages in thread
From: Daniel Lezcano @ 2026-03-27 18:05 UTC (permalink / raw)
To: daniel.lezcano, tglx, zhipeng.wang_1
Cc: shawnguo, jstultz, linux-kernel, Heiko Stuebner,
moderated list:ARM/Rockchip SoC support,
open list:ARM/Rockchip SoC support
Now the TIMER_PDEV_DECLARE() allows the driver to be compiled as a
module. Add the MODULE_DESCRIPTION and the MODULE_LICENSE left for the
one converting the driver as a module.
Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel•org>
---
drivers/clocksource/timer-rockchip.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/clocksource/timer-rockchip.c b/drivers/clocksource/timer-rockchip.c
index 486bbffba464..61433b295882 100644
--- a/drivers/clocksource/timer-rockchip.c
+++ b/drivers/clocksource/timer-rockchip.c
@@ -271,3 +271,5 @@ static const struct of_device_id rk_timer_match_table[] = {
};
TIMER_PDEV_DECLARE(rk_timer, rk_timer_probe, NULL, rk_timer_match_table);
+MODULE_DESCRIPTION("Rockchip timer driver");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH resend v1 7/7] clocksource/drivers/mediatek: Convert to module support
2026-03-27 18:05 [PATCH v1 resend 0/7] Timer driver module support Daniel Lezcano
2026-03-27 18:05 ` [PATCH resend v1 5/7] clocksource/drivers/rockchip: Use the TIMER_PDEV_DECLARE() macro Daniel Lezcano
2026-03-27 18:05 ` [PATCH resend v1 6/7] clocksource/drivers/rockchip: Add rockchip timer module support Daniel Lezcano
@ 2026-03-27 18:05 ` Daniel Lezcano
2026-04-03 7:59 ` [EXT] [PATCH v1 resend 0/7] Timer driver " Zhipeng Wang
3 siblings, 0 replies; 6+ messages in thread
From: Daniel Lezcano @ 2026-03-27 18:05 UTC (permalink / raw)
To: daniel.lezcano, tglx, zhipeng.wang_1
Cc: shawnguo, jstultz, linux-kernel, Matthias Brugger,
AngeloGioacchino Del Regno,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
Now the TIMER_PDEV_DECLARE() allows the driver to be compiled as a
module. Add the MODULE_DESCRIPTION and the MODULE_LICENSE left for the
one converting the driver as a module.
Signed-off-by: Daniel Lezcano <daniel.lezcano@kernel•org>
---
drivers/clocksource/timer-mediatek.c | 29 ++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 7bcb4a3f26fb..f5de5f397730 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -215,8 +215,7 @@ static irqreturn_t mtk_gpt_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void
-__init mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
+static void mtk_gpt_setup(struct timer_of *to, u8 timer, u8 option)
{
writel(GPT_CTRL_CLEAR | GPT_CTRL_DISABLE,
timer_of_base(to) + GPT_CTRL_REG(timer));
@@ -281,7 +280,7 @@ static struct timer_of to = {
},
};
-static int __init mtk_syst_init(struct device_node *node)
+static int mtk_syst_init(struct device_node *node)
{
int ret;
@@ -302,7 +301,7 @@ static int __init mtk_syst_init(struct device_node *node)
return 0;
}
-static int __init mtk_gpt_init(struct device_node *node)
+static int mtk_gpt_init(struct device_node *node)
{
int ret;
@@ -337,5 +336,23 @@ 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)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int (*probe_func)(struct device_node *node);
+
+ probe_func = of_device_get_match_data(&pdev->dev);
+
+ return probe_func(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 */ }
+};
+
+TIMER_PDEV_DECLARE(mtk_timer, mtk_timer_probe, NULL, mtk_timer_match_table);
+MODULE_DESCRIPTION("Mediatek timer driver");
+MODULE_LICENSE("GPL");
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* RE: [EXT] [PATCH v1 resend 0/7] Timer driver module support
2026-03-27 18:05 [PATCH v1 resend 0/7] Timer driver module support Daniel Lezcano
` (2 preceding siblings ...)
2026-03-27 18:05 ` [PATCH resend v1 7/7] clocksource/drivers/mediatek: Convert to " Daniel Lezcano
@ 2026-04-03 7:59 ` Zhipeng Wang
2026-04-03 8:50 ` Daniel Lezcano
3 siblings, 1 reply; 6+ messages in thread
From: Zhipeng Wang @ 2026-04-03 7:59 UTC (permalink / raw)
To: Daniel Lezcano, tglx@kernel•org
Cc: shawnguo@kernel•org, jstultz@google•com,
linux-kernel@vger•kernel.org, Matthias Brugger,
AngeloGioacchino Del Regno,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
> -----Original Message-----
> From: Daniel Lezcano <daniel.lezcano@kernel•org>
> Sent: 2026年3月28日 2:06
> To: daniel.lezcano@kernel•org; tglx@kernel•org; Zhipeng Wang
> <zhipeng.wang_1@nxp•com>
> Cc: shawnguo@kernel•org; jstultz@google•com; linux-kernel@vger•kernel.org;
> Matthias Brugger <matthias.bgg@gmail•com>; AngeloGioacchino Del Regno
> <angelogioacchino.delregno@collabora•com>; moderated list:ARM/Mediatek
> SoC support <linux-arm-kernel@lists•infradead.org>; moderated
> list:ARM/Mediatek SoC support <linux-mediatek@lists•infradead.org>
> Subject: [EXT] [PATCH v1 resend 0/7] Timer driver module support
>
> [You don't often get email from daniel.lezcano@kernel•org. Learn why this is
> important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Caution: This is an external email. Please take care when clicking links or
> opening attachments. When in doubt, report the message using the 'Report
> this email' button
>
>
> Converting the timer driver modules requires a particular care because,
> depending on the platform, that may be not supported.
>
> A previous study showed we are safe regarding how the module refcount is
> held and if THIS_MODULE is set for the clockevent and the clocksource when
> they are registered.
>
> It won't be possible to unload a module if a clockevent is registered.
>
> It will be possible to unload a module if only a clocksource is registered and it
> is not the current one.
>
> However platforms without architected timers may need the timer driver to be
> initialized very early and others can be initialized later. The former can not be a
> module and the init function receives a device_node pointer, there is no device
> associated and devres is not used. That results in a lot of rollbacking code
> where usually it is where we find bug and resource leaks. The latter can be
> converted to a module and uses a module_platform_driver(), thus the init
> function is a probe function receiving a struct platform_device pointer
> parameter.
>
> We end up with two approaches and duplicate code for the init functions. This
> is not optimal.
>
> Finally, we have the driver having to be initialized very early on some platforms
> and be built as a module on other platforms, resulting on having two init
> functions co-existing in the same driver.
>
> This series provides what is needed to move to the same probe function for
> early init, builtin and module timers.
>
> A new macro is introduced: TIMER_PDEV_DECLARE() and a new Kconfig option
> is added CONFIG_EARLY_TIMER. TIMER_PDEV_DECLARE() will have different
> behavior depending on the context:
>
> - The driver is a module and CONFIG_EARLY_TIMER=no
> --> the driver is a module
>
> - The driver is builtin and CONFIG_EARLY_TIMER=no
> --> the driver is loaded later
>
> - The driver is builtin or a module but CONFIG_EARLY_TIMER=yes
> --> the driver is initialized through the timer-probe function
>
> The different timer driver framework functions have their __init sections
> removed and the symbols exported in order to be compatible with the drivers
> converted into modules.
>
> The series provides a couple of drivers changed. The Mediatek as a recent
> requested target which is only compiled-tested. The Rockchip timer which was
> tested on a rk3588 in the three different configurations.
>
> Daniel Lezcano (7):
> clocksource/drivers/timer-probe: Create a platform_device before the
> framework is initialized
> drivers/clocksource/rockchip: Use the TIMER_PDEV_DECLARE() macro
> clocksource/drivers/mmio: Make the code compatible with modules
> clocksource/drivers/timer-of: Make the code compatible with modules
> clocksource/drivers/timer-probe: Add the module support for the
> TIMER_PDEV_DECLARE() macro
> clocksource/drivers/rockchip: Add rockchip timer module support
> clocksource/drivers/mediatek: Convert to module support
>
> drivers/clocksource/Kconfig | 7 +-
> drivers/clocksource/mmio.c | 11 ++-
> drivers/clocksource/timer-mediatek.c | 29 ++++++--
> drivers/clocksource/timer-of.c | 24 ++++---
> drivers/clocksource/timer-of.h | 5 +-
> drivers/clocksource/timer-probe.c | 69 ++++++++++++++++--
> drivers/clocksource/timer-rockchip.c | 101 ++++++++++-----------------
> include/asm-generic/vmlinux.lds.h | 10 +++
> include/linux/clocksource.h | 31 ++++++++
> 9 files changed, 194 insertions(+), 93 deletions(-)
>
> --
> 2.43.0
Hi Daniel,
Apologies for the delayed response. Thank you for working on the timer driver module support series. I've
tested your patches on i.MX platforms and they work well with the TPM
timer driver.
Based on your framework, I've converted the i.MX TPM timer driver to
use TIMER_PDEV_DECLARE. The driver has been tested on:
- i.MX7ULP (ARM, no alternative timer): built-in with CONFIG_EARLY_TIMER=y
- i.MX8ULP (ARM64, has ARM Generic Timer): built-in, module, and
CONFIG_EARLY_TIMER=y configurations
All test cases passed without issues.
I'm attaching the patch below:
Author: Zhipeng Wang <zhipeng.wang_1@nxp•com>
Date: Thu Apr 2 15:46:53 2026 +0900
clocksource/drivers/imx-tpm: Convert to TIMER_PDEV_DECLARE and improve resource management
Convert the i.MX TPM timer driver from TIMER_OF_DECLARE to
TIMER_PDEV_DECLARE to support both early initialization and
platform device probing, aligning with the timer driver
modernization effort.
This driver is used on two different platforms with the same
hardware:
- ARM platforms (i.MX7ULP) without alternative timers require
early initialization for delay_timer and sched_clock
- ARM64 platforms (i.MX8ULP) with ARM Generic Timer can use
TPM as a backup timer with deferred initialization
Key changes:
1. Replace TIMER_OF_DECLARE with TIMER_PDEV_DECLARE to enable
flexible initialization based on platform requirements
2. Convert tpm_timer_init() to tpm_timer_probe() with platform
device parameter for proper device model integration
3. Use devm_clk_get_enabled() for ipg clock management instead
of manual clk_prepare_enable/clk_put, fixing potential
resource leaks in error paths
4. Remove __init annotations from tpm_clocksource_init() and
tpm_clockevent_init() to support deferred probing
5. Add proper of_device_id table for device matching
Tested on i.MX7ULP (ARM) and i.MX8ULP (ARM64) platforms.
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp•com>
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 00a5c3a682de9..6e753141b3628 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -618,8 +618,9 @@ 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
+ default ARCH_MXC
select CLKSRC_MMIO
select TIMER_OF
help
diff --git a/drivers/clocksource/timer-imx-tpm.c b/drivers/clocksource/timer-imx-tpm.c
index 92c025b70eb62..13ebb6b627a5b 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"
@@ -152,7 +154,7 @@ static struct timer_of to_tpm = {
},
};
-static int __init tpm_clocksource_init(void)
+static int tpm_clocksource_init(void)
{
#if defined(CONFIG_ARM)
tpm_delay_timer.read_current_timer = &tpm_read_current_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,23 +182,21 @@ static void __init tpm_clockevent_init(void)
1));
}
-static int __init tpm_timer_init(struct device_node *np)
+static int tpm_timer_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
struct clk *ipg;
int ret;
- ipg = of_clk_get_by_name(np, "ipg");
- if (IS_ERR(ipg)) {
- pr_err("tpm: failed to get ipg clk\n");
- return -ENODEV;
- }
- /* enable clk before accessing registers */
- ret = clk_prepare_enable(ipg);
- if (ret) {
- pr_err("tpm: ipg clock enable failed (%d)\n", ret);
- clk_put(ipg);
- return ret;
- }
+ /*
+ * Get and enable ipg clock before accessing registers.
+ * Use devm variant to ensure automatic cleanup on error paths.
+ */
+ ipg = devm_clk_get_enabled(dev, "ipg");
+ if (IS_ERR(ipg))
+ return dev_err_probe(dev, PTR_ERR(ipg),
+ "failed to get ipg clock\n");
ret = timer_of_init(np, &to_tpm);
if (ret)
@@ -241,4 +241,13 @@ static int __init tpm_timer_init(struct device_node *np)
return tpm_clocksource_init();
}
-TIMER_OF_DECLARE(imx7ulp, "fsl,imx7ulp-tpm", tpm_timer_init);
+
+static const struct of_device_id imx_tpm_dt_ids[] = {
+ { .compatible = "fsl,imx7ulp-tpm", },
+ { /* sentinel */ }
+};
+
+TIMER_PDEV_DECLARE(imx_tpm, tpm_timer_probe, NULL, imx_tpm_dt_ids);
+
+MODULE_DESCRIPTION("i.MX TPM Timer Driver");
+MODULE_LICENSE("GPL");
BRs,
Zhipeng
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [EXT] [PATCH v1 resend 0/7] Timer driver module support
2026-04-03 7:59 ` [EXT] [PATCH v1 resend 0/7] Timer driver " Zhipeng Wang
@ 2026-04-03 8:50 ` Daniel Lezcano
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Lezcano @ 2026-04-03 8:50 UTC (permalink / raw)
To: Zhipeng Wang, Daniel Lezcano, tglx@kernel•org
Cc: shawnguo@kernel•org, jstultz@google•com,
linux-kernel@vger•kernel.org, Matthias Brugger,
AngeloGioacchino Del Regno,
moderated list:ARM/Mediatek SoC support,
moderated list:ARM/Mediatek SoC support
Hi Zhipeng,
On 4/3/26 09:59, Zhipeng Wang wrote:
>
[ ... ]
>> 2.43.0
> Hi Daniel,
>
> Apologies for the delayed response. Thank you for working on the timer driver module support series. I've
> tested your patches on i.MX platforms and they work well with the TPM
> timer driver.
>
> Based on your framework, I've converted the i.MX TPM timer driver to
> use TIMER_PDEV_DECLARE. The driver has been tested on:
> - i.MX7ULP (ARM, no alternative timer): built-in with CONFIG_EARLY_TIMER=y
> - i.MX8ULP (ARM64, has ARM Generic Timer): built-in, module, and
> CONFIG_EARLY_TIMER=y configurations
>
> All test cases passed without issues.
thanks for testing
I'll apply patch 2 and 3 and send a v2 for the next release and wait for
more comments.
-- Daniel
[ ... ]
^ permalink raw reply [flat|nested] 6+ messages in thread