* [PATCH 1/3] clocksource/drivers/timer-mediatek: Fix random crash at boot
2026-10-02 7:19 [PATCH 0/3] Convert MediaTek GPT timers to OF probing Luca Leonardo Scorcia
@ 2026-10-02 7:19 ` Luca Leonardo Scorcia
2026-10-02 7:19 ` [PATCH 2/3] clocksource/drivers/timer-mediatek: Convert to OF probing Luca Leonardo Scorcia
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Luca Leonardo Scorcia @ 2026-10-02 7:19 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Daniel Lezcano, Thomas Gleixner,
Matthias Brugger, AngeloGioacchino Del Regno, Stanley Chu,
linux-kernel, linux-arm-kernel
MediaTek bootloaders generally enable APXGPT timers at boot. This means
that a timer IRQ can sometimes happen between the IRQ line request and the
configuration of the clock event handler. This leads to a hard crash with
an instruction abort, branch to pc 0x0 in mtk_gpt_interrupt handler as
clkevt is null.
To avoid this issue request the IRQ with IRQF_NO_AUTOEN and enable it
explicitly after the clock event is configured.
Issue was reported and fix tested on the Lenovo Tab E7 (TB-7104F, mt8167).
Fixes: a0858f937960 ("clocksource/drivers/timer-mediatek: Convert the driver to timer-of")
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
Credits for issue discovery and suggested fix go to
matemiller992 on postmarketOS forums. I am submitting it upstream with
permission. Not adding Reported-by or Suggested-by tags because it was
requested not to share real name.
drivers/clocksource/timer-mediatek.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index 7bcb4a3f26fb..e20075b09fab 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -277,7 +277,7 @@ static struct timer_of to = {
},
.of_irq = {
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_NO_AUTOEN,
},
};
@@ -298,6 +298,7 @@ static int __init mtk_syst_init(struct device_node *node)
clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
TIMER_SYNC_TICKS, 0xffffffff);
+ enable_irq(timer_of_irq(&to));
return 0;
}
@@ -334,6 +335,7 @@ static int __init mtk_gpt_init(struct device_node *node)
TIMER_SYNC_TICKS, 0xffffffff);
mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
+ enable_irq(timer_of_irq(&to));
return 0;
}
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/3] clocksource/drivers/timer-mediatek: Convert to OF probing
2026-10-02 7:19 [PATCH 0/3] Convert MediaTek GPT timers to OF probing Luca Leonardo Scorcia
2026-10-02 7:19 ` [PATCH 1/3] clocksource/drivers/timer-mediatek: Fix random crash at boot Luca Leonardo Scorcia
@ 2026-10-02 7:19 ` Luca Leonardo Scorcia
2026-10-02 7:19 ` [PATCH 3/3] clocksource/drivers/timer-mediatek: Request and enable the bus clock Luca Leonardo Scorcia
2026-10-02 7:46 ` [PATCH 0/3] Convert MediaTek GPT timers to OF probing Roman Vivchar
3 siblings, 0 replies; 5+ messages in thread
From: Luca Leonardo Scorcia @ 2026-10-02 7:19 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Daniel Lezcano, Thomas Gleixner,
Matthias Brugger, AngeloGioacchino Del Regno, Stanley Chu,
linux-kernel, linux-arm-kernel
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.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
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
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 3/3] clocksource/drivers/timer-mediatek: Request and enable the bus clock
2026-10-02 7:19 [PATCH 0/3] Convert MediaTek GPT timers to OF probing Luca Leonardo Scorcia
2026-10-02 7:19 ` [PATCH 1/3] clocksource/drivers/timer-mediatek: Fix random crash at boot Luca Leonardo Scorcia
2026-10-02 7:19 ` [PATCH 2/3] clocksource/drivers/timer-mediatek: Convert to OF probing Luca Leonardo Scorcia
@ 2026-10-02 7:19 ` Luca Leonardo Scorcia
2026-10-02 7:46 ` [PATCH 0/3] Convert MediaTek GPT timers to OF probing Roman Vivchar
3 siblings, 0 replies; 5+ messages in thread
From: Luca Leonardo Scorcia @ 2026-10-02 7:19 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Daniel Lezcano, Thomas Gleixner,
Matthias Brugger, AngeloGioacchino Del Regno, Stanley Chu,
linux-kernel, linux-arm-kernel
MediaTek APXGPT general purpose timers may optionally depend on a bus
clock. If this clock is not enabled the timers don't actually run. Boot
loaders usually turn it on, but later the kernel turns it off since it's
never requested by any driver.
Some platforms (like mt6735) declare it as a critical clock in their
clock definitions to keep it running, but at least on mt8167 it's not
actually required for a successful boot.
If a bus clock is declared in the device tree, make sure it is enabled
by driver probe and associated to the device.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
drivers/clocksource/timer-mediatek.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/clocksource/timer-mediatek.c b/drivers/clocksource/timer-mediatek.c
index a9e7ff6908a3..842d6ee4259e 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -9,6 +9,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/interrupt.h>
@@ -283,8 +284,9 @@ static struct timer_of to = {
},
};
-static int mtk_syst_init(struct device_node *node)
+static int mtk_syst_init(struct platform_device *pdev)
{
+ struct device_node *node = pdev->dev.of_node;
int ret;
to.clkevt.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_ONESHOT;
@@ -305,10 +307,14 @@ static int 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 platform_device *pdev)
{
+ struct device_node *node = pdev->dev.of_node;
+ struct clk *clk_bus;
int ret;
+ clk_bus = devm_clk_get_optional_enabled(&pdev->dev, "bus");
+
to.clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
to.clkevt.set_state_shutdown = mtk_gpt_clkevt_shutdown;
to.clkevt.set_state_periodic = mtk_gpt_clkevt_set_periodic;
@@ -344,11 +350,10 @@ static int __init mtk_gpt_init(struct device_node *node)
static int mtk_timer_probe(struct platform_device *pdev)
{
- int (*timer_init)(struct device_node *node);
- struct device_node *np = pdev->dev.of_node;
+ int (*timer_init)(struct platform_device *pdev);
timer_init = of_device_get_match_data(&pdev->dev);
- return timer_init(np);
+ return timer_init(pdev);
}
static const struct of_device_id mtk_timer_match_table[] = {
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 0/3] Convert MediaTek GPT timers to OF probing
2026-10-02 7:19 [PATCH 0/3] Convert MediaTek GPT timers to OF probing Luca Leonardo Scorcia
` (2 preceding siblings ...)
2026-10-02 7:19 ` [PATCH 3/3] clocksource/drivers/timer-mediatek: Request and enable the bus clock Luca Leonardo Scorcia
@ 2026-10-02 7:46 ` Roman Vivchar
3 siblings, 0 replies; 5+ messages in thread
From: Roman Vivchar @ 2026-10-02 7:46 UTC (permalink / raw)
To: Luca Leonardo Scorcia
Cc: linux-mediatek, Daniel Lezcano, Thomas Gleixner,
Matthias Brugger, AngeloGioacchino Del Regno, Stanley Chu,
linux-kernel, linux-arm-kernel
Hi,
On Friday, October 2nd, 2026 at 10:21 AM, Luca Leonardo Scorcia <l.scorcia@gmail.com> wrote:
> While chasing a kernel freeze on the Lenovo Tab E7 TB-7104F (mt8167), I
> stumbled on the MediaTek GPT timer driver. This driver is currently early
> loaded via TIMER_OF_DECLARE. I noticed that on mt8167 (and I guess mt8516
> too), this driver actually fails to probe because its device tree
> declaration depends on two HW clocks, CLK_TOP_CLK26M_D2 (13 MHz) and
> CLK_TOP_APXGPT (bus clock). However the driver providing those clocks is
> loaded later in the boot process, leading TIMER_OF_DECLARE to fail with
> -EDEFER.
>
> Patch #2 converts this driver to OF probe, fixing this initial issue.
>
> I noticed that other devices avoid this by connecting the timer to
> fixed clocks instead of referring to an actual clock. This approach
> may work on mt8167 too, but I think referring to the actual clock is
> cleaner.
>
> Once the driver probed successfully I noticed that even if it was enabled
> by the boot loader, the kernel would quickly turn off its bus clock as
> the driver wasn't actually requesting it.
>
> Patch #3 enables it and attaches it to the timer device. I wondered how
> other platforms made it actually work, and noticed that mt6735 declares it
> as a critical clock. This approach might work for mt8167 too, but same
> reasoning as before applies.
Most mt67xx and their 81xx siblings are feeding arch timer from cpuxgpt timers.
These are usually turned on by the firmware at EL3, so in general you can
disable both apxgpt and syst in the devicetree (unless 8167 feeds arch timer
from the gpt6 like 65xx...)
>
> After those fixes the driver probes and works correctly, but I would
> occasionally notice a crash at boot inside the timer interrupt handler.
> It turned out to be a side effect of the bootloader enabling the GPT
> timer at boot: an interrupt may arrive and be handled while the driver is
> not completely initialized.
>
> Patch #1 fixes it by requesting the IRQ but keeping it disabled and
> enabling it after the clock source initialization completes. I sorted this
> patch before the others because it's actually independent of the latter
> two and may fix (rare) random crashes on other devices.
>
> Please note that all the changes apply both to GPT timers and the SYST
> timers, but I have no device to test the SYST ones.
>
> The series was tested on the Sony PlayStation Classic Mini (mt8167).
>
> Re: patch #1, credits for issue discovery and suggested fix go to
> matemiller992 on postmarketOS forums. I am submitting it upstream with
> permission. Not adding Reported-by or Suggested-by tags because it was
> requested not to share real name.
>
> Unfortunately, this series did not fix the tablet randomly freezing during
> boot. Any idea on how to better troubleshoot this is more than welcome!
Have you tried to add {clk,regulator,pd}_ignore_unused? If that doesn't help,
try turning off cpufreq. On mt6595 I had to mark CPU regulator as always-on
(although it should be safe to disable) to avoid system freeze at the boot.
Otherwise start adding status = "disabled" to the devicetree nodes until it
properly boots.
Best regards,
Roman
^ permalink raw reply [flat|nested] 5+ messages in thread