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

Merge tag 'timers-core-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer updates from Thomas Gleixner:
"Updates for the time(r) subsystem:

Core:

- Make the clocksource watchdog more robust by better validation
checks of the measurement.

Drivers:

- New drivers for MStar and SSD20xd SOCs

- The usual cleanups and improvements all over the place"

* tag 'timers-core-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
dt-bindings: timer: Add Mstar MSC313e timer devicetree bindings documentation
clocksource/drivers/msc313e: Add support for ssd20xd-based platforms
clocksource/drivers: Add MStar MSC313e timer support
clocksource/drivers/pistachio: Fix -Wunused-but-set-variable warning
clocksource/drivers/timer-imx-sysctr: Set cpumask to cpu_possible_mask
clocksource/drivers/imx-sysctr: Mark two variable with __ro_after_init
clocksource/drivers/renesas,ostm: Make RENESAS_OSTM symbol visible
clocksource/drivers/renesas-ostm: Add RZ/G2L OSTM support
dt-bindings: timer: renesas: ostm: Document Renesas RZ/G2L OSTM
clocksource/drivers/exynos_mct: Fix silly typo resulting in checkpatch warning
clocksource: Reduce the default clocksource_watchdog() retries to 2
clocksource: Avoid accidental unstable marking of clocksources
dt-bindings: timer: tpm-timer: Add imx8ulp compatible string
reset: Add of_reset_control_get_optional_exclusive()
clocksource/drivers/exynos_mct: Refactor resources allocation
dt-bindings: timer: remove rockchip,rk3066-timer compatible string from rockchip,rk-timer.yaml
dt-bindings: timer: cadence_ttc: Add power-domains

+475 -44
+2 -2
Documentation/admin-guide/kernel-parameters.txt
··· 612 612 clocksource.max_cswd_read_retries= [KNL] 613 613 Number of clocksource_watchdog() retries due to 614 614 external delays before the clock will be marked 615 - unstable. Defaults to three retries, that is, 616 - four attempts to read the clock under test. 615 + unstable. Defaults to two retries, that is, 616 + three attempts to read the clock under test. 617 617 618 618 clocksource.verify_n_cpus= [KNL] 619 619 Limit the number of CPUs checked for clocksources
+3
Documentation/devicetree/bindings/timer/cdns,ttc.yaml
··· 25 25 clocks: 26 26 maxItems: 1 27 27 28 + power-domains: 29 + maxItems: 1 30 + 28 31 timer-width: 29 32 $ref: "/schemas/types.yaml#/definitions/uint32" 30 33 description: |
+46
Documentation/devicetree/bindings/timer/mstar,msc313e-timer.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/mstar,msc313e-timer.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Mstar MSC313e Timer Device Tree Bindings 8 + 9 + maintainers: 10 + - Daniel Palmer <daniel@0x0f.com> 11 + - Romain Perier <romain.perier@gmail.com> 12 + 13 + properties: 14 + compatible: 15 + enum: 16 + - mstar,msc313e-timer 17 + - sstar,ssd20xd-timer 18 + 19 + reg: 20 + maxItems: 1 21 + 22 + interrupts: 23 + maxItems: 1 24 + 25 + clocks: 26 + maxItems: 1 27 + 28 + required: 29 + - compatible 30 + - reg 31 + - interrupts 32 + - clocks 33 + 34 + additionalProperties: false 35 + 36 + examples: 37 + - | 38 + #include <dt-bindings/interrupt-controller/arm-gic.h> 39 + 40 + timer@6040 { 41 + compatible = "mstar,msc313e-timer"; 42 + reg = <0x6040 0x40>; 43 + clocks = <&xtal_div2>; 44 + interrupts-extended = <&intc_fiq GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; 45 + }; 46 + ...
+5 -1
Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml
··· 19 19 20 20 properties: 21 21 compatible: 22 - const: fsl,imx7ulp-tpm 22 + oneOf: 23 + - const: fsl,imx7ulp-tpm 24 + - items: 25 + - const: fsl,imx8ulp-tpm 26 + - const: fsl,imx7ulp-tpm 23 27 24 28 reg: 25 29 maxItems: 1
+17 -3
Documentation/devicetree/bindings/timer/renesas,ostm.yaml
··· 21 21 compatible: 22 22 items: 23 23 - enum: 24 - - renesas,r7s72100-ostm # RZ/A1H 25 - - renesas,r7s9210-ostm # RZ/A2M 26 - - const: renesas,ostm # Generic 24 + - renesas,r7s72100-ostm # RZ/A1H 25 + - renesas,r7s9210-ostm # RZ/A2M 26 + - renesas,r9a07g044-ostm # RZ/G2{L,LC} 27 + - const: renesas,ostm # Generic 27 28 28 29 reg: 29 30 maxItems: 1 ··· 38 37 power-domains: 39 38 maxItems: 1 40 39 40 + resets: 41 + maxItems: 1 42 + 41 43 required: 42 44 - compatible 43 45 - reg 44 46 - interrupts 45 47 - clocks 46 48 - power-domains 49 + 50 + if: 51 + properties: 52 + compatible: 53 + contains: 54 + enum: 55 + - renesas,r9a07g044-ostm 56 + then: 57 + required: 58 + - resets 47 59 48 60 additionalProperties: false 49 61
-1
Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml
··· 18 18 - enum: 19 19 - rockchip,rv1108-timer 20 20 - rockchip,rk3036-timer 21 - - rockchip,rk3066-timer 22 21 - rockchip,rk3188-timer 23 22 - rockchip,rk3228-timer 24 23 - rockchip,rk3229-timer
+1
MAINTAINERS
··· 2304 2304 F: arch/arm/boot/dts/mstar-* 2305 2305 F: arch/arm/mach-mstar/ 2306 2306 F: drivers/clk/mstar/ 2307 + F: drivers/clocksource/timer-msc313e.c 2307 2308 F: drivers/gpio/gpio-msc313.c 2308 2309 F: drivers/rtc/rtc-msc313.c 2309 2310 F: drivers/watchdog/msc313e_wdt.c
+11 -1
drivers/clocksource/Kconfig
··· 510 510 This hardware comes with 16-bit timer registers. 511 511 512 512 config RENESAS_OSTM 513 - bool "Renesas OSTM timer driver" if COMPILE_TEST 513 + bool "Renesas OSTM timer driver" 514 + depends on ARCH_RENESAS || COMPILE_TEST 514 515 select CLKSRC_MMIO 515 516 select TIMER_OF 516 517 help ··· 671 670 select CLKSRC_MMIO 672 671 help 673 672 Enables the support for Milbeaut timer driver. 673 + 674 + config MSC313E_TIMER 675 + bool "MSC313E timer driver" if COMPILE_TEST 676 + select TIMER_OF 677 + select CLKSRC_MMIO 678 + help 679 + Enables support for the MStar MSC313E timer driver. 680 + This provides access to multiple interrupt generating 681 + programmable 32-bit free running incrementing counters. 674 682 675 683 config INGENIC_TIMER 676 684 bool "Clocksource/timer using the TCU in Ingenic JZ SoCs"
+1
drivers/clocksource/Makefile
··· 88 88 obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o 89 89 obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o 90 90 obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o 91 + obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o
+31 -21
drivers/clocksource/exynos_mct.c
··· 467 467 evt->tick_resume = set_state_shutdown; 468 468 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 469 469 CLOCK_EVT_FEAT_PERCPU; 470 - evt->rating = MCT_CLKEVENTS_RATING, 470 + evt->rating = MCT_CLKEVENTS_RATING; 471 471 472 472 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); 473 473 ··· 504 504 return 0; 505 505 } 506 506 507 - static int __init exynos4_timer_resources(struct device_node *np, void __iomem *base) 507 + static int __init exynos4_timer_resources(struct device_node *np) 508 508 { 509 - int err, cpu; 510 509 struct clk *mct_clk, *tick_clk; 510 + 511 + reg_base = of_iomap(np, 0); 512 + if (!reg_base) 513 + panic("%s: unable to ioremap mct address space\n", __func__); 511 514 512 515 tick_clk = of_clk_get_by_name(np, "fin_pll"); 513 516 if (IS_ERR(tick_clk)) ··· 522 519 panic("%s: unable to retrieve mct clock instance\n", __func__); 523 520 clk_prepare_enable(mct_clk); 524 521 525 - reg_base = base; 526 - if (!reg_base) 527 - panic("%s: unable to ioremap mct address space\n", __func__); 522 + return 0; 523 + } 524 + 525 + static int __init exynos4_timer_interrupts(struct device_node *np, 526 + unsigned int int_type) 527 + { 528 + int nr_irqs, i, err, cpu; 529 + 530 + mct_int_type = int_type; 531 + 532 + /* This driver uses only one global timer interrupt */ 533 + mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); 534 + 535 + /* 536 + * Find out the number of local irqs specified. The local 537 + * timer irqs are specified after the four global timer 538 + * irqs are specified. 539 + */ 540 + nr_irqs = of_irq_count(np); 541 + for (i = MCT_L0_IRQ; i < nr_irqs; i++) 542 + mct_irqs[i] = irq_of_parse_and_map(np, i); 528 543 529 544 if (mct_int_type == MCT_INT_PPI) { 530 545 ··· 602 581 603 582 static int __init mct_init_dt(struct device_node *np, unsigned int int_type) 604 583 { 605 - u32 nr_irqs, i; 606 584 int ret; 607 585 608 - mct_int_type = int_type; 586 + ret = exynos4_timer_resources(np); 587 + if (ret) 588 + return ret; 609 589 610 - /* This driver uses only one global timer interrupt */ 611 - mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ); 612 - 613 - /* 614 - * Find out the number of local irqs specified. The local 615 - * timer irqs are specified after the four global timer 616 - * irqs are specified. 617 - */ 618 - nr_irqs = of_irq_count(np); 619 - for (i = MCT_L0_IRQ; i < nr_irqs; i++) 620 - mct_irqs[i] = irq_of_parse_and_map(np, i); 621 - 622 - ret = exynos4_timer_resources(np, of_iomap(np, 0)); 590 + ret = exynos4_timer_interrupts(np, int_type); 623 591 if (ret) 624 592 return ret; 625 593
+38 -1
drivers/clocksource/renesas-ostm.c
··· 9 9 #include <linux/clk.h> 10 10 #include <linux/clockchips.h> 11 11 #include <linux/interrupt.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/reset.h> 12 14 #include <linux/sched_clock.h> 13 15 #include <linux/slab.h> 14 16 ··· 161 159 162 160 static int __init ostm_init(struct device_node *np) 163 161 { 162 + struct reset_control *rstc; 164 163 struct timer_of *to; 165 164 int ret; 166 165 167 166 to = kzalloc(sizeof(*to), GFP_KERNEL); 168 167 if (!to) 169 168 return -ENOMEM; 169 + 170 + rstc = of_reset_control_get_optional_exclusive(np, NULL); 171 + if (IS_ERR(rstc)) { 172 + ret = PTR_ERR(rstc); 173 + goto err_free; 174 + } 175 + 176 + reset_control_deassert(rstc); 170 177 171 178 to->flags = TIMER_OF_BASE | TIMER_OF_CLOCK; 172 179 if (system_clock) { ··· 189 178 190 179 ret = timer_of_init(np, to); 191 180 if (ret) 192 - goto err_free; 181 + goto err_reset; 193 182 194 183 /* 195 184 * First probed device will be used as system clocksource. Any ··· 214 203 215 204 err_cleanup: 216 205 timer_of_cleanup(to); 206 + err_reset: 207 + reset_control_assert(rstc); 208 + reset_control_put(rstc); 217 209 err_free: 218 210 kfree(to); 219 211 return ret; 220 212 } 221 213 222 214 TIMER_OF_DECLARE(ostm, "renesas,ostm", ostm_init); 215 + 216 + #ifdef CONFIG_ARCH_R9A07G044 217 + static int __init ostm_probe(struct platform_device *pdev) 218 + { 219 + struct device *dev = &pdev->dev; 220 + 221 + return ostm_init(dev->of_node); 222 + } 223 + 224 + static const struct of_device_id ostm_of_table[] = { 225 + { .compatible = "renesas,ostm", }, 226 + { /* sentinel */ } 227 + }; 228 + 229 + static struct platform_driver ostm_device_driver = { 230 + .driver = { 231 + .name = "renesas_ostm", 232 + .of_match_table = of_match_ptr(ostm_of_table), 233 + .suppress_bind_attrs = true, 234 + }, 235 + }; 236 + builtin_platform_driver_probe(ostm_device_driver, ostm_probe); 237 + #endif
+3 -3
drivers/clocksource/timer-imx-sysctr.c
··· 20 20 21 21 #define SYS_CTR_CLK_DIV 0x3 22 22 23 - static void __iomem *sys_ctr_base; 24 - static u32 cmpcr; 23 + static void __iomem *sys_ctr_base __ro_after_init; 24 + static u32 cmpcr __ro_after_init; 25 25 26 26 static void sysctr_timer_enable(bool enable) 27 27 { ··· 119 119 120 120 static void __init sysctr_clockevent_init(void) 121 121 { 122 - to_sysctr.clkevt.cpumask = cpumask_of(0); 122 + to_sysctr.clkevt.cpumask = cpu_possible_mask; 123 123 124 124 clockevents_config_and_register(&to_sysctr.clkevt, 125 125 timer_of_rate(&to_sysctr),
+253
drivers/clocksource/timer-msc313e.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * MStar timer driver 4 + * 5 + * Copyright (C) 2021 Daniel Palmer 6 + * Copyright (C) 2021 Romain Perier 7 + * 8 + */ 9 + 10 + #include <linux/clk.h> 11 + #include <linux/clockchips.h> 12 + #include <linux/interrupt.h> 13 + #include <linux/irq.h> 14 + #include <linux/irqreturn.h> 15 + #include <linux/sched_clock.h> 16 + #include <linux/of.h> 17 + #include <linux/of_address.h> 18 + #include <linux/of_irq.h> 19 + 20 + #ifdef CONFIG_ARM 21 + #include <linux/delay.h> 22 + #endif 23 + 24 + #include "timer-of.h" 25 + 26 + #define TIMER_NAME "msc313e_timer" 27 + 28 + #define MSC313E_REG_CTRL 0x00 29 + #define MSC313E_REG_CTRL_TIMER_EN BIT(0) 30 + #define MSC313E_REG_CTRL_TIMER_TRIG BIT(1) 31 + #define MSC313E_REG_CTRL_TIMER_INT_EN BIT(8) 32 + #define MSC313E_REG_TIMER_MAX_LOW 0x08 33 + #define MSC313E_REG_TIMER_MAX_HIGH 0x0c 34 + #define MSC313E_REG_COUNTER_LOW 0x10 35 + #define MSC313E_REG_COUNTER_HIGH 0x14 36 + #define MSC313E_REG_TIMER_DIVIDE 0x18 37 + 38 + #define MSC313E_CLK_DIVIDER 9 39 + #define TIMER_SYNC_TICKS 3 40 + 41 + #ifdef CONFIG_ARM 42 + struct msc313e_delay { 43 + void __iomem *base; 44 + struct delay_timer delay; 45 + }; 46 + static struct msc313e_delay msc313e_delay; 47 + #endif 48 + 49 + static void __iomem *msc313e_clksrc; 50 + 51 + static void msc313e_timer_stop(void __iomem *base) 52 + { 53 + writew(0, base + MSC313E_REG_CTRL); 54 + } 55 + 56 + static void msc313e_timer_start(void __iomem *base, bool periodic) 57 + { 58 + u16 reg; 59 + 60 + reg = readw(base + MSC313E_REG_CTRL); 61 + if (periodic) 62 + reg |= MSC313E_REG_CTRL_TIMER_EN; 63 + else 64 + reg |= MSC313E_REG_CTRL_TIMER_TRIG; 65 + writew(reg | MSC313E_REG_CTRL_TIMER_INT_EN, base + MSC313E_REG_CTRL); 66 + } 67 + 68 + static void msc313e_timer_setup(void __iomem *base, unsigned long delay) 69 + { 70 + unsigned long flags; 71 + 72 + local_irq_save(flags); 73 + writew(delay >> 16, base + MSC313E_REG_TIMER_MAX_HIGH); 74 + writew(delay & 0xffff, base + MSC313E_REG_TIMER_MAX_LOW); 75 + local_irq_restore(flags); 76 + } 77 + 78 + static unsigned long msc313e_timer_current_value(void __iomem *base) 79 + { 80 + unsigned long flags; 81 + u16 l, h; 82 + 83 + local_irq_save(flags); 84 + l = readw(base + MSC313E_REG_COUNTER_LOW); 85 + h = readw(base + MSC313E_REG_COUNTER_HIGH); 86 + local_irq_restore(flags); 87 + 88 + return (((u32)h) << 16 | l); 89 + } 90 + 91 + static int msc313e_timer_clkevt_shutdown(struct clock_event_device *evt) 92 + { 93 + struct timer_of *timer = to_timer_of(evt); 94 + 95 + msc313e_timer_stop(timer_of_base(timer)); 96 + 97 + return 0; 98 + } 99 + 100 + static int msc313e_timer_clkevt_set_oneshot(struct clock_event_device *evt) 101 + { 102 + struct timer_of *timer = to_timer_of(evt); 103 + 104 + msc313e_timer_stop(timer_of_base(timer)); 105 + msc313e_timer_start(timer_of_base(timer), false); 106 + 107 + return 0; 108 + } 109 + 110 + static int msc313e_timer_clkevt_set_periodic(struct clock_event_device *evt) 111 + { 112 + struct timer_of *timer = to_timer_of(evt); 113 + 114 + msc313e_timer_stop(timer_of_base(timer)); 115 + msc313e_timer_setup(timer_of_base(timer), timer_of_period(timer)); 116 + msc313e_timer_start(timer_of_base(timer), true); 117 + 118 + return 0; 119 + } 120 + 121 + static int msc313e_timer_clkevt_next_event(unsigned long evt, struct clock_event_device *clkevt) 122 + { 123 + struct timer_of *timer = to_timer_of(clkevt); 124 + 125 + msc313e_timer_stop(timer_of_base(timer)); 126 + msc313e_timer_setup(timer_of_base(timer), evt); 127 + msc313e_timer_start(timer_of_base(timer), false); 128 + 129 + return 0; 130 + } 131 + 132 + static irqreturn_t msc313e_timer_clkevt_irq(int irq, void *dev_id) 133 + { 134 + struct clock_event_device *evt = dev_id; 135 + 136 + evt->event_handler(evt); 137 + 138 + return IRQ_HANDLED; 139 + } 140 + 141 + static u64 msc313e_timer_clksrc_read(struct clocksource *cs) 142 + { 143 + return msc313e_timer_current_value(msc313e_clksrc) & cs->mask; 144 + } 145 + 146 + #ifdef CONFIG_ARM 147 + static unsigned long msc313e_read_delay_timer_read(void) 148 + { 149 + return msc313e_timer_current_value(msc313e_delay.base); 150 + } 151 + #endif 152 + 153 + static u64 msc313e_timer_sched_clock_read(void) 154 + { 155 + return msc313e_timer_current_value(msc313e_clksrc); 156 + } 157 + 158 + static struct clock_event_device msc313e_clkevt = { 159 + .name = TIMER_NAME, 160 + .rating = 300, 161 + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 162 + .set_state_shutdown = msc313e_timer_clkevt_shutdown, 163 + .set_state_periodic = msc313e_timer_clkevt_set_periodic, 164 + .set_state_oneshot = msc313e_timer_clkevt_set_oneshot, 165 + .tick_resume = msc313e_timer_clkevt_shutdown, 166 + .set_next_event = msc313e_timer_clkevt_next_event, 167 + }; 168 + 169 + static int __init msc313e_clkevt_init(struct device_node *np) 170 + { 171 + int ret; 172 + struct timer_of *to; 173 + 174 + to = kzalloc(sizeof(*to), GFP_KERNEL); 175 + if (!to) 176 + return -ENOMEM; 177 + 178 + to->flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE; 179 + to->of_irq.handler = msc313e_timer_clkevt_irq; 180 + ret = timer_of_init(np, to); 181 + if (ret) 182 + return ret; 183 + 184 + if (of_device_is_compatible(np, "sstar,ssd20xd-timer")) { 185 + to->of_clk.rate = clk_get_rate(to->of_clk.clk) / MSC313E_CLK_DIVIDER; 186 + to->of_clk.period = DIV_ROUND_UP(to->of_clk.rate, HZ); 187 + writew(MSC313E_CLK_DIVIDER - 1, timer_of_base(to) + MSC313E_REG_TIMER_DIVIDE); 188 + } 189 + 190 + msc313e_clkevt.cpumask = cpu_possible_mask; 191 + msc313e_clkevt.irq = to->of_irq.irq; 192 + to->clkevt = msc313e_clkevt; 193 + 194 + clockevents_config_and_register(&to->clkevt, timer_of_rate(to), 195 + TIMER_SYNC_TICKS, 0xffffffff); 196 + return 0; 197 + } 198 + 199 + static int __init msc313e_clksrc_init(struct device_node *np) 200 + { 201 + struct timer_of to = { 0 }; 202 + int ret; 203 + u16 reg; 204 + 205 + to.flags = TIMER_OF_BASE | TIMER_OF_CLOCK; 206 + ret = timer_of_init(np, &to); 207 + if (ret) 208 + return ret; 209 + 210 + msc313e_clksrc = timer_of_base(&to); 211 + reg = readw(msc313e_clksrc + MSC313E_REG_CTRL); 212 + reg |= MSC313E_REG_CTRL_TIMER_EN; 213 + writew(reg, msc313e_clksrc + MSC313E_REG_CTRL); 214 + 215 + #ifdef CONFIG_ARM 216 + msc313e_delay.base = timer_of_base(&to); 217 + msc313e_delay.delay.read_current_timer = msc313e_read_delay_timer_read; 218 + msc313e_delay.delay.freq = timer_of_rate(&to); 219 + 220 + register_current_timer_delay(&msc313e_delay.delay); 221 + #endif 222 + 223 + sched_clock_register(msc313e_timer_sched_clock_read, 32, timer_of_rate(&to)); 224 + return clocksource_mmio_init(timer_of_base(&to), TIMER_NAME, timer_of_rate(&to), 300, 32, 225 + msc313e_timer_clksrc_read); 226 + } 227 + 228 + static int __init msc313e_timer_init(struct device_node *np) 229 + { 230 + int ret = 0; 231 + static int num_called; 232 + 233 + switch (num_called) { 234 + case 0: 235 + ret = msc313e_clksrc_init(np); 236 + if (ret) 237 + return ret; 238 + break; 239 + 240 + default: 241 + ret = msc313e_clkevt_init(np); 242 + if (ret) 243 + return ret; 244 + break; 245 + } 246 + 247 + num_called++; 248 + 249 + return 0; 250 + } 251 + 252 + TIMER_OF_DECLARE(msc313, "mstar,msc313e-timer", msc313e_timer_init); 253 + TIMER_OF_DECLARE(ssd20xd, "sstar,ssd20xd-timer", msc313e_timer_init);
+2 -1
drivers/clocksource/timer-pistachio.c
··· 71 71 pistachio_clocksource_read_cycles(struct clocksource *cs) 72 72 { 73 73 struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs); 74 - u32 counter, overflow; 74 + __maybe_unused u32 overflow; 75 + u32 counter; 75 76 unsigned long flags; 76 77 77 78 /*
+20
include/linux/reset.h
··· 455 455 } 456 456 457 457 /** 458 + * of_reset_control_get_optional_exclusive - Lookup and obtain an optional exclusive 459 + * reference to a reset controller. 460 + * @node: device to be reset by the controller 461 + * @id: reset line name 462 + * 463 + * Optional variant of of_reset_control_get_exclusive(). If the requested reset 464 + * is not specified in the device tree, this function returns NULL instead of 465 + * an error. 466 + * 467 + * Returns a struct reset_control or IS_ERR() condition containing errno. 468 + * 469 + * Use of id names is optional. 470 + */ 471 + static inline struct reset_control *of_reset_control_get_optional_exclusive( 472 + struct device_node *node, const char *id) 473 + { 474 + return __of_reset_control_get(node, id, 0, false, true, true); 475 + } 476 + 477 + /** 458 478 * of_reset_control_get_shared - Lookup and obtain a shared reference 459 479 * to a reset controller. 460 480 * @node: device to be reset by the controller
+42 -10
kernel/time/clocksource.c
··· 107 107 * This delay could be due to SMIs, NMIs, or to VCPU preemptions. Used as 108 108 * a lower bound for cs->uncertainty_margin values when registering clocks. 109 109 */ 110 - #define WATCHDOG_MAX_SKEW (50 * NSEC_PER_USEC) 110 + #define WATCHDOG_MAX_SKEW (100 * NSEC_PER_USEC) 111 111 112 112 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG 113 113 static void clocksource_watchdog_work(struct work_struct *work); ··· 199 199 spin_unlock_irqrestore(&watchdog_lock, flags); 200 200 } 201 201 202 - ulong max_cswd_read_retries = 3; 202 + ulong max_cswd_read_retries = 2; 203 203 module_param(max_cswd_read_retries, ulong, 0644); 204 204 EXPORT_SYMBOL_GPL(max_cswd_read_retries); 205 205 static int verify_n_cpus = 8; 206 206 module_param(verify_n_cpus, int, 0644); 207 207 208 - static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) 208 + enum wd_read_status { 209 + WD_READ_SUCCESS, 210 + WD_READ_UNSTABLE, 211 + WD_READ_SKIP 212 + }; 213 + 214 + static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) 209 215 { 210 216 unsigned int nretries; 211 - u64 wd_end, wd_delta; 212 - int64_t wd_delay; 217 + u64 wd_end, wd_end2, wd_delta; 218 + int64_t wd_delay, wd_seq_delay; 213 219 214 220 for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) { 215 221 local_irq_disable(); 216 222 *wdnow = watchdog->read(watchdog); 217 223 *csnow = cs->read(cs); 218 224 wd_end = watchdog->read(watchdog); 225 + wd_end2 = watchdog->read(watchdog); 219 226 local_irq_enable(); 220 227 221 228 wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask); ··· 233 226 pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n", 234 227 smp_processor_id(), watchdog->name, nretries); 235 228 } 236 - return true; 229 + return WD_READ_SUCCESS; 237 230 } 231 + 232 + /* 233 + * Now compute delay in consecutive watchdog read to see if 234 + * there is too much external interferences that cause 235 + * significant delay in reading both clocksource and watchdog. 236 + * 237 + * If consecutive WD read-back delay > WATCHDOG_MAX_SKEW/2, 238 + * report system busy, reinit the watchdog and skip the current 239 + * watchdog test. 240 + */ 241 + wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask); 242 + wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift); 243 + if (wd_seq_delay > WATCHDOG_MAX_SKEW/2) 244 + goto skip_test; 238 245 } 239 246 240 247 pr_warn("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n", 241 248 smp_processor_id(), watchdog->name, wd_delay, nretries); 242 - return false; 249 + return WD_READ_UNSTABLE; 250 + 251 + skip_test: 252 + pr_info("timekeeping watchdog on CPU%d: %s wd-wd read-back delay of %lldns\n", 253 + smp_processor_id(), watchdog->name, wd_seq_delay); 254 + pr_info("wd-%s-wd read-back delay of %lldns, clock-skew test skipped!\n", 255 + cs->name, wd_delay); 256 + return WD_READ_SKIP; 243 257 } 244 258 245 259 static u64 csnow_mid; ··· 384 356 int next_cpu, reset_pending; 385 357 int64_t wd_nsec, cs_nsec; 386 358 struct clocksource *cs; 359 + enum wd_read_status read_ret; 387 360 u32 md; 388 361 389 362 spin_lock(&watchdog_lock); ··· 402 373 continue; 403 374 } 404 375 405 - if (!cs_watchdog_read(cs, &csnow, &wdnow)) { 406 - /* Clock readout unreliable, so give it up. */ 407 - __clocksource_unstable(cs); 376 + read_ret = cs_watchdog_read(cs, &csnow, &wdnow); 377 + 378 + if (read_ret != WD_READ_SUCCESS) { 379 + if (read_ret == WD_READ_UNSTABLE) 380 + /* Clock readout unreliable, so give it up. */ 381 + __clocksource_unstable(cs); 408 382 continue; 409 383 } 410 384