From a9fbf2c80545e92e50af8061280b77d6a6ac357a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig=20=28The=20Capable=20Hub=29?= Date: Wed, 17 Jun 2026 11:24:10 +0200 Subject: clocksource/drivers/sh_mtu2: Drop unused assignment of platform_device_id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver explicitly sets the .driver_data member of struct platform_device_id to zero without relying on that value. Drop these unused assignments. While touching this array drop the comma after the list terminator and use a named initializer for .name. Signed-off-by: Uwe Kleine-König (The Capable Hub) Signed-off-by: Daniel Lezcano Link: https://patch.msgid.link/a44e520e437f1b4017b3205c274a2457cbdeb43d.1781687723.git.u.kleine-koenig@baylibre.com --- drivers/clocksource/sh_mtu2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 1997639b113e..3aca86d6a2d4 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -484,8 +484,8 @@ static int sh_mtu2_probe(struct platform_device *pdev) } static const struct platform_device_id sh_mtu2_id_table[] = { - { "sh-mtu2", 0 }, - { }, + { .name = "sh-mtu2" }, + { } }; MODULE_DEVICE_TABLE(platform, sh_mtu2_id_table); -- cgit v1.2.3 From 38c6b710926567aa696332a300e85b6cab56eac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig=20=28The=20Capable=20Hub=29?= Date: Wed, 17 Jun 2026 11:24:11 +0200 Subject: clocksource/drivers/sh_cmt: Use named initializers for platform_device_id arrays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Named initializers are better readable and more robust to changes of the struct definition. This robustness is relevant for a planned change to struct platform_device_id replacing .driver_data by an anonymous union. Signed-off-by: Uwe Kleine-König (The Capable Hub) Signed-off-by: Daniel Lezcano Link: https://patch.msgid.link/6a6951b86f0e9a2ab4a378ab63edf7a487f1d693.1781687723.git.u.kleine-koenig@baylibre.com --- drivers/clocksource/sh_cmt.c | 4 ++-- drivers/clocksource/sh_tmu.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index cf057f531a58..7977507f6ce3 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -974,8 +974,8 @@ static int sh_cmt_map_memory(struct sh_cmt_device *cmt) } static const struct platform_device_id sh_cmt_id_table[] = { - { "sh-cmt-16", (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] }, - { "sh-cmt-32", (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] }, + { .name = "sh-cmt-16", .driver_data = (kernel_ulong_t)&sh_cmt_info[SH_CMT_16BIT] }, + { .name = "sh-cmt-32", .driver_data = (kernel_ulong_t)&sh_cmt_info[SH_CMT_32BIT] }, { } }; MODULE_DEVICE_TABLE(platform, sh_cmt_id_table); diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 8d6a9e279f73..8b3cfa6727bd 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -614,8 +614,8 @@ static int sh_tmu_probe(struct platform_device *pdev) } static const struct platform_device_id sh_tmu_id_table[] = { - { "sh-tmu", SH_TMU }, - { "sh-tmu-sh3", SH_TMU_SH3 }, + { .name = "sh-tmu", .driver_data = SH_TMU }, + { .name = "sh-tmu-sh3", .driver_data = SH_TMU_SH3 }, { } }; MODULE_DEVICE_TABLE(platform, sh_tmu_id_table); -- cgit v1.2.3 From 6d6dd3863aa35f1873c7e8b82b1ee66244255a3a Mon Sep 17 00:00:00 2001 From: Pan Chuang Date: Mon, 13 Jul 2026 21:07:39 +0800 Subject: clocksource: Remove redundant dev_err()/dev_err_probe() Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in devm_request_*_irq()"), devm_request_irq() automatically logs detailed error messages on failure. Remove the now-redundant driver-specific dev_err() and dev_err_probe() calls. Signed-off-by: Pan Chuang Signed-off-by: Daniel Lezcano Link: https://patch.msgid.link/20260713130740.293502-1-panchuang@vivo.com --- drivers/clocksource/arm_arch_timer_mmio.c | 4 +--- drivers/clocksource/em_sti.c | 4 +--- drivers/clocksource/timer-nxp-stm.c | 2 +- drivers/clocksource/timer-sun5i.c | 4 +--- drivers/clocksource/timer-tegra186.c | 4 +--- drivers/clocksource/timer-ti-dm.c | 4 +--- 6 files changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/clocksource/arm_arch_timer_mmio.c b/drivers/clocksource/arm_arch_timer_mmio.c index d10362692fdd..d678f764d3bb 100644 --- a/drivers/clocksource/arm_arch_timer_mmio.c +++ b/drivers/clocksource/arm_arch_timer_mmio.c @@ -313,10 +313,8 @@ static int arch_timer_mmio_frame_register(struct platform_device *pdev, ret = devm_request_irq(&pdev->dev, irq, arch_timer_mmio_handler, IRQF_TIMER | IRQF_NO_AUTOEN, "arch_mem_timer", &at->evt); - if (ret) { - dev_err(&pdev->dev, "Failed to request mem timer irq\n"); + if (ret) return ret; - } /* Afer this point, we're not allowed to fail anymore */ arch_timer_mmio_setup(at, irq); diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c index ca8d29ab70da..73a3357d173d 100644 --- a/drivers/clocksource/em_sti.c +++ b/drivers/clocksource/em_sti.c @@ -300,10 +300,8 @@ static int em_sti_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, irq, em_sti_interrupt, IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, dev_name(&pdev->dev), p); - if (ret) { - dev_err(&pdev->dev, "failed to request low IRQ\n"); + if (ret) return ret; - } /* get hold of clock */ p->clk = devm_clk_get(&pdev->dev, "sclk"); diff --git a/drivers/clocksource/timer-nxp-stm.c b/drivers/clocksource/timer-nxp-stm.c index 1ab907233f48..6fe098a4a33f 100644 --- a/drivers/clocksource/timer-nxp-stm.c +++ b/drivers/clocksource/timer-nxp-stm.c @@ -441,7 +441,7 @@ static int nxp_stm_timer_probe(struct platform_device *pdev) ret = devm_request_irq(dev, irq, nxp_stm_module_interrupt, IRQF_TIMER | IRQF_NOBALANCING, name, stm_timer); if (ret) - return dev_err_probe(dev, ret, "Unable to allocate interrupt line\n"); + return ret; ret = nxp_stm_clocksource_init(dev, stm_timer, name, base, clk); if (ret) diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c index 6ab300d22621..bcf155fb9cac 100644 --- a/drivers/clocksource/timer-sun5i.c +++ b/drivers/clocksource/timer-sun5i.c @@ -247,10 +247,8 @@ static int sun5i_setup_clockevent(struct platform_device *pdev, ret = devm_request_irq(dev, irq, sun5i_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, "sun5i_timer0", ce); - if (ret) { - dev_err(dev, "Unable to register interrupt\n"); + if (ret) return ret; - } return 0; } diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c index 78600ddeb1c6..0f626ecf61b0 100644 --- a/drivers/clocksource/timer-tegra186.c +++ b/drivers/clocksource/timer-tegra186.c @@ -532,10 +532,8 @@ static int tegra186_timer_probe(struct platform_device *pdev) if (kernel_wdt) { err = devm_request_irq(dev, irq, tegra186_wdt_irq, 0, dev_name(dev), kernel_wdt); - if (err < 0) { - dev_err(dev, "failed to request kernel WDT IRQ: %d\n", err); + if (err < 0) goto unregister_usec; - } tegra186_wdt_set_timeout(&kernel_wdt->base, TEGRA186_KERNEL_WDT_TIMEOUT); tegra186_wdt_enable(kernel_wdt); diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c index bd06afb7d522..6787acac9a43 100644 --- a/drivers/clocksource/timer-ti-dm.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -1375,10 +1375,8 @@ static int omap_dm_timer_setup_clockevent(struct dmtimer *timer) ret = devm_request_irq(dev, timer->irq, omap_dm_timer_evt_interrupt, IRQF_TIMER, "omap_dm_timer_clockevent", clkevt); - if (ret) { - dev_err(dev, "Failed to request interrupt: %d\n", ret); + if (ret) return ret; - } __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW); -- cgit v1.2.3 From d21808328225ab8cee46885bf9a0dffcefbe630e Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Thu, 25 Jun 2026 06:04:34 +0800 Subject: clocksource/drivers/timer-sun4i: Advertise a real minimum delta sun4i_clkevt_next_event() compensates for the timer stop/start synchronization delay by programming evt - TIMER_SYNC_TICKS into the hardware interval register. The clockevent device currently advertises TIMER_SYNC_TICKS as min_delta_ticks, so the clockevents core is allowed to call set_next_event() with evt == TIMER_SYNC_TICKS. That programs a zero-tick interval. With oneshot/highres/nohz timer operation this can leave the next event stuck, which was observed as a boot hang on Allwinner D1 after the clockevents core started reusing forced minimum-delta events. Advertise one extra tick instead, so the smallest event accepted by the core still programs at least one hardware tick after the synchronization compensation. Fixes: 12e1480bcb49 ("clocksource: sun4i: Report the minimum tick that we can program") Reported-by: Indrek Kruusa Closes: https://lore.kernel.org/linux-riscv/CA+fTLhgLmTY+exGujKf8OYYQvcEW5X5NJ_5sLq2AYL6zER2c0A@mail.gmail.com/ Assisted-by: Codex:gpt-5.5 Signed-off-by: Felix Yan Signed-off-by: Daniel Lezcano Tested-by: Indrek Kruusa Acked-by: Jernej Skrabec Cc: stable@vger.kernel.org Link: https://lore.kernel.org/linux-riscv/CA+fTLhgLmTY+exGujKf8OYYQvcEW5X5NJ_5sLq2AYL6zER2c0A@mail.gmail.com/ Link: https://patch.msgid.link/20260624220434.4183732-1-felixonmars@archlinux.org --- drivers/clocksource/timer-sun4i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-sun4i.c b/drivers/clocksource/timer-sun4i.c index 7bdcc60ad43c..c2d04ab7cf2d 100644 --- a/drivers/clocksource/timer-sun4i.c +++ b/drivers/clocksource/timer-sun4i.c @@ -208,7 +208,7 @@ static int __init sun4i_timer_init(struct device_node *node) sun4i_timer_clear_interrupt(timer_of_base(&to)); clockevents_config_and_register(&to.clkevt, timer_of_rate(&to), - TIMER_SYNC_TICKS, 0xffffffff); + TIMER_SYNC_TICKS + 1, 0xffffffff); /* Enable timer0 interrupt */ val = readl(timer_of_base(&to) + TIMER_IRQ_EN_REG); -- cgit v1.2.3 From 05520e035f8332c8e33f3011b5ca016fde61793d Mon Sep 17 00:00:00 2001 From: WenTao Liang Date: Sun, 28 Jun 2026 21:07:00 +0800 Subject: clocksource/drivers/nxp-pit: Fix IRQ leak on cpuhp_setup_state error path When cpuhp_setup_state fails after pit_clockevent_per_cpu_init has successfully called request_irq, the error handling jumps directly to out_pit_clocksource_unregister without freeing the registered IRQ. This leaks the IRQ line and, since kfree(pit) follows, leaves a dangling pointer registered as the interrupt handler's dev_id, potentially leading to a use-after-free if the IRQ fires afterwards. Fix it by calling pit_clockevent_per_cpu_exit to properly release the IRQ before falling through to the existing cleanup chain. Suggested-by: Greg KH Fixes: bee33f22d7c3 ("clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support") Cc: stable@vger.kernel.org Signed-off-by: WenTao Liang Signed-off-by: Daniel Lezcano Link: https://patch.msgid.link/20260628130700.45680-1-vulab@iscas.ac.cn --- drivers/clocksource/timer-nxp-pit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-nxp-pit.c b/drivers/clocksource/timer-nxp-pit.c index bc5157e2ba57..2f70d1d5e21b 100644 --- a/drivers/clocksource/timer-nxp-pit.c +++ b/drivers/clocksource/timer-nxp-pit.c @@ -328,8 +328,10 @@ static int pit_timer_init(struct device_node *np) if (pit_instances == max_pit_instances) { ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "PIT timer:starting", pit_clockevent_starting_cpu, NULL); - if (ret < 0) + if (ret < 0) { + pit_clockevent_per_cpu_exit(pit, pit_instances); goto out_pit_clocksource_unregister; + } } return 0; -- cgit v1.2.3 From e998c6300ef4e062a704ee17b5a812c0b595cf42 Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Sun, 5 Jul 2026 01:54:51 +0800 Subject: clocksource/drivers/clps711x: Do not unmap clocksource MMIO clps711x_clksrc_init() stores the timer base address in the static tcd pointer and registers it as both the clocksource MMIO address and the sched_clock read address. The clocksource init path must therefore keep the mapping alive after clps711x_timer_init() returns. However, the shared unmap_io exit path is also reached after successful clocksource registration, so the MMIO mapping is torn down while the clocksource and sched_clock readers may still access it. Return directly after successful clocksource registration and leave the mapping alive for the registered readers. Keep the unmap_io path for the error paths and for the clockevent init path. Fixes: cd32e596f02f ("clocksource/drivers/clps711x: Fix resource leaks in error paths") Signed-off-by: Guangshuo Li Signed-off-by: Daniel Lezcano Link: https://patch.msgid.link/20260704175451.256364-1-lgs201920130244@gmail.com --- drivers/clocksource/clps711x-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c index bb0a44adaf28..63ae3a691b14 100644 --- a/drivers/clocksource/clps711x-timer.c +++ b/drivers/clocksource/clps711x-timer.c @@ -94,7 +94,7 @@ static int __init clps711x_timer_init(struct device_node *np) switch (of_alias_get_id(np, "timer")) { case CLPS711X_CLKSRC_CLOCKSOURCE: clps711x_clksrc_init(clock, base); - break; + return 0; case CLPS711X_CLKSRC_CLOCKEVENT: ret = _clps711x_clkevt_init(clock, base, irq); break; -- cgit v1.2.3 From 3b212f9d70805d91febae01d618868f4860e267c Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 13 Jul 2026 10:56:53 +0200 Subject: clocksource/drivers/samsung_pwm: Switch to raw_spinlock_t type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Samsung PWM timer might be used as a clock source on some legacy systems. When PREEMPT_RT is enabled on ARM, regular spinlock is converted to a sleeping lock (mutex-based), which must not be used in atomic context such as hard interrupt handlers. Switch the samsung_pwm_lock to the raw_spinlock, which remains a true non-sleeping spinlock even under PREEMPT_RT. Fixes: 7aac482e6290 ("clocksource: samsung_pwm_timer: Make PWM spinlock global") Fixes: f11899894c0a ("clocksource: add samsung pwm timer driver") Signed-off-by: Marek Szyprowski Signed-off-by: Daniel Lezcano Reviewed-by: Krzysztof Kozlowski Reviewed-by: Sebastian Andrzej Siewior Acked-by: Uwe Kleine-König Link: https://patch.msgid.link/20260713085653.1145015-1-m.szyprowski@samsung.com --- drivers/clocksource/samsung_pwm_timer.c | 22 +++++++++++----------- drivers/pwm/pwm-samsung.c | 22 +++++++++++----------- include/clocksource/samsung_pwm.h | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c index b9561e3f196c..0544124cf5ce 100644 --- a/drivers/clocksource/samsung_pwm_timer.c +++ b/drivers/clocksource/samsung_pwm_timer.c @@ -56,7 +56,7 @@ #define TCON_AUTORELOAD(chan) \ ((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan)) -DEFINE_SPINLOCK(samsung_pwm_lock); +DEFINE_RAW_SPINLOCK(samsung_pwm_lock); EXPORT_SYMBOL(samsung_pwm_lock); struct samsung_pwm_clocksource { @@ -87,14 +87,14 @@ static void samsung_timer_set_prescale(unsigned int channel, u16 prescale) if (channel >= 2) shift = TCFG0_PRESCALER1_SHIFT; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); reg = readl(pwm.base + REG_TCFG0); reg &= ~(TCFG0_PRESCALER_MASK << shift); reg |= (prescale - 1) << shift; writel(reg, pwm.base + REG_TCFG0); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static void samsung_timer_set_divisor(unsigned int channel, u8 divisor) @@ -106,14 +106,14 @@ static void samsung_timer_set_divisor(unsigned int channel, u8 divisor) bits = (fls(divisor) - 1) - pwm.variant.div_base; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); reg = readl(pwm.base + REG_TCFG1); reg &= ~(TCFG1_MUX_MASK << shift); reg |= bits << shift; writel(reg, pwm.base + REG_TCFG1); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static void samsung_time_stop(unsigned int channel) @@ -124,13 +124,13 @@ static void samsung_time_stop(unsigned int channel) if (channel > 0) ++channel; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); tcon = readl_relaxed(pwm.base + REG_TCON); tcon &= ~TCON_START(channel); writel_relaxed(tcon, pwm.base + REG_TCON); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static void samsung_time_setup(unsigned int channel, unsigned long tcnt) @@ -142,7 +142,7 @@ static void samsung_time_setup(unsigned int channel, unsigned long tcnt) if (tcon_chan > 0) ++tcon_chan; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); tcon = readl_relaxed(pwm.base + REG_TCON); @@ -153,7 +153,7 @@ static void samsung_time_setup(unsigned int channel, unsigned long tcnt) writel_relaxed(tcnt, pwm.base + REG_TCMPB(channel)); writel_relaxed(tcon, pwm.base + REG_TCON); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static void samsung_time_start(unsigned int channel, bool periodic) @@ -164,7 +164,7 @@ static void samsung_time_start(unsigned int channel, bool periodic) if (channel > 0) ++channel; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); tcon = readl_relaxed(pwm.base + REG_TCON); @@ -178,7 +178,7 @@ static void samsung_time_start(unsigned int channel, bool periodic) writel_relaxed(tcon, pwm.base + REG_TCON); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static int samsung_set_next_event(unsigned long cycles, diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index 951b38ff5f8e..14fb460a4565 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -102,7 +102,7 @@ struct samsung_pwm_chip { * IP. Should this change, both drivers will need to be modified to * properly synchronize accesses to particular instances. */ -static DEFINE_SPINLOCK(samsung_pwm_lock); +static DEFINE_RAW_SPINLOCK(samsung_pwm_lock); #endif static inline @@ -141,14 +141,14 @@ static void pwm_samsung_set_divisor(struct samsung_pwm_chip *our_chip, bits = (fls(divisor) - 1) - our_chip->variant.div_base; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); reg = readl(our_chip->base + REG_TCFG1); reg &= ~(TCFG1_MUX_MASK << shift); reg |= bits << shift; writel(reg, our_chip->base + REG_TCFG1); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static int pwm_samsung_is_tdiv(struct samsung_pwm_chip *our_chip, unsigned int chan) @@ -249,7 +249,7 @@ static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm) unsigned long flags; u32 tcon; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); tcon = readl(our_chip->base + REG_TCON); @@ -263,7 +263,7 @@ static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm) our_chip->disabled_mask &= ~BIT(pwm->hwpwm); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); return 0; } @@ -275,7 +275,7 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm) unsigned long flags; u32 tcon; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); tcon = readl(our_chip->base + REG_TCON); tcon &= ~TCON_AUTORELOAD(tcon_chan); @@ -290,7 +290,7 @@ static void pwm_samsung_disable(struct pwm_chip *chip, struct pwm_device *pwm) our_chip->disabled_mask |= BIT(pwm->hwpwm); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static void pwm_samsung_manual_update(struct samsung_pwm_chip *our_chip, @@ -298,11 +298,11 @@ static void pwm_samsung_manual_update(struct samsung_pwm_chip *our_chip, { unsigned long flags; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); __pwm_samsung_manual_update(our_chip, pwm); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static int __pwm_samsung_config(struct pwm_chip *chip, struct pwm_device *pwm, @@ -390,7 +390,7 @@ static void pwm_samsung_set_invert(struct samsung_pwm_chip *our_chip, unsigned long flags; u32 tcon; - spin_lock_irqsave(&samsung_pwm_lock, flags); + raw_spin_lock_irqsave(&samsung_pwm_lock, flags); tcon = readl(our_chip->base + REG_TCON); @@ -404,7 +404,7 @@ static void pwm_samsung_set_invert(struct samsung_pwm_chip *our_chip, writel(tcon, our_chip->base + REG_TCON); - spin_unlock_irqrestore(&samsung_pwm_lock, flags); + raw_spin_unlock_irqrestore(&samsung_pwm_lock, flags); } static int pwm_samsung_set_polarity(struct pwm_chip *chip, diff --git a/include/clocksource/samsung_pwm.h b/include/clocksource/samsung_pwm.h index 9b435caa95fe..36f6f246e559 100644 --- a/include/clocksource/samsung_pwm.h +++ b/include/clocksource/samsung_pwm.h @@ -15,7 +15,7 @@ * spinlock is not shared between both drivers. */ #ifdef CONFIG_CLKSRC_SAMSUNG_PWM -extern spinlock_t samsung_pwm_lock; +extern raw_spinlock_t samsung_pwm_lock; #endif struct samsung_pwm_variant { -- cgit v1.2.3 From 739007deca12d95db13762301b0745aa92938717 Mon Sep 17 00:00:00 2001 From: Rustam Adilov Date: Sat, 25 Jul 2026 22:55:10 +0500 Subject: clocksource/drivers/rtl-otto: Change driver to use __raw reads and writes As it stands, the driver uses ioread32 and iowrite32 for register access and it works fine. However this stops working when the SWAP_IO_SPACE config is enabled as this drivers expects ioread32 and iowrite32 to be in native endian (that is big endian for currently supported SoCs). RTL9607C is a big endian MIPS SoC that has identical timer as the already supported chips but needs to have SWAP_IO_SPACE to have a functioning little endian USB host. Fix this by replacing all instances of ioread32 and iowrite32 with __raw_readl and __raw_writel variants. Since they essentially do the same register access, this shouldn't affect anything on other machines. Signed-off-by: Rustam Adilov Signed-off-by: Daniel Lezcano Reviewed-by: Chris Packham Link: https://patch.msgid.link/20260725175510.77240-1-adilov@disroot.org --- drivers/clocksource/timer-rtl-otto.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/clocksource/timer-rtl-otto.c b/drivers/clocksource/timer-rtl-otto.c index dd236a7babee..0d1b9a01a94c 100644 --- a/drivers/clocksource/timer-rtl-otto.c +++ b/drivers/clocksource/timer-rtl-otto.c @@ -56,37 +56,37 @@ struct rttm_cs { /* Simple internal register functions */ static inline unsigned int rttm_get_counter(void __iomem *base) { - return ioread32(base + RTTM_CNT); + return __raw_readl(base + RTTM_CNT); } static inline void rttm_set_period(void __iomem *base, unsigned int period) { - iowrite32(period, base + RTTM_DATA); + __raw_writel(period, base + RTTM_DATA); } static inline void rttm_disable_timer(void __iomem *base) { - iowrite32(0, base + RTTM_CTRL); + __raw_writel(0, base + RTTM_CTRL); } static inline void rttm_enable_timer(void __iomem *base, u32 mode, u32 divisor) { - iowrite32(RTTM_CTRL_ENABLE | mode | divisor, base + RTTM_CTRL); + __raw_writel(RTTM_CTRL_ENABLE | mode | divisor, base + RTTM_CTRL); } static inline void rttm_ack_irq(void __iomem *base) { - iowrite32(ioread32(base + RTTM_INT) | RTTM_INT_PENDING, base + RTTM_INT); + __raw_writel(__raw_readl(base + RTTM_INT) | RTTM_INT_PENDING, base + RTTM_INT); } static inline void rttm_enable_irq(void __iomem *base) { - iowrite32(RTTM_INT_ENABLE, base + RTTM_INT); + __raw_writel(RTTM_INT_ENABLE, base + RTTM_INT); } static inline void rttm_disable_irq(void __iomem *base) { - iowrite32(0, base + RTTM_INT); + __raw_writel(0, base + RTTM_INT); } /* Aggregated control functions for kernel clock framework */ -- cgit v1.2.3 From 8b4127f6db40381229f3564d34ac35f36311c201 Mon Sep 17 00:00:00 2001 From: Yuho Choi Date: Sun, 2 Aug 2026 17:35:45 -0400 Subject: clocksource/drivers/armada: Unwind timer clock on init failure The Armada timer init paths enable their clock before calling the common initialization routine. If that routine returns an error, the clock is left enabled even though the timer was not initialized successfully. Fixes: 12549e27c63c ("clocksource/drivers/time-armada-370-xp: Convert init function to return error") Signed-off-by: Yuho Choi Signed-off-by: Daniel Lezcano Link: https://patch.msgid.link/20260802213545.565913-1-dbgh9129@gmail.com --- drivers/clocksource/timer-armada-370-xp.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/clocksource/timer-armada-370-xp.c b/drivers/clocksource/timer-armada-370-xp.c index a405a084cf72..b5a984aa1cbb 100644 --- a/drivers/clocksource/timer-armada-370-xp.c +++ b/drivers/clocksource/timer-armada-370-xp.c @@ -349,7 +349,11 @@ static int __init armada_xp_timer_init(struct device_node *np) timer_clk = clk_get_rate(clk); - return armada_370_xp_timer_common_init(np); + ret = armada_370_xp_timer_common_init(np); + if (ret) + clk_disable_unprepare(clk); + + return ret; } TIMER_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", armada_xp_timer_init); @@ -387,7 +391,11 @@ static int __init armada_375_timer_init(struct device_node *np) timer25Mhz = false; } - return armada_370_xp_timer_common_init(np); + ret = armada_370_xp_timer_common_init(np); + if (ret) + clk_disable_unprepare(clk); + + return ret; } TIMER_OF_DECLARE(armada_375, "marvell,armada-375-timer", armada_375_timer_init); @@ -410,7 +418,11 @@ static int __init armada_370_timer_init(struct device_node *np) timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; timer25Mhz = false; - return armada_370_xp_timer_common_init(np); + ret = armada_370_xp_timer_common_init(np); + if (ret) + clk_disable_unprepare(clk); + + return ret; } TIMER_OF_DECLARE(armada_370, "marvell,armada-370-timer", armada_370_timer_init); -- cgit v1.2.3