History

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

Linus Torvalds committed 4 years ago

Commit fd048992 parents 147cc58 35e13e916 files · +475 −44Browse files

Unified · Split

16 files
  1. Documentation/admin-guide/kernel-parameters.txt +2 −2
  2. Documentation/devicetree/bindings/timer/cdns,ttc.yaml +3 −0
  3. Documentation/devicetree/bindings/timer/mstar,msc313e-timer.yaml +46 −0
  4. Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml +5 −1
  5. Documentation/devicetree/bindings/timer/renesas,ostm.yaml +17 −3
  6. Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml +0 −1
  7. MAINTAINERS +1 −0
  8. drivers/clocksource/Kconfig +11 −1
  9. drivers/clocksource/Makefile +1 −0
  10. drivers/clocksource/exynos_mct.c +31 −21
  11. drivers/clocksource/renesas-ostm.c +38 −1
  12. drivers/clocksource/timer-imx-sysctr.c +3 −3
  13. drivers/clocksource/timer-msc313e.c +253 −0
  14. drivers/clocksource/timer-pistachio.c +2 −1
  15. include/linux/reset.h +20 −0
  16. kernel/time/clocksource.c +42 −10
Documentation/admin-guide/kernel-parameters.txt+2−2
@@ -612,8 +612,8 @@ · 611 unmodified lines
612 clocksource.max_cswd_read_retries= [KNL]612 clocksource.max_cswd_read_retries= [KNL]
613 Number of clocksource_watchdog() retries due to613 Number of clocksource_watchdog() retries due to
614 external delays before the clock will be marked614 external delays before the clock will be marked
615 unstable. Defaults to three retries, that is,615 unstable. Defaults to two retries, that is,
616 four attempts to read the clock under test.616 three attempts to read the clock under test.
617 617
618 clocksource.verify_n_cpus= [KNL]618 clocksource.verify_n_cpus= [KNL]
619 Limit the number of CPUs checked for clocksources619 Limit the number of CPUs checked for clocksources
Documentation/devicetree/bindings/timer/cdns,ttc.yaml+3−0
@@ -25,6 +25,9 @@ properties: · 24 unmodified lines
25 clocks:25 clocks:
26 maxItems: 126 maxItems: 1
27 27
28 power-domains:
29 maxItems: 1
30
28 timer-width:31 timer-width:
29 $ref: "/schemas/types.yaml#/definitions/uint32"32 $ref: "/schemas/types.yaml#/definitions/uint32"
30 description: |33 description: |
Documentation/devicetree/bindings/timer/mstar,msc313e-timer.yaml+46−0
@@ -0,0 +1,46 @@
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
7title: Mstar MSC313e Timer Device Tree Bindings
8
9maintainers:
10 - Daniel Palmer <daniel@0x0f.com>
11 - Romain Perier <romain.perier@gmail.com>
12
13properties:
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
28required:
29 - compatible
30 - reg
31 - interrupts
32 - clocks
33
34additionalProperties: false
35
36examples:
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...
Documentation/devicetree/bindings/timer/nxp,tpm-timer.yaml+5−1
@@ -19,7 +19,11 @@ description: | · 18 unmodified lines
19 19
20properties:20properties:
21 compatible:21 compatible:
22 const: fsl,imx7ulp-tpm22 oneOf:
23 - const: fsl,imx7ulp-tpm
24 - items:
25 - const: fsl,imx8ulp-tpm
26 - const: fsl,imx7ulp-tpm
23 27
24 reg:28 reg:
25 maxItems: 129 maxItems: 1
Documentation/devicetree/bindings/timer/renesas,ostm.yaml+17−3
@@ -21,9 +21,10 @@ properties: · 20 unmodified lines
21 compatible:21 compatible:
22 items:22 items:
23 - enum:23 - enum:
24 - renesas,r7s72100-ostm # RZ/A1H24 - renesas,r7s72100-ostm # RZ/A1H
25 - renesas,r7s9210-ostm # RZ/A2M25 - renesas,r7s9210-ostm # RZ/A2M
26 - const: renesas,ostm # Generic26 - renesas,r9a07g044-ostm # RZ/G2{L,LC}
27 - const: renesas,ostm # Generic
27 28
28 reg:29 reg:
29 maxItems: 130 maxItems: 1
@@ -37,6 +38,9 @@ properties: · 7 unmodified lines
37 power-domains:38 power-domains:
38 maxItems: 139 maxItems: 1
39 40
41 resets:
42 maxItems: 1
43
40required:44required:
41 - compatible45 - compatible
42 - reg46 - reg
@@ -44,6 +48,16 @@ required: · 1 unmodified line
44 - clocks48 - clocks
45 - power-domains49 - power-domains
46 50
51if:
52 properties:
53 compatible:
54 contains:
55 enum:
56 - renesas,r9a07g044-ostm
57then:
58 required:
59 - resets
60
47additionalProperties: false61additionalProperties: false
48 62
49examples:63examples:
Documentation/devicetree/bindings/timer/rockchip,rk-timer.yaml+0−1
@@ -18,7 +18,6 @@ properties: · 17 unmodified lines
18 - enum:18 - enum:
19 - rockchip,rv1108-timer19 - rockchip,rv1108-timer
20 - rockchip,rk3036-timer20 - rockchip,rk3036-timer
21 - rockchip,rk3066-timer
22 - rockchip,rk3188-timer21 - rockchip,rk3188-timer
23 - rockchip,rk3228-timer22 - rockchip,rk3228-timer
24 - rockchip,rk3229-timer23 - rockchip,rk3229-timer
MAINTAINERS+1−0
@@ -2304,6 +2304,7 @@ F: Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml · 2303 unmodified lines
2304F: arch/arm/boot/dts/mstar-*2304F: arch/arm/boot/dts/mstar-*
2305F: arch/arm/mach-mstar/2305F: arch/arm/mach-mstar/
2306F: drivers/clk/mstar/2306F: drivers/clk/mstar/
2307F: drivers/clocksource/timer-msc313e.c
2307F: drivers/gpio/gpio-msc313.c2308F: drivers/gpio/gpio-msc313.c
2308F: drivers/rtc/rtc-msc313.c2309F: drivers/rtc/rtc-msc313.c
2309F: drivers/watchdog/msc313e_wdt.c2310F: drivers/watchdog/msc313e_wdt.c
drivers/clocksource/Kconfig+11−1
@@ -510,7 +510,8 @@ config SH_TIMER_MTU2 · 509 unmodified lines
510 This hardware comes with 16-bit timer registers.510 This hardware comes with 16-bit timer registers.
511 511
512config RENESAS_OSTM512config RENESAS_OSTM
513 bool "Renesas OSTM timer driver" if COMPILE_TEST513 bool "Renesas OSTM timer driver"
514 depends on ARCH_RENESAS || COMPILE_TEST
514 select CLKSRC_MMIO515 select CLKSRC_MMIO
515 select TIMER_OF516 select TIMER_OF
516 help517 help
@@ -671,6 +672,15 @@ config MILBEAUT_TIMER · 154 unmodified lines
671 help672 help
672 Enables the support for Milbeaut timer driver.673 Enables the support for Milbeaut timer driver.
673 674
675config MSC313E_TIMER
676 bool "MSC313E timer driver" if COMPILE_TEST
677 select TIMER_OF
678 select CLKSRC_MMIO
679 help
680 Enables support for the MStar MSC313E timer driver.
681 This provides access to multiple interrupt generating
682 programmable 32-bit free running incrementing counters.
683
674config INGENIC_TIMER684config INGENIC_TIMER
675 bool "Clocksource/timer using the TCU in Ingenic JZ SoCs"685 bool "Clocksource/timer using the TCU in Ingenic JZ SoCs"
676 default MACH_INGENIC686 default MACH_INGENIC
drivers/clocksource/Makefile+1−0
@@ -88,3 +88,4 @@ obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o · 87 unmodified lines
88obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o88obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
89obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o89obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o
90obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o90obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o
91obj-$(CONFIG_MSC313E_TIMER) += timer-msc313e.o
drivers/clocksource/exynos_mct.c+31−21
@@ -467,7 +467,7 @@ static int exynos4_mct_starting_cpu(unsigned int cpu) · 466 unmodified lines
467 evt->tick_resume = set_state_shutdown;467 evt->tick_resume = set_state_shutdown;
468 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |468 evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
469 CLOCK_EVT_FEAT_PERCPU;469 CLOCK_EVT_FEAT_PERCPU;
470 evt->rating = MCT_CLKEVENTS_RATING,470 evt->rating = MCT_CLKEVENTS_RATING;
471 471
472 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);472 exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
473 473
@@ -504,11 +504,14 @@ static int exynos4_mct_dying_cpu(unsigned int cpu) · 30 unmodified lines
504 return 0;504 return 0;
505}505}
506 506
507static int __init exynos4_timer_resources(struct device_node *np, void __iomem *base)507static int __init exynos4_timer_resources(struct device_node *np)
508{508{
509 int err, cpu;
510 struct clk *mct_clk, *tick_clk;509 struct clk *mct_clk, *tick_clk;
511 510
511 reg_base = of_iomap(np, 0);
512 if (!reg_base)
513 panic("%s: unable to ioremap mct address space\n", __func__);
514
512 tick_clk = of_clk_get_by_name(np, "fin_pll");515 tick_clk = of_clk_get_by_name(np, "fin_pll");
513 if (IS_ERR(tick_clk))516 if (IS_ERR(tick_clk))
514 panic("%s: unable to determine tick clock rate\n", __func__);517 panic("%s: unable to determine tick clock rate\n", __func__);
@@ -519,9 +522,27 @@ static int __init exynos4_timer_resources(struct device_node *np, void __iomem * · 4 unmodified lines
519 panic("%s: unable to retrieve mct clock instance\n", __func__);522 panic("%s: unable to retrieve mct clock instance\n", __func__);
520 clk_prepare_enable(mct_clk);523 clk_prepare_enable(mct_clk);
521 524
522 reg_base = base;525 return 0;
523 if (!reg_base)526}
524 panic("%s: unable to ioremap mct address space\n", __func__);527
528static int __init exynos4_timer_interrupts(struct device_node *np,
529 unsigned int int_type)
530{
531 int nr_irqs, i, err, cpu;
532
533 mct_int_type = int_type;
534
535 /* This driver uses only one global timer interrupt */
536 mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
537
538 /*
539 * Find out the number of local irqs specified. The local
540 * timer irqs are specified after the four global timer
541 * irqs are specified.
542 */
543 nr_irqs = of_irq_count(np);
544 for (i = MCT_L0_IRQ; i < nr_irqs; i++)
545 mct_irqs[i] = irq_of_parse_and_map(np, i);
525 546
526 if (mct_int_type == MCT_INT_PPI) {547 if (mct_int_type == MCT_INT_PPI) {
527 548
@@ -581,24 +602,13 @@ out_irq: · 53 unmodified lines
581 602
582static int __init mct_init_dt(struct device_node *np, unsigned int int_type)603static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
583{604{
584 u32 nr_irqs, i;
585 int ret;605 int ret;
586 606
587 mct_int_type = int_type;607 ret = exynos4_timer_resources(np);
588 608 if (ret)
589 /* This driver uses only one global timer interrupt */609 return ret;
590 mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
591
592 /*
593 * Find out the number of local irqs specified. The local
594 * timer irqs are specified after the four global timer
595 * irqs are specified.
596 */
597 nr_irqs = of_irq_count(np);
598 for (i = MCT_L0_IRQ; i < nr_irqs; i++)
599 mct_irqs[i] = irq_of_parse_and_map(np, i);
600 610
601 ret = exynos4_timer_resources(np, of_iomap(np, 0));611 ret = exynos4_timer_interrupts(np, int_type);
602 if (ret)612 if (ret)
603 return ret;613 return ret;
604 614
drivers/clocksource/renesas-ostm.c+38−1
@@ -9,6 +9,8 @@ · 8 unmodified lines
9#include <linux/clk.h>9#include <linux/clk.h>
10#include <linux/clockchips.h>10#include <linux/clockchips.h>
11#include <linux/interrupt.h>11#include <linux/interrupt.h>
12#include <linux/platform_device.h>
13#include <linux/reset.h>
12#include <linux/sched_clock.h>14#include <linux/sched_clock.h>
13#include <linux/slab.h>15#include <linux/slab.h>
14 16
@@ -159,6 +161,7 @@ static int __init ostm_init_clkevt(struct timer_of *to) · 144 unmodified lines
159 161
160static int __init ostm_init(struct device_node *np)162static int __init ostm_init(struct device_node *np)
161{163{
164 struct reset_control *rstc;
162 struct timer_of *to;165 struct timer_of *to;
163 int ret;166 int ret;
164 167
@@ -166,6 +169,14 @@ static int __init ostm_init(struct device_node *np) · 1 unmodified line
166 if (!to)169 if (!to)
167 return -ENOMEM;170 return -ENOMEM;
168 171
172 rstc = of_reset_control_get_optional_exclusive(np, NULL);
173 if (IS_ERR(rstc)) {
174 ret = PTR_ERR(rstc);
175 goto err_free;
176 }
177
178 reset_control_deassert(rstc);
179
169 to->flags = TIMER_OF_BASE | TIMER_OF_CLOCK;180 to->flags = TIMER_OF_BASE | TIMER_OF_CLOCK;
170 if (system_clock) {181 if (system_clock) {
171 /*182 /*
@@ -178,7 +189,7 @@ static int __init ostm_init(struct device_node *np) · 6 unmodified lines
178 189
179 ret = timer_of_init(np, to);190 ret = timer_of_init(np, to);
180 if (ret)191 if (ret)
181 goto err_free;192 goto err_reset;
182 193
183 /*194 /*
184 * First probed device will be used as system clocksource. Any195 * First probed device will be used as system clocksource. Any
@@ -203,9 +214,35 @@ static int __init ostm_init(struct device_node *np) · 18 unmodified lines
203 214
204err_cleanup:215err_cleanup:
205 timer_of_cleanup(to);216 timer_of_cleanup(to);
217err_reset:
218 reset_control_assert(rstc);
219 reset_control_put(rstc);
206err_free:220err_free:
207 kfree(to);221 kfree(to);
208 return ret;222 return ret;
209}223}
210 224
211TIMER_OF_DECLARE(ostm, "renesas,ostm", ostm_init);225TIMER_OF_DECLARE(ostm, "renesas,ostm", ostm_init);
226
227#ifdef CONFIG_ARCH_R9A07G044
228static int __init ostm_probe(struct platform_device *pdev)
229{
230 struct device *dev = &pdev->dev;
231
232 return ostm_init(dev->of_node);
233}
234
235static const struct of_device_id ostm_of_table[] = {
236 { .compatible = "renesas,ostm", },
237 { /* sentinel */ }
238};
239
240static struct platform_driver ostm_device_driver = {
241 .driver = {
242 .name = "renesas_ostm",
243 .of_match_table = of_match_ptr(ostm_of_table),
244 .suppress_bind_attrs = true,
245 },
246};
247builtin_platform_driver_probe(ostm_device_driver, ostm_probe);
248#endif
drivers/clocksource/timer-imx-sysctr.c+3−3
@@ -20,8 +20,8 @@ · 19 unmodified lines
20 20
21#define SYS_CTR_CLK_DIV 0x321#define SYS_CTR_CLK_DIV 0x3
22 22
23static void __iomem *sys_ctr_base;23static void __iomem *sys_ctr_base __ro_after_init;
24static u32 cmpcr;24static u32 cmpcr __ro_after_init;
25 25
26static void sysctr_timer_enable(bool enable)26static void sysctr_timer_enable(bool enable)
27{27{
@@ -119,7 +119,7 @@ static struct timer_of to_sysctr = { · 91 unmodified lines
119 119
120static void __init sysctr_clockevent_init(void)120static 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 clockevents_config_and_register(&to_sysctr.clkevt,124 clockevents_config_and_register(&to_sysctr.clkevt,
125 timer_of_rate(&to_sysctr),125 timer_of_rate(&to_sysctr),
drivers/clocksource/timer-msc313e.c+253−0
@@ -0,0 +1,253 @@
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
42struct msc313e_delay {
43 void __iomem *base;
44 struct delay_timer delay;
45};
46static struct msc313e_delay msc313e_delay;
47#endif
48
49static void __iomem *msc313e_clksrc;
50
51static void msc313e_timer_stop(void __iomem *base)
52{
53 writew(0, base + MSC313E_REG_CTRL);
54}
55
56static 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
68static 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
78static 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
91static 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
100static 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
110static 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
121static 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
132static 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
141static 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
147static unsigned long msc313e_read_delay_timer_read(void)
148{
149 return msc313e_timer_current_value(msc313e_delay.base);
150}
151#endif
152
153static u64 msc313e_timer_sched_clock_read(void)
154{
155 return msc313e_timer_current_value(msc313e_clksrc);
156}
157
158static 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
169static 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
199static 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
228static 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
252TIMER_OF_DECLARE(msc313, "mstar,msc313e-timer", msc313e_timer_init);
253TIMER_OF_DECLARE(ssd20xd, "sstar,ssd20xd-timer", msc313e_timer_init);
drivers/clocksource/timer-pistachio.c+2−1
@@ -71,7 +71,8 @@ static u64 notrace · 70 unmodified lines
71pistachio_clocksource_read_cycles(struct clocksource *cs)71pistachio_clocksource_read_cycles(struct clocksource *cs)
72{72{
73 struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs);73 struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs);
74 u32 counter, overflow;74 __maybe_unused u32 overflow;
75 u32 counter;
75 unsigned long flags;76 unsigned long flags;
76 77
77 /*78 /*
include/linux/reset.h+20−0
@@ -454,6 +454,26 @@ static inline struct reset_control *of_reset_control_get_exclusive( · 453 unmodified lines
454 return __of_reset_control_get(node, id, 0, false, false, true);454 return __of_reset_control_get(node, id, 0, false, false, true);
455}455}
456 456
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 */
471static 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
457/**477/**
458 * of_reset_control_get_shared - Lookup and obtain a shared reference478 * of_reset_control_get_shared - Lookup and obtain a shared reference
459 * to a reset controller.479 * to a reset controller.
kernel/time/clocksource.c+42−10
@@ -107,7 +107,7 @@ static u64 suspend_start; · 106 unmodified lines
107 * This delay could be due to SMIs, NMIs, or to VCPU preemptions. Used as107 * This delay could be due to SMIs, NMIs, or to VCPU preemptions. Used as
108 * a lower bound for cs->uncertainty_margin values when registering clocks.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#ifdef CONFIG_CLOCKSOURCE_WATCHDOG112#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
113static void clocksource_watchdog_work(struct work_struct *work);113static void clocksource_watchdog_work(struct work_struct *work);
@@ -199,23 +199,30 @@ void clocksource_mark_unstable(struct clocksource *cs) · 85 unmodified lines
199 spin_unlock_irqrestore(&watchdog_lock, flags);199 spin_unlock_irqrestore(&watchdog_lock, flags);
200}200}
201 201
202ulong max_cswd_read_retries = 3;202ulong max_cswd_read_retries = 2;
203module_param(max_cswd_read_retries, ulong, 0644);203module_param(max_cswd_read_retries, ulong, 0644);
204EXPORT_SYMBOL_GPL(max_cswd_read_retries);204EXPORT_SYMBOL_GPL(max_cswd_read_retries);
205static int verify_n_cpus = 8;205static int verify_n_cpus = 8;
206module_param(verify_n_cpus, int, 0644);206module_param(verify_n_cpus, int, 0644);
207 207
208static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)208enum wd_read_status {
209 WD_READ_SUCCESS,
210 WD_READ_UNSTABLE,
211 WD_READ_SKIP
212};
213
214static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow)
209{215{
210 unsigned int nretries;216 unsigned int nretries;
211 u64 wd_end, wd_delta;217 u64 wd_end, wd_end2, wd_delta;
212 int64_t wd_delay;218 int64_t wd_delay, wd_seq_delay;
213 219
214 for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) {220 for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) {
215 local_irq_disable();221 local_irq_disable();
216 *wdnow = watchdog->read(watchdog);222 *wdnow = watchdog->read(watchdog);
217 *csnow = cs->read(cs);223 *csnow = cs->read(cs);
218 wd_end = watchdog->read(watchdog);224 wd_end = watchdog->read(watchdog);
225 wd_end2 = watchdog->read(watchdog);
219 local_irq_enable();226 local_irq_enable();
220 227
221 wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask);228 wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask);
@@ -226,13 +233,34 @@ static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) · 4 unmodified lines
226 pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n",233 pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n",
227 smp_processor_id(), watchdog->name, nretries);234 smp_processor_id(), watchdog->name, nretries);
228 }235 }
229 return true;236 return WD_READ_SUCCESS;
230 }237 }
238
239 /*
240 * Now compute delay in consecutive watchdog read to see if
241 * there is too much external interferences that cause
242 * significant delay in reading both clocksource and watchdog.
243 *
244 * If consecutive WD read-back delay > WATCHDOG_MAX_SKEW/2,
245 * report system busy, reinit the watchdog and skip the current
246 * watchdog test.
247 */
248 wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask);
249 wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift);
250 if (wd_seq_delay > WATCHDOG_MAX_SKEW/2)
251 goto skip_test;
231 }252 }
232 253
233 pr_warn("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n",254 pr_warn("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n",
234 smp_processor_id(), watchdog->name, wd_delay, nretries);255 smp_processor_id(), watchdog->name, wd_delay, nretries);
235 return false;256 return WD_READ_UNSTABLE;
257
258skip_test:
259 pr_info("timekeeping watchdog on CPU%d: %s wd-wd read-back delay of %lldns\n",
260 smp_processor_id(), watchdog->name, wd_seq_delay);
261 pr_info("wd-%s-wd read-back delay of %lldns, clock-skew test skipped!\n",
262 cs->name, wd_delay);
263 return WD_READ_SKIP;
236}264}
237 265
238static u64 csnow_mid;266static u64 csnow_mid;
@@ -356,6 +384,7 @@ static void clocksource_watchdog(struct timer_list *unused) · 117 unmodified lines
356 int next_cpu, reset_pending;384 int next_cpu, reset_pending;
357 int64_t wd_nsec, cs_nsec;385 int64_t wd_nsec, cs_nsec;
358 struct clocksource *cs;386 struct clocksource *cs;
387 enum wd_read_status read_ret;
359 u32 md;388 u32 md;
360 389
361 spin_lock(&watchdog_lock);390 spin_lock(&watchdog_lock);
@@ -373,9 +402,12 @@ static void clocksource_watchdog(struct timer_list *unused) · 11 unmodified lines
373 continue;402 continue;
374 }403 }
375 404
376 if (!cs_watchdog_read(cs, &csnow, &wdnow)) {405 read_ret = cs_watchdog_read(cs, &csnow, &wdnow);
377 /* Clock readout unreliable, so give it up. */406
378 __clocksource_unstable(cs);407 if (read_ret != WD_READ_SUCCESS) {
408 if (read_ret == WD_READ_UNSTABLE)
409 /* Clock readout unreliable, so give it up. */
410 __clocksource_unstable(cs);
379 continue;411 continue;
380 }412 }
381 413