Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'timers-core-2024-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull more clocksource updates from Thomas Gleixner:
"A set of updates for clocksource and clockevent drivers:

- A fix for the prescaler of the ARM global timer where the prescaler
mask define only covered 4 bits while it is actully 8 bits wide.
This obviously restricted the possible range of prescaler
adjustments

- A fix for the RISC-V timer which prevents a timer interrupt being
raised while the timer is initialized

- A set of device tree updates to support new system on chips in
various drivers

- Kernel-doc and other cleanups all over the place"

* tag 'timers-core-2024-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
clocksource/drivers/timer-riscv: Clear timer interrupt on timer initialization
dt-bindings: timer: Add support for cadence TTC PWM
clocksource/drivers/arm_global_timer: Simplify prescaler register access
clocksource/drivers/arm_global_timer: Guard against division by zero
clocksource/drivers/arm_global_timer: Make gt_target_rate unsigned long
dt-bindings: timer: add Ralink SoCs system tick counter
clocksource: arm_global_timer: fix non-kernel-doc comment
clocksource/drivers/arm_global_timer: Remove stray tab
clocksource/drivers/arm_global_timer: Fix maximum prescaler value
clocksource/drivers/imx-sysctr: Add i.MX95 support
clocksource/drivers/imx-sysctr: Drop use global variables
dt-bindings: timer: nxp,sysctr-timer: support i.MX95
dt-bindings: timer: renesas: ostm: Document RZ/Five SoC
dt-bindings: timer: renesas,tmu: Document input capture interrupt
clocksource/drivers/ti-32K: Fix misuse of "/**" comment
clocksource/drivers/stm32: Fix all kernel-doc warnings
dt-bindings: timer: exynos4210-mct: Add google,gs101-mct compatible
clocksource/drivers/imx: Fix -Wunused-but-set-variable warning

+193 -61
+21 -1
Documentation/devicetree/bindings/timer/cdns,ttc.yaml
··· 32 32 description: | 33 33 Bit width of the timer, necessary if not 16. 34 34 35 + "#pwm-cells": 36 + const: 3 37 + 35 38 required: 36 39 - compatible 37 40 - reg 38 - - interrupts 39 41 - clocks 42 + 43 + allOf: 44 + - if: 45 + not: 46 + required: 47 + - "#pwm-cells" 48 + then: 49 + required: 50 + - interrupts 40 51 41 52 additionalProperties: false 42 53 ··· 60 49 reg = <0xF8001000 0x1000>; 61 50 clocks = <&cpu_clk 3>; 62 51 timer-width = <32>; 52 + }; 53 + 54 + - | 55 + pwm: pwm@f8002000 { 56 + compatible = "cdns,ttc"; 57 + reg = <0xf8002000 0x1000>; 58 + clocks = <&cpu_clk 3>; 59 + timer-width = <32>; 60 + #pwm-cells = <3>; 63 61 };
+3 -1
Documentation/devicetree/bindings/timer/nxp,sysctr-timer.yaml
··· 18 18 19 19 properties: 20 20 compatible: 21 - const: nxp,sysctr-timer 21 + enum: 22 + - nxp,imx95-sysctr-timer 23 + - nxp,sysctr-timer 22 24 23 25 reg: 24 26 maxItems: 1
+38
Documentation/devicetree/bindings/timer/ralink,cevt-systick.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/timer/ralink,cevt-systick.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: System tick counter present in Ralink family SoCs 8 + 9 + maintainers: 10 + - Sergio Paracuellos <sergio.paracuellos@gmail.com> 11 + 12 + properties: 13 + compatible: 14 + const: ralink,cevt-systick 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + interrupts: 20 + maxItems: 1 21 + 22 + required: 23 + - compatible 24 + - reg 25 + - interrupts 26 + 27 + additionalProperties: false 28 + 29 + examples: 30 + - | 31 + systick@d00 { 32 + compatible = "ralink,cevt-systick"; 33 + reg = <0xd00 0x10>; 34 + 35 + interrupt-parent = <&cpuintc>; 36 + interrupts = <7>; 37 + }; 38 + ...
+1 -1
Documentation/devicetree/bindings/timer/renesas,ostm.yaml
··· 23 23 - enum: 24 24 - renesas,r7s72100-ostm # RZ/A1H 25 25 - renesas,r7s9210-ostm # RZ/A2M 26 - - renesas,r9a07g043-ostm # RZ/G2UL 26 + - renesas,r9a07g043-ostm # RZ/G2UL and RZ/Five 27 27 - renesas,r9a07g044-ostm # RZ/G2{L,LC} 28 28 - renesas,r9a07g054-ostm # RZ/V2L 29 29 - const: renesas,ostm # Generic
+16 -2
Documentation/devicetree/bindings/timer/renesas,tmu.yaml
··· 46 46 47 47 interrupts: 48 48 minItems: 2 49 - maxItems: 3 49 + items: 50 + - description: Underflow interrupt, channel 0 51 + - description: Underflow interrupt, channel 1 52 + - description: Underflow interrupt, channel 2 53 + - description: Input capture interrupt, channel 2 54 + 55 + interrupt-names: 56 + minItems: 2 57 + items: 58 + - const: tuni0 59 + - const: tuni1 60 + - const: tuni2 61 + - const: ticpi2 50 62 51 63 clocks: 52 64 maxItems: 1 ··· 112 100 reg = <0xffd80000 0x30>; 113 101 interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>, 114 102 <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, 115 - <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; 103 + <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, 104 + <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; 105 + interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2"; 116 106 clocks = <&mstp0_clks R8A7779_CLK_TMU0>; 117 107 clock-names = "fck"; 118 108 power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
+2
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.yaml
··· 26 26 - items: 27 27 - enum: 28 28 - axis,artpec8-mct 29 + - google,gs101-mct 29 30 - samsung,exynos3250-mct 30 31 - samsung,exynos5250-mct 31 32 - samsung,exynos5260-mct ··· 128 127 contains: 129 128 enum: 130 129 - axis,artpec8-mct 130 + - google,gs101-mct 131 131 - samsung,exynos5260-mct 132 132 - samsung,exynos5420-mct 133 133 - samsung,exynos5433-mct
+16 -19
drivers/clocksource/arm_global_timer.c
··· 9 9 10 10 #include <linux/init.h> 11 11 #include <linux/interrupt.h> 12 + #include <linux/bitfield.h> 12 13 #include <linux/clocksource.h> 13 14 #include <linux/clockchips.h> 14 15 #include <linux/cpu.h> ··· 32 31 #define GT_CONTROL_COMP_ENABLE BIT(1) /* banked */ 33 32 #define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */ 34 33 #define GT_CONTROL_AUTO_INC BIT(3) /* banked */ 35 - #define GT_CONTROL_PRESCALER_SHIFT 8 36 - #define GT_CONTROL_PRESCALER_MAX 0xF 37 - #define GT_CONTROL_PRESCALER_MASK (GT_CONTROL_PRESCALER_MAX << \ 38 - GT_CONTROL_PRESCALER_SHIFT) 34 + #define GT_CONTROL_PRESCALER_MASK GENMASK(15, 8) 39 35 40 36 #define GT_INT_STATUS 0x0c 41 37 #define GT_INT_STATUS_EVENT_FLAG BIT(0) ··· 50 52 */ 51 53 static void __iomem *gt_base; 52 54 static struct notifier_block gt_clk_rate_change_nb; 53 - static u32 gt_psv_new, gt_psv_bck, gt_target_rate; 55 + static u32 gt_psv_new, gt_psv_bck; 56 + static unsigned long gt_target_rate; 54 57 static int gt_ppi; 55 58 static struct clock_event_device __percpu *gt_evt; 56 59 ··· 87 88 return _gt_counter_read(); 88 89 } 89 90 90 - /** 91 + /* 91 92 * To ensure that updates to comparator value register do not set the 92 93 * Interrupt Status Register proceed as follows: 93 94 * 1. Clear the Comp Enable bit in the Timer Control Register. ··· 246 247 247 248 reg = readl(gt_base + GT_CONTROL); 248 249 reg &= ~GT_CONTROL_PRESCALER_MASK; 249 - reg |= psv << GT_CONTROL_PRESCALER_SHIFT; 250 + reg |= FIELD_PREP(GT_CONTROL_PRESCALER_MASK, psv); 250 251 writel(reg, gt_base + GT_CONTROL); 251 252 } 252 253 ··· 255 256 u32 reg; 256 257 257 258 reg = readl(gt_base + GT_CONTROL); 258 - reg &= GT_CONTROL_PRESCALER_MASK; 259 - return reg >> GT_CONTROL_PRESCALER_SHIFT; 259 + return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg); 260 260 } 261 261 262 262 static void __init gt_delay_timer_init(void) ··· 270 272 writel(0, gt_base + GT_COUNTER0); 271 273 writel(0, gt_base + GT_COUNTER1); 272 274 /* set prescaler and enable timer on all the cores */ 273 - writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) << 274 - GT_CONTROL_PRESCALER_SHIFT) 275 - | GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); 275 + writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK, 276 + CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) | 277 + GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); 276 278 277 279 #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK 278 280 sched_clock_register(gt_sched_clock_read, 64, gt_target_rate); ··· 288 290 switch (event) { 289 291 case PRE_RATE_CHANGE: 290 292 { 291 - int psv; 293 + unsigned long psv; 292 294 293 - psv = DIV_ROUND_CLOSEST(ndata->new_rate, 294 - gt_target_rate); 295 - 296 - if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) 295 + psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate); 296 + if (!psv || 297 + abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) 297 298 return NOTIFY_BAD; 298 299 299 300 psv--; 300 301 301 302 /* prescaler within legal range? */ 302 - if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX) 303 + if (!FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv)) 303 304 return NOTIFY_BAD; 304 305 305 306 /* ··· 408 411 err = gt_clocksource_init(); 409 412 if (err) 410 413 goto out_irq; 411 - 414 + 412 415 err = cpuhp_setup_state(CPUHP_AP_ARM_GLOBAL_TIMER_STARTING, 413 416 "clockevents/arm/global_timer:starting", 414 417 gt_starting_cpu, gt_dying_cpu);
+1 -2
drivers/clocksource/timer-imx-gpt.c
··· 258 258 { 259 259 struct clock_event_device *ced = dev_id; 260 260 struct imx_timer *imxtm = to_imx_timer(ced); 261 - uint32_t tstat; 262 261 263 - tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); 262 + readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); 264 263 265 264 imxtm->gpt->gpt_irq_acknowledge(imxtm); 266 265
+89 -32
drivers/clocksource/timer-imx-sysctr.c
··· 4 4 5 5 #include <linux/interrupt.h> 6 6 #include <linux/clockchips.h> 7 + #include <linux/slab.h> 7 8 8 9 #include "timer-of.h" 9 10 10 11 #define CMP_OFFSET 0x10000 12 + #define RD_OFFSET 0x20000 11 13 12 14 #define CNTCV_LO 0x8 13 15 #define CNTCV_HI 0xc 14 16 #define CMPCV_LO (CMP_OFFSET + 0x20) 15 17 #define CMPCV_HI (CMP_OFFSET + 0x24) 16 18 #define CMPCR (CMP_OFFSET + 0x2c) 19 + #define CNTCV_LO_IMX95 (RD_OFFSET + 0x8) 20 + #define CNTCV_HI_IMX95 (RD_OFFSET + 0xc) 17 21 18 22 #define SYS_CTR_EN 0x1 19 23 #define SYS_CTR_IRQ_MASK 0x2 20 24 21 25 #define SYS_CTR_CLK_DIV 0x3 22 26 23 - static void __iomem *sys_ctr_base __ro_after_init; 24 - static u32 cmpcr __ro_after_init; 27 + struct sysctr_private { 28 + u32 cmpcr; 29 + u32 lo_off; 30 + u32 hi_off; 31 + }; 25 32 26 - static void sysctr_timer_enable(bool enable) 33 + static void sysctr_timer_enable(struct clock_event_device *evt, bool enable) 27 34 { 28 - writel(enable ? cmpcr | SYS_CTR_EN : cmpcr, sys_ctr_base + CMPCR); 35 + struct timer_of *to = to_timer_of(evt); 36 + struct sysctr_private *priv = to->private_data; 37 + void __iomem *base = timer_of_base(to); 38 + 39 + writel(enable ? priv->cmpcr | SYS_CTR_EN : priv->cmpcr, base + CMPCR); 29 40 } 30 41 31 - static void sysctr_irq_acknowledge(void) 42 + static void sysctr_irq_acknowledge(struct clock_event_device *evt) 32 43 { 33 44 /* 34 45 * clear the enable bit(EN =0) will clear 35 46 * the status bit(ISTAT = 0), then the interrupt 36 47 * signal will be negated(acknowledged). 37 48 */ 38 - sysctr_timer_enable(false); 49 + sysctr_timer_enable(evt, false); 39 50 } 40 51 41 - static inline u64 sysctr_read_counter(void) 52 + static inline u64 sysctr_read_counter(struct clock_event_device *evt) 42 53 { 54 + struct timer_of *to = to_timer_of(evt); 55 + struct sysctr_private *priv = to->private_data; 56 + void __iomem *base = timer_of_base(to); 43 57 u32 cnt_hi, tmp_hi, cnt_lo; 44 58 45 59 do { 46 - cnt_hi = readl_relaxed(sys_ctr_base + CNTCV_HI); 47 - cnt_lo = readl_relaxed(sys_ctr_base + CNTCV_LO); 48 - tmp_hi = readl_relaxed(sys_ctr_base + CNTCV_HI); 60 + cnt_hi = readl_relaxed(base + priv->hi_off); 61 + cnt_lo = readl_relaxed(base + priv->lo_off); 62 + tmp_hi = readl_relaxed(base + priv->hi_off); 49 63 } while (tmp_hi != cnt_hi); 50 64 51 65 return ((u64) cnt_hi << 32) | cnt_lo; ··· 68 54 static int sysctr_set_next_event(unsigned long delta, 69 55 struct clock_event_device *evt) 70 56 { 57 + struct timer_of *to = to_timer_of(evt); 58 + void __iomem *base = timer_of_base(to); 71 59 u32 cmp_hi, cmp_lo; 72 60 u64 next; 73 61 74 - sysctr_timer_enable(false); 62 + sysctr_timer_enable(evt, false); 75 63 76 - next = sysctr_read_counter(); 64 + next = sysctr_read_counter(evt); 77 65 78 66 next += delta; 79 67 80 68 cmp_hi = (next >> 32) & 0x00fffff; 81 69 cmp_lo = next & 0xffffffff; 82 70 83 - writel_relaxed(cmp_hi, sys_ctr_base + CMPCV_HI); 84 - writel_relaxed(cmp_lo, sys_ctr_base + CMPCV_LO); 71 + writel_relaxed(cmp_hi, base + CMPCV_HI); 72 + writel_relaxed(cmp_lo, base + CMPCV_LO); 85 73 86 - sysctr_timer_enable(true); 74 + sysctr_timer_enable(evt, true); 87 75 88 76 return 0; 89 77 } ··· 97 81 98 82 static int sysctr_set_state_shutdown(struct clock_event_device *evt) 99 83 { 100 - sysctr_timer_enable(false); 84 + sysctr_timer_enable(evt, false); 101 85 102 86 return 0; 103 87 } ··· 106 90 { 107 91 struct clock_event_device *evt = dev_id; 108 92 109 - sysctr_irq_acknowledge(); 93 + sysctr_irq_acknowledge(evt); 110 94 111 95 evt->event_handler(evt); 112 96 ··· 133 117 }, 134 118 }; 135 119 136 - static void __init sysctr_clockevent_init(void) 120 + static int __init __sysctr_timer_init(struct device_node *np) 137 121 { 138 - to_sysctr.clkevt.cpumask = cpu_possible_mask; 122 + struct sysctr_private *priv; 123 + void __iomem *base; 124 + int ret; 139 125 140 - clockevents_config_and_register(&to_sysctr.clkevt, 141 - timer_of_rate(&to_sysctr), 142 - 0xff, 0x7fffffff); 143 - } 144 - 145 - static int __init sysctr_timer_init(struct device_node *np) 146 - { 147 - int ret = 0; 126 + priv = kzalloc(sizeof(struct sysctr_private), GFP_KERNEL); 127 + if (!priv) 128 + return -ENOMEM; 148 129 149 130 ret = timer_of_init(np, &to_sysctr); 150 - if (ret) 131 + if (ret) { 132 + kfree(priv); 151 133 return ret; 134 + } 152 135 153 136 if (!of_property_read_bool(np, "nxp,no-divider")) { 154 137 /* system counter clock is divided by 3 internally */ 155 138 to_sysctr.of_clk.rate /= SYS_CTR_CLK_DIV; 156 139 } 157 140 158 - sys_ctr_base = timer_of_base(&to_sysctr); 159 - cmpcr = readl(sys_ctr_base + CMPCR); 160 - cmpcr &= ~SYS_CTR_EN; 141 + to_sysctr.clkevt.cpumask = cpu_possible_mask; 142 + to_sysctr.private_data = priv; 161 143 162 - sysctr_clockevent_init(); 144 + base = timer_of_base(&to_sysctr); 145 + priv->cmpcr = readl(base + CMPCR) & ~SYS_CTR_EN; 163 146 164 147 return 0; 165 148 } 149 + 150 + static int __init sysctr_timer_init(struct device_node *np) 151 + { 152 + struct sysctr_private *priv; 153 + int ret; 154 + 155 + ret = __sysctr_timer_init(np); 156 + if (ret) 157 + return ret; 158 + 159 + priv = to_sysctr.private_data; 160 + priv->lo_off = CNTCV_LO; 161 + priv->hi_off = CNTCV_HI; 162 + 163 + clockevents_config_and_register(&to_sysctr.clkevt, 164 + timer_of_rate(&to_sysctr), 165 + 0xff, 0x7fffffff); 166 + 167 + return 0; 168 + } 169 + 170 + static int __init sysctr_timer_imx95_init(struct device_node *np) 171 + { 172 + struct sysctr_private *priv; 173 + int ret; 174 + 175 + ret = __sysctr_timer_init(np); 176 + if (ret) 177 + return ret; 178 + 179 + priv = to_sysctr.private_data; 180 + priv->lo_off = CNTCV_LO_IMX95; 181 + priv->hi_off = CNTCV_HI_IMX95; 182 + 183 + clockevents_config_and_register(&to_sysctr.clkevt, 184 + timer_of_rate(&to_sysctr), 185 + 0xff, 0x7fffffff); 186 + 187 + return 0; 188 + } 189 + 166 190 TIMER_OF_DECLARE(sysctr_timer, "nxp,sysctr-timer", sysctr_timer_init); 191 + TIMER_OF_DECLARE(sysctr_timer_imx95, "nxp,imx95-sysctr-timer", sysctr_timer_imx95_init);
+3
drivers/clocksource/timer-riscv.c
··· 108 108 { 109 109 struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu); 110 110 111 + /* Clear timer interrupt */ 112 + riscv_clock_event_stop(); 113 + 111 114 ce->cpumask = cpumask_of(cpu); 112 115 ce->irq = riscv_clock_event_irq; 113 116 if (riscv_timer_cannot_wake_cpu)
+2 -2
drivers/clocksource/timer-stm32.c
··· 73 73 * Accessor helper to get the number of bits in the timer-of private 74 74 * structure. 75 75 * 76 - * Returns an integer corresponding to the number of bits. 76 + * Returns: an integer corresponding to the number of bits. 77 77 */ 78 78 static int stm32_timer_of_bits_get(struct timer_of *to) 79 79 { ··· 177 177 } 178 178 179 179 /** 180 - * stm32_timer_width - Sort out the timer width (32/16) 180 + * stm32_timer_set_width - Sort out the timer width (32/16) 181 181 * @to: a pointer to a timer-of structure 182 182 * 183 183 * Write the 32-bit max value and read/return the result. If the timer
+1 -1
drivers/clocksource/timer-ti-32k.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /** 2 + /* 3 3 * timer-ti-32k.c - OMAP2 32k Timer Support 4 4 * 5 5 * Copyright (C) 2009 Nokia Corporation