Re: [PATCH 2/3] clocksource/drivers/timer-mediatek: Convert to OF probing
From: Chen-Yu Tsai
Date: Mon Nov 09 2026 - 04:52:35 EST
On Fri, Oct 02, 2026 at 09:19:27AM +0200, Luca Leonardo Scorcia wrote:
> MediaTek APXGPT general purpose timer driver is registered via
> TIMER_OF_DECLARE to be loaded early in the boot process. It depends on
> a reference 13 MHz clock that is assigned via the clocks property of
> its DT node.
> On platforms like mt8516/mt8167 this clock is provided by a driver that
> is loaded using OF probing and becomes available only later during boot.
> This leads to a silent EDEFER error during timer init, which is not
> recovered by TIMER_OF_DECLARE and GPT clocks are not registered at all.
>
> Since those clocks are not critical for boot, convert the timer-mediatek
> to OF probing and drop the TIMER_OF_DECLARE instructions.
I think this is now triggering some lockdep warnings.
[ +0.000084] BUG: sleeping function called from invalid context at ./include/linux/percpu-rwsem.h:51
[ +0.000086] in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 1, name: swapper/0
[ +0.000079] preempt_count: 0, expected: 0
[ +0.000050] RCU nest depth: 0, expected: 0
[ +0.000051] locks held by swapper/0/1: 1, last CPU#3:
[ +0.000060] #0: ffffff80c15d1138 (&dev->mutex){....}-{4:4}, at: __driver_attach (./include/linux/device.h:1109 drivers/base/dd.c:1046 drivers/base/dd.c:1299)
[ +0.000142] irq event stamp: 250728
[ +0.067364] hardirqs last enabled at (250727): tick_oneshot_mode_active (kernel/time/tick-oneshot.c:128)
[ +0.009480] hardirqs last disabled at (250728): sched_clock_register (kernel/time/sched_clock.c:189)
[ +0.009301] softirqs last enabled at (250642): __do_softirq (kernel/softirq.c:703)
[ +0.008427] softirqs last disabled at (250637): __do_softirq (kernel/softirq.c:703)
[ +0.008433] CPU: 3 UID: 0 PID: 1 Comm: swapper/0 Tainted: G W 7.4.0-rc1-next-20261105-04243-gd86019357887 #373 PREEMPT>
[ +0.000018] Tainted: [W]=WARN
[ +0.000005] Hardware name: Google Hana (DT)
[ +0.000007] Call trace:
[ +0.000005] show_stack (arch/arm64/kernel/stacktrace.c:499) (C)
[ +0.000018] __dump_stack (lib/dump_stack.c:94)
[ +0.000015] dump_stack_lvl (lib/dump_stack.c:120)
[ +0.000015] dump_stack (lib/dump_stack.c:129)
[ +0.000013] __might_resched (kernel/sched/core.c:9195)
[ +0.000018] __might_sleep (kernel/sched/core.c:9124)
[ +0.000014] cpus_read_lock (./include/linux/percpu-rwsem.h:51 ./include/linux/percpu-rwsem.h:77 kernel/cpu.c:490)
[ +0.000013] static_key_enable (kernel/jump_label.c:222)
[ +0.000016] enable_sched_clock_irqtime (kernel/sched/cputime.c:33)
[ +0.000014] sched_clock_register (kernel/time/sched_clock.c:243)
[ +0.000014] mtk_gpt_init (drivers/clocksource/timer-mediatek.c:338)
[ +0.000014] mtk_timer_probe (drivers/clocksource/timer-mediatek.c:356)
[ +0.000014] platform_probe (drivers/base/platform.c:1508)
[ +0.000012] really_probe (drivers/base/dd.c:? drivers/base/dd.c:707)
[ +0.000014] __driver_probe_device (drivers/base/dd.c:869)
[ +0.000014] driver_probe_device (drivers/base/dd.c:899)
[ +0.000014] __driver_attach (drivers/base/dd.c:1300)
[ +0.000014] bus_for_each_dev (drivers/base/bus.c:383)
[ +0.000013] driver_attach (drivers/base/dd.c:1318)
[ +0.000013] bus_add_driver (drivers/base/bus.c:782)
[ +0.000013] driver_register (drivers/base/driver.c:174)
[ +0.000014] __platform_driver_register (drivers/base/platform.c:996)
[ +0.000016] mtk_timer_driver_init (drivers/clocksource/timer-mediatek.c:372)
[ +0.000017] do_one_initcall (init/main.c:1419)
[ +0.000015] do_initcall_level (init/main.c:1481)
[ +0.000014] do_initcalls (init/main.c:1497)
[ +0.000012] do_basic_setup (init/main.c:1517)
[ +0.000013] kernel_init_freeable (init/main.c:1732)
[ +0.000013] kernel_init (init/main.c:1622)
[ +0.000014] ret_from_fork (arch/arm64/kernel/entry.S:870)
> Signed-off-by: Luca Leonardo Scorcia <l.scorcia@xxxxxxxxx>
> ---
> drivers/clocksource/timer-mediatek.c | 36 ++++++++++++++++++++++++----
> 1 file changed, 31 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
> index e20075b09fab..a9e7ff6908a3 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"
> @@ -215,8 +218,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 +283,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;
>
> @@ -339,5 +341,29 @@ 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 (*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");
> --
> 2.43.0
>