From 9ffa5e6b8f93ccf1a217dd12e204c1a5e211abef Mon Sep 17 00:00:00 2001 From: Johan Jonker Date: Fri, 28 Oct 2022 16:41:30 +0200 Subject: [PATCH 01/11] dt-bindings: timer: rockchip: Add rockchip,rk3128-timer Add rockchip,rk3128-timer compatible string. Signed-off-by: Johan Jonker Acked-by: Krzysztof Kozlowski Reviewed-by: Heiko Stuebner Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/0e57f38f-bace-8556-7258-aa0b3c0ac103@gmail.com --- Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml index dc3bc1e62fe9c..b61ed1a431bb3 100644 --- a/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml +++ b/Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml @@ -18,6 +18,7 @@ properties: - enum: - rockchip,rv1108-timer - rockchip,rk3036-timer + - rockchip,rk3128-timer - rockchip,rk3188-timer - rockchip,rk3228-timer - rockchip,rk3229-timer From aa3f72ea9410f8c9394a5d25bbf40a4cfb56f5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Fri, 4 Nov 2022 17:18:45 +0100 Subject: [PATCH 02/11] dt-bindings: timer: nuvoton,npcm7xx-timer: Allow specifying all clocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timer module contains multiple timers. In the WPCM450 SoC, each timer runs off a clock can be gated individually. To model this correctly, the timer node in the devicetree needs to take multiple clock inputs. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Rob Herring Reviewed-by: Joel Stanley Link: https://lore.kernel.org/r/20221104161850.2889894-2-j.neuschaefer@gmx.net Signed-off-by: Daniel Lezcano --- .../devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml index 737af78ad70c3..d53e1bb98b8a6 100644 --- a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml +++ b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.yaml @@ -25,7 +25,13 @@ properties: - description: The timer interrupt of timer 0 clocks: - maxItems: 1 + items: + - description: The reference clock for timer 0 + - description: The reference clock for timer 1 + - description: The reference clock for timer 2 + - description: The reference clock for timer 3 + - description: The reference clock for timer 4 + minItems: 1 required: - compatible From db78539fc95cf62b0b8f274368fcd8202eac91f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Fri, 4 Nov 2022 17:18:46 +0100 Subject: [PATCH 03/11] clocksource/drivers/timer-npcm7xx: Enable timer 1 clock before use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the WPCM450 SoC, the clocks for each timer can be gated individually. To prevent the timer 1 clock from being gated, enable it explicitly. Signed-off-by: Jonathan Neuschäfer Reviewed-by: Joel Stanley Link: https://lore.kernel.org/r/20221104161850.2889894-3-j.neuschaefer@gmx.net Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-npcm7xx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clocksource/timer-npcm7xx.c b/drivers/clocksource/timer-npcm7xx.c index a00520cbb660a..9af30af5f989a 100644 --- a/drivers/clocksource/timer-npcm7xx.c +++ b/drivers/clocksource/timer-npcm7xx.c @@ -188,6 +188,7 @@ static void __init npcm7xx_clocksource_init(void) static int __init npcm7xx_timer_init(struct device_node *np) { + struct clk *clk; int ret; ret = timer_of_init(np, &npcm7xx_to); @@ -199,6 +200,15 @@ static int __init npcm7xx_timer_init(struct device_node *np) npcm7xx_to.of_clk.rate = npcm7xx_to.of_clk.rate / (NPCM7XX_Tx_MIN_PRESCALE + 1); + /* Enable the clock for timer1, if it exists */ + clk = of_clk_get(np, 1); + if (clk) { + if (!IS_ERR(clk)) + clk_prepare_enable(clk); + else + pr_warn("%pOF: Failed to get clock for timer1: %pe", np, clk); + } + npcm7xx_clocksource_init(); npcm7xx_clockevents_init(); From 45ae272a948a03a7d55748bf52d2f47d3b4e1d5a Mon Sep 17 00:00:00 2001 From: Joe Korty Date: Mon, 21 Nov 2022 14:53:43 +0000 Subject: [PATCH 04/11] clocksource/drivers/arm_arch_timer: Fix XGene-1 TVAL register math error The TVAL register is 32 bit signed. Thus only the lower 31 bits are available to specify when an interrupt is to occur at some time in the near future. Attempting to specify a larger interval with TVAL results in a negative time delta which means the timer fires immediately upon being programmed, rather than firing at that expected future time. The solution is for Linux to declare that TVAL is a 31 bit register rather than give its true size of 32 bits. This prevents Linux from programming TVAL with a too-large value. Note that, prior to 5.16, this little trick was the standard way to handle TVAL in Linux, so there is nothing new happening here on that front. The softlockup detector hides the issue, because it keeps generating short timer deadlines that are within the scope of the broken timer. Disable it, and you start using NO_HZ with much longer timer deadlines, which turns into an interrupt flood: 11: 1124855130 949168462 758009394 76417474 104782230 30210281 310890 1734323687 GICv2 29 Level arch_timer And "much longer" isn't that long: it takes less than 43s to underflow TVAL at 50MHz (the frequency of the counter on XGene-1). Some comments on the v1 version of this patch by Marc Zyngier: XGene implements CVAL (a 64bit comparator) in terms of TVAL (a countdown register) instead of the other way around. TVAL being a 32bit register, the width of the counter should equally be 32. However, TVAL is a *signed* value, and keeps counting down in the negative range once the timer fires. It means that any TVAL value with bit 31 set will fire immediately, as it cannot be distinguished from an already expired timer. Reducing the timer range back to a paltry 31 bits papers over the issue. Another problem cannot be fixed though, which is that the timer interrupt *must* be handled within the negative countdown period, or the interrupt will be lost (TVAL will rollover to a positive value, indicative of a new timer deadline). Cc: stable@vger.kernel.org # 5.16+ Fixes: 012f18850452 ("clocksource/drivers/arm_arch_timer: Work around broken CVAL implementations") Signed-off-by: Joe Korty Reviewed-by: Marc Zyngier [maz: revamped the commit message] Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20221024165422.GA51107@zipoli.concurrent-rt.com Link: https://lore.kernel.org/r/20221121145343.896018-1-maz@kernel.org Signed-off-by: Daniel Lezcano --- drivers/clocksource/arm_arch_timer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 9c3420a0d19d0..e2920da18ea1c 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -806,6 +806,9 @@ static u64 __arch_timer_check_delta(void) /* * XGene-1 implements CVAL in terms of TVAL, meaning * that the maximum timer range is 32bit. Shame on them. + * + * Note that TVAL is signed, thus has only 31 of its + * 32 bits to express magnitude. */ MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, APM_CPU_PART_POTENZA)), @@ -813,8 +816,8 @@ static u64 __arch_timer_check_delta(void) }; if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) { - pr_warn_once("Broken CNTx_CVAL_EL1, limiting width to 32bits"); - return CLOCKSOURCE_MASK(32); + pr_warn_once("Broken CNTx_CVAL_EL1, using 32 bit TVAL instead.\n"); + return CLOCKSOURCE_MASK(31); } #endif return CLOCKSOURCE_MASK(arch_counter_get_width()); From 9688498b1648aa98a3ee45d9f07763c099f6fb12 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 28 Oct 2022 13:35:26 +0300 Subject: [PATCH 05/11] clocksource/drivers/timer-ti-dm: Fix warning for omap_timer_match We can now get a warning for 'omap_timer_match' defined but not used. Let's fix this by dropping of_match_ptr for omap_timer_match. Reported-by: kernel test robot Fixes: ab0bbef3ae0f ("clocksource/drivers/timer-ti-dm: Make timer selectable for ARCH_K3") Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20221028103526.40319-1-tony@atomide.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-ti-dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c index cad29ded3a48f..00af1a8e34fbd 100644 --- a/drivers/clocksource/timer-ti-dm.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -1258,7 +1258,7 @@ static struct platform_driver omap_dm_timer_driver = { .remove = omap_dm_timer_remove, .driver = { .name = "omap_timer", - .of_match_table = of_match_ptr(omap_timer_match), + .of_match_table = omap_timer_match, .pm = &omap_dm_timer_pm_ops, }, }; From dedb2aced3e958c6f4811d3e6b392652ff0eea01 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 28 Oct 2022 13:36:04 +0300 Subject: [PATCH 06/11] clocksource/drivers/timer-ti-dm: Make timer_get_irq static We can make timer_get_irq() static as noted by Janusz. It is only used by omap_rproc_get_timer_irq() via platform data. Reported-by: Janusz Krzysztofik Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20221028103604.40385-1-tony@atomide.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-ti-dm.c | 2 +- include/clocksource/timer-ti-dm.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c index 00af1a8e34fbd..eeeeb3c08c91a 100644 --- a/drivers/clocksource/timer-ti-dm.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -643,7 +643,7 @@ static int omap_dm_timer_free(struct omap_dm_timer *cookie) return 0; } -int omap_dm_timer_get_irq(struct omap_dm_timer *cookie) +static int omap_dm_timer_get_irq(struct omap_dm_timer *cookie) { struct dmtimer *timer = to_dmtimer(cookie); if (timer) diff --git a/include/clocksource/timer-ti-dm.h b/include/clocksource/timer-ti-dm.h index 77eceeae708cf..dcc1712f75e78 100644 --- a/include/clocksource/timer-ti-dm.h +++ b/include/clocksource/timer-ti-dm.h @@ -62,8 +62,6 @@ struct omap_dm_timer { }; -int omap_dm_timer_get_irq(struct omap_dm_timer *timer); - u32 omap_dm_timer_modify_idlect_mask(u32 inputmask); /* From 822963b96dfdb72ec4fb1395fbdfa778656b49d1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 28 Oct 2022 13:38:13 +0300 Subject: [PATCH 07/11] clocksource/drivers/timer-ti-dm: Clear settings on probe and free Clear the timer control register on driver probe and omap_dm_timer_free(). Otherwise we assume the consumer driver takes care of properly initializing timer interrupts on PWM driver module reload for example. AFAIK this is not currently needed as a fix, I just happened to run into this while cleaning up things. Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20221028103813.40783-1-tony@atomide.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-ti-dm.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c index eeeeb3c08c91a..b24b903a88222 100644 --- a/drivers/clocksource/timer-ti-dm.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -633,6 +633,8 @@ static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *n static int omap_dm_timer_free(struct omap_dm_timer *cookie) { struct dmtimer *timer; + struct device *dev; + int rc; timer = to_dmtimer(cookie); if (unlikely(!timer)) @@ -640,6 +642,17 @@ static int omap_dm_timer_free(struct omap_dm_timer *cookie) WARN_ON(!timer->reserved); timer->reserved = 0; + + dev = &timer->pdev->dev; + rc = pm_runtime_resume_and_get(dev); + if (rc) + return rc; + + /* Clear timer configuration */ + dmtimer_write(timer, OMAP_TIMER_CTRL_REG, 0); + + pm_runtime_put_sync(dev); + return 0; } @@ -1135,6 +1148,10 @@ static int omap_dm_timer_probe(struct platform_device *pdev) goto err_disable; } __omap_dm_timer_init_regs(timer); + + /* Clear timer configuration */ + dmtimer_write(timer, OMAP_TIMER_CTRL_REG, 0); + pm_runtime_put(dev); } From 180d35a7c05d520314a590c99ad8643d0213f28b Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Sat, 29 Oct 2022 19:44:27 +0800 Subject: [PATCH 08/11] clocksource/drivers/timer-ti-dm: Fix missing clk_disable_unprepare in dmtimer_systimer_init_clock() If clk_get_rate() fails which is called after clk_prepare_enable(), clk_disable_unprepare() need be called in error path to disable the clock in dmtimer_systimer_init_clock(). Fixes: 52762fbd1c47 ("clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support") Signed-off-by: Yang Yingliang Reviewed-by: Tony Lindgren Link: https://lore.kernel.org/r/20221029114427.946520-1-yangyingliang@huawei.com Signed-off-by: Daniel Lezcano --- drivers/clocksource/timer-ti-dm-systimer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c index 2737407ff0698..632523c1232f6 100644 --- a/drivers/clocksource/timer-ti-dm-systimer.c +++ b/drivers/clocksource/timer-ti-dm-systimer.c @@ -345,8 +345,10 @@ static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t, return error; r = clk_get_rate(clock); - if (!r) + if (!r) { + clk_disable_unprepare(clock); return -ENODEV; + } if (is_ick) t->ick = clock; From 4238568744c0a150d8901e7847092a0f871c938d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 1 Nov 2022 22:13:58 +0100 Subject: [PATCH 09/11] clocksource/drivers/arm_arch_timer: Use kstrtobool() instead of strtobool() strtobool() is the same as kstrtobool(). However, the latter is more used within the kernel. In order to remove strtobool() and slightly simplify kstrtox.h, switch to the other function name. While at it, include the corresponding header file () Signed-off-by: Christophe JAILLET Acked-by: Mark Rutland Link: https://lore.kernel.org/r/f430bb12e12eb225ab1206db0be64b755ddafbdc.1667336095.git.christophe.jaillet@wanadoo.fr Signed-off-by: Daniel Lezcano --- drivers/clocksource/arm_arch_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index e2920da18ea1c..1695c56a2aaea 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -97,7 +98,7 @@ static bool evtstrm_enable __ro_after_init = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EV static int __init early_evtstrm_cfg(char *buf) { - return strtobool(buf, &evtstrm_enable); + return kstrtobool(buf, &evtstrm_enable); } early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg); From bbf687daab58ef8d09916d69537ff6fa2c849e88 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 3 Nov 2022 21:48:58 +0100 Subject: [PATCH 10/11] dt-bindings: timer: renesas,tmu: Add r8a779g0 support Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20221103204859.24667-1-wsa+renesas@sang-engineering.com Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/timer/renesas,tmu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/timer/renesas,tmu.yaml b/Documentation/devicetree/bindings/timer/renesas,tmu.yaml index 60f4c059bcffd..a67e427a9e7e2 100644 --- a/Documentation/devicetree/bindings/timer/renesas,tmu.yaml +++ b/Documentation/devicetree/bindings/timer/renesas,tmu.yaml @@ -38,6 +38,7 @@ properties: - renesas,tmu-r8a77995 # R-Car D3 - renesas,tmu-r8a779a0 # R-Car V3U - renesas,tmu-r8a779f0 # R-Car S4-8 + - renesas,tmu-r8a779g0 # R-Car V4H - const: renesas,tmu reg: From 83571a4389039b1be2d77655b2ce47543d407e41 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 4 Nov 2022 16:06:42 +0100 Subject: [PATCH 11/11] dt-bindings: timer: renesas,cmt: Add r8a779g0 CMT support Signed-off-by: Wolfram Sang Acked-by: Rob Herring Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20221104150642.4587-1-wsa+renesas@sang-engineering.com Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/timer/renesas,cmt.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.yaml b/Documentation/devicetree/bindings/timer/renesas,cmt.yaml index bde6c9b66bf42..a0be1755ea28b 100644 --- a/Documentation/devicetree/bindings/timer/renesas,cmt.yaml +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.yaml @@ -102,12 +102,14 @@ properties: - enum: - renesas,r8a779a0-cmt0 # 32-bit CMT0 on R-Car V3U - renesas,r8a779f0-cmt0 # 32-bit CMT0 on R-Car S4-8 + - renesas,r8a779g0-cmt0 # 32-bit CMT0 on R-Car V4H - const: renesas,rcar-gen4-cmt0 # 32-bit CMT0 on R-Car Gen4 - items: - enum: - renesas,r8a779a0-cmt1 # 48-bit CMT on R-Car V3U - renesas,r8a779f0-cmt1 # 48-bit CMT on R-Car S4-8 + - renesas,r8a779g0-cmt1 # 48-bit CMT on R-Car V4H - const: renesas,rcar-gen4-cmt1 # 48-bit CMT on R-Car Gen4 reg: