aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2019-02-23 11:21:53 -0500
committerThomas Gleixner <tglx@linutronix.de>2019-02-23 11:21:53 -0500
commit8dd2eee2f444a7a570599bffc9da330157cca5b5 (patch)
tree400b9a2fb19e7ac5bac27750bdac77615eded541
parent75b710af7139768fd4ba2d4e05335d2344796279 (diff)
parentf40f4fc9506d6b2b786920059b320aac3a831574 (diff)
Merge branch 'clockevents/5.1' of https://git.linaro.org/people/daniel.lezcano/linux into timers/core
Pull clockevents updates from Daniel Lezcano: - Update the binding documentation for the gpt timer (Anson Huang) - Improve checking and error handling at init time on risc timer (Atish Patra) - Update the binding documentation for r8a774c0 cmt and tmu (Biju Das) - Fail gracefully when clock rate is unavailable on sun5i (Chen-Yu Tsai) - Rename the tango-xtal, pxa and cs5535 to timer-*.c for consistency (Daniel Lezcano) - Add the support for the tegra210 timer and add the platform's Kconfig selection (Joseph Lo) - Do a cleanup in the header inclusions and remove the unused ones for the exynos_mct timer driver (Krzysztof Kozlowski) - Remove some non-of dead code and fix the error path when initializing the resources in the exynos_mct timer driver (Marek Szyprowski) - Update the DT bindings for the MT7629 (Ryder Lee) - Provide a workaround for the arm arch timer for Allwinner A64 timers (Samuel Holland) - Clear the timer interrupt at shutdown time on the exynos_mct timer driver (Stuart Menefy)
-rw-r--r--Documentation/arm64/silicon-errata.txt2
-rw-r--r--Documentation/devicetree/bindings/timer/fsl,imxgpt.txt39
-rw-r--r--Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt11
-rw-r--r--Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt36
-rw-r--r--Documentation/devicetree/bindings/timer/renesas,cmt.txt2
-rw-r--r--Documentation/devicetree/bindings/timer/renesas,tmu.txt1
-rw-r--r--drivers/clocksource/Kconfig13
-rw-r--r--drivers/clocksource/Makefile6
-rw-r--r--drivers/clocksource/arm_arch_timer.c55
-rw-r--r--drivers/clocksource/exynos_mct.c48
-rw-r--r--drivers/clocksource/timer-cs5535.c (renamed from drivers/clocksource/cs5535-clockevt.c)0
-rw-r--r--drivers/clocksource/timer-pxa.c (renamed from drivers/clocksource/pxa_timer.c)0
-rw-r--r--drivers/clocksource/timer-riscv.c23
-rw-r--r--drivers/clocksource/timer-sun5i.c10
-rw-r--r--drivers/clocksource/timer-tango-xtal.c (renamed from drivers/clocksource/tango_xtal.c)0
-rw-r--r--drivers/clocksource/timer-tegra20.c370
-rw-r--r--drivers/soc/tegra/Kconfig1
-rw-r--r--include/linux/cpuhotplug.h1
18 files changed, 470 insertions, 148 deletions
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 1f09d043d086..ddb8ce5333ba 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -44,6 +44,8 @@ stable kernels.
44 44
45| Implementor | Component | Erratum ID | Kconfig | 45| Implementor | Component | Erratum ID | Kconfig |
46+----------------+-----------------+-----------------+-----------------------------+ 46+----------------+-----------------+-----------------+-----------------------------+
47| Allwinner | A64/R18 | UNKNOWN1 | SUN50I_ERRATUM_UNKNOWN1 |
48| | | | |
47| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | 49| ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 |
48| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 | 50| ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 |
49| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 | 51| ARM | Cortex-A53 | #824069 | ARM64_ERRATUM_824069 |
diff --git a/Documentation/devicetree/bindings/timer/fsl,imxgpt.txt b/Documentation/devicetree/bindings/timer/fsl,imxgpt.txt
index 9809b11f7180..5d8fd5b52598 100644
--- a/Documentation/devicetree/bindings/timer/fsl,imxgpt.txt
+++ b/Documentation/devicetree/bindings/timer/fsl,imxgpt.txt
@@ -2,17 +2,44 @@ Freescale i.MX General Purpose Timer (GPT)
2 2
3Required properties: 3Required properties:
4 4
5- compatible : should be "fsl,<soc>-gpt" 5- compatible : should be one of following:
6- reg : Specifies base physical address and size of the registers. 6 for i.MX1:
7- interrupts : A list of 4 interrupts; one per timer channel. 7 - "fsl,imx1-gpt";
8- clocks : The clocks provided by the SoC to drive the timer. 8 for i.MX21:
9 - "fsl,imx21-gpt";
10 for i.MX27:
11 - "fsl,imx27-gpt", "fsl,imx21-gpt";
12 for i.MX31:
13 - "fsl,imx31-gpt";
14 for i.MX25:
15 - "fsl,imx25-gpt", "fsl,imx31-gpt";
16 for i.MX50:
17 - "fsl,imx50-gpt", "fsl,imx31-gpt";
18 for i.MX51:
19 - "fsl,imx51-gpt", "fsl,imx31-gpt";
20 for i.MX53:
21 - "fsl,imx53-gpt", "fsl,imx31-gpt";
22 for i.MX6Q:
23 - "fsl,imx6q-gpt", "fsl,imx31-gpt";
24 for i.MX6DL:
25 - "fsl,imx6dl-gpt";
26 for i.MX6SL:
27 - "fsl,imx6sl-gpt", "fsl,imx6dl-gpt";
28 for i.MX6SX:
29 - "fsl,imx6sx-gpt", "fsl,imx6dl-gpt";
30- reg : specifies base physical address and size of the registers.
31- interrupts : should be the gpt interrupt.
32- clocks : the clocks provided by the SoC to drive the timer, must contain
33 an entry for each entry in clock-names.
34- clock-names : must include "ipg" entry first, then "per" entry.
9 35
10Example: 36Example:
11 37
12gpt1: timer@10003000 { 38gpt1: timer@10003000 {
13 compatible = "fsl,imx27-gpt", "fsl,imx1-gpt"; 39 compatible = "fsl,imx27-gpt", "fsl,imx21-gpt";
14 reg = <0x10003000 0x1000>; 40 reg = <0x10003000 0x1000>;
15 interrupts = <26>; 41 interrupts = <26>;
16 clocks = <&clks 46>, <&clks 61>; 42 clocks = <&clks IMX27_CLK_GPT1_IPG_GATE>,
43 <&clks IMX27_CLK_PER1_GATE>;
17 clock-names = "ipg", "per"; 44 clock-names = "ipg", "per";
18}; 45};
diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index 18d4d0166c76..ff7c567a7972 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -1,7 +1,7 @@
1Mediatek Timers 1MediaTek Timers
2--------------- 2---------------
3 3
4Mediatek SoCs have two different timers on different platforms, 4MediaTek SoCs have two different timers on different platforms,
5- GPT (General Purpose Timer) 5- GPT (General Purpose Timer)
6- SYST (System Timer) 6- SYST (System Timer)
7 7
@@ -9,6 +9,7 @@ The proper timer will be selected automatically by driver.
9 9
10Required properties: 10Required properties:
11- compatible should contain: 11- compatible should contain:
12 For those SoCs that use GPT
12 * "mediatek,mt2701-timer" for MT2701 compatible timers (GPT) 13 * "mediatek,mt2701-timer" for MT2701 compatible timers (GPT)
13 * "mediatek,mt6580-timer" for MT6580 compatible timers (GPT) 14 * "mediatek,mt6580-timer" for MT6580 compatible timers (GPT)
14 * "mediatek,mt6589-timer" for MT6589 compatible timers (GPT) 15 * "mediatek,mt6589-timer" for MT6589 compatible timers (GPT)
@@ -17,7 +18,11 @@ Required properties:
17 * "mediatek,mt8135-timer" for MT8135 compatible timers (GPT) 18 * "mediatek,mt8135-timer" for MT8135 compatible timers (GPT)
18 * "mediatek,mt8173-timer" for MT8173 compatible timers (GPT) 19 * "mediatek,mt8173-timer" for MT8173 compatible timers (GPT)
19 * "mediatek,mt6577-timer" for MT6577 and all above compatible timers (GPT) 20 * "mediatek,mt6577-timer" for MT6577 and all above compatible timers (GPT)
20 * "mediatek,mt6765-timer" for MT6765 compatible timers (SYST) 21
22 For those SoCs that use SYST
23 * "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
24 * "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
25
21- reg: Should contain location and length for timer register. 26- reg: Should contain location and length for timer register.
22- clocks: Should contain system clock. 27- clocks: Should contain system clock.
23 28
diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
new file mode 100644
index 000000000000..032cda96fe0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
@@ -0,0 +1,36 @@
1NVIDIA Tegra210 timer
2
3The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
4timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
5from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
6(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
7or watchdog interrupts.
8
9Required properties:
10- compatible : "nvidia,tegra210-timer".
11- reg : Specifies base physical address and size of the registers.
12- interrupts : A list of 14 interrupts; one per each timer channels 0 through
13 13.
14- clocks : Must contain one entry, for the module clock.
15 See ../clocks/clock-bindings.txt for details.
16
17timer@60005000 {
18 compatible = "nvidia,tegra210-timer";
19 reg = <0x0 0x60005000 0x0 0x400>;
20 interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
21 <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
22 <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
23 <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
24 <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
25 <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
26 <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
27 <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
28 <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
29 <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
30 <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
31 <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
32 <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
33 <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
34 clocks = <&tegra_car TEGRA210_CLK_TIMER>;
35 clock-names = "timer";
36};
diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
index 862a80f0380a..c0594450e9ef 100644
--- a/Documentation/devicetree/bindings/timer/renesas,cmt.txt
+++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt
@@ -32,6 +32,8 @@ Required Properties:
32 - "renesas,r8a77470-cmt1" for the 48-bit CMT1 device included in r8a77470. 32 - "renesas,r8a77470-cmt1" for the 48-bit CMT1 device included in r8a77470.
33 - "renesas,r8a774a1-cmt0" for the 32-bit CMT0 device included in r8a774a1. 33 - "renesas,r8a774a1-cmt0" for the 32-bit CMT0 device included in r8a774a1.
34 - "renesas,r8a774a1-cmt1" for the 48-bit CMT1 device included in r8a774a1. 34 - "renesas,r8a774a1-cmt1" for the 48-bit CMT1 device included in r8a774a1.
35 - "renesas,r8a774c0-cmt0" for the 32-bit CMT0 device included in r8a774c0.
36 - "renesas,r8a774c0-cmt1" for the 48-bit CMT1 device included in r8a774c0.
35 - "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790. 37 - "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790.
36 - "renesas,r8a7790-cmt1" for the 48-bit CMT1 device included in r8a7790. 38 - "renesas,r8a7790-cmt1" for the 48-bit CMT1 device included in r8a7790.
37 - "renesas,r8a7791-cmt0" for the 32-bit CMT0 device included in r8a7791. 39 - "renesas,r8a7791-cmt0" for the 32-bit CMT0 device included in r8a7791.
diff --git a/Documentation/devicetree/bindings/timer/renesas,tmu.txt b/Documentation/devicetree/bindings/timer/renesas,tmu.txt
index 4ddff85837da..13ad07416bdd 100644
--- a/Documentation/devicetree/bindings/timer/renesas,tmu.txt
+++ b/Documentation/devicetree/bindings/timer/renesas,tmu.txt
@@ -10,6 +10,7 @@ Required Properties:
10 10
11 - compatible: must contain one or more of the following: 11 - compatible: must contain one or more of the following:
12 - "renesas,tmu-r8a7740" for the r8a7740 TMU 12 - "renesas,tmu-r8a7740" for the r8a7740 TMU
13 - "renesas,tmu-r8a774c0" for the r8a774C0 TMU
13 - "renesas,tmu-r8a7778" for the r8a7778 TMU 14 - "renesas,tmu-r8a7778" for the r8a7778 TMU
14 - "renesas,tmu-r8a7779" for the r8a7779 TMU 15 - "renesas,tmu-r8a7779" for the r8a7779 TMU
15 - "renesas,tmu-r8a77970" for the r8a77970 TMU 16 - "renesas,tmu-r8a77970" for the r8a77970 TMU
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..5d93e580e5dc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,8 @@ config SUN5I_HSTIMER
131config TEGRA_TIMER 131config TEGRA_TIMER
132 bool "Tegra timer driver" if COMPILE_TEST 132 bool "Tegra timer driver" if COMPILE_TEST
133 select CLKSRC_MMIO 133 select CLKSRC_MMIO
134 depends on ARM 134 select TIMER_OF
135 depends on ARM || ARM64
135 help 136 help
136 Enables support for the Tegra driver. 137 Enables support for the Tegra driver.
137 138
@@ -360,6 +361,16 @@ config ARM64_ERRATUM_858921
360 The workaround will be dynamically enabled when an affected 361 The workaround will be dynamically enabled when an affected
361 core is detected. 362 core is detected.
362 363
364config SUN50I_ERRATUM_UNKNOWN1
365 bool "Workaround for Allwinner A64 erratum UNKNOWN1"
366 default y
367 depends on ARM_ARCH_TIMER && ARM64 && ARCH_SUNXI
368 select ARM_ARCH_TIMER_OOL_WORKAROUND
369 help
370 This option enables a workaround for instability in the timer on
371 the Allwinner A64 SoC. The workaround will only be active if the
372 allwinner,erratum-unknown1 property is found in the timer node.
373
363config ARM_GLOBAL_TIMER 374config ARM_GLOBAL_TIMER
364 bool "Support for the ARM global timer" if COMPILE_TEST 375 bool "Support for the ARM global timer" if COMPILE_TEST
365 select TIMER_OF if OF 376 select TIMER_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..c4a8e9ef932a 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o
6obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o 6obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
7obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o 7obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
8obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o 8obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
9obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o 9obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += timer-cs5535.o
10obj-$(CONFIG_CLKSRC_JCORE_PIT) += jcore-pit.o 10obj-$(CONFIG_CLKSRC_JCORE_PIT) += jcore-pit.o
11obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o 11obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
12obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o 12obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o
@@ -29,7 +29,7 @@ obj-$(CONFIG_BCM2835_TIMER) += bcm2835_timer.o
29obj-$(CONFIG_CLPS711X_TIMER) += clps711x-timer.o 29obj-$(CONFIG_CLPS711X_TIMER) += clps711x-timer.o
30obj-$(CONFIG_ATLAS7_TIMER) += timer-atlas7.o 30obj-$(CONFIG_ATLAS7_TIMER) += timer-atlas7.o
31obj-$(CONFIG_MXS_TIMER) += mxs_timer.o 31obj-$(CONFIG_MXS_TIMER) += mxs_timer.o
32obj-$(CONFIG_CLKSRC_PXA) += pxa_timer.o 32obj-$(CONFIG_CLKSRC_PXA) += timer-pxa.o
33obj-$(CONFIG_PRIMA2_TIMER) += timer-prima2.o 33obj-$(CONFIG_PRIMA2_TIMER) += timer-prima2.o
34obj-$(CONFIG_U300_TIMER) += timer-u300.o 34obj-$(CONFIG_U300_TIMER) += timer-u300.o
35obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o 35obj-$(CONFIG_SUN4I_TIMER) += timer-sun4i.o
@@ -69,7 +69,7 @@ obj-$(CONFIG_KEYSTONE_TIMER) += timer-keystone.o
69obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o 69obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o
70obj-$(CONFIG_CLKSRC_VERSATILE) += timer-versatile.o 70obj-$(CONFIG_CLKSRC_VERSATILE) += timer-versatile.o
71obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o 71obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o
72obj-$(CONFIG_CLKSRC_TANGO_XTAL) += tango_xtal.o 72obj-$(CONFIG_CLKSRC_TANGO_XTAL) += timer-tango-xtal.o
73obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o 73obj-$(CONFIG_CLKSRC_IMX_GPT) += timer-imx-gpt.o
74obj-$(CONFIG_CLKSRC_IMX_TPM) += timer-imx-tpm.o 74obj-$(CONFIG_CLKSRC_IMX_TPM) += timer-imx-tpm.o
75obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o 75obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 9a7d4dc00b6e..a8b20b65bd4b 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -326,6 +326,48 @@ static u64 notrace arm64_1188873_read_cntvct_el0(void)
326} 326}
327#endif 327#endif
328 328
329#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
330/*
331 * The low bits of the counter registers are indeterminate while bit 10 or
332 * greater is rolling over. Since the counter value can jump both backward
333 * (7ff -> 000 -> 800) and forward (7ff -> fff -> 800), ignore register values
334 * with all ones or all zeros in the low bits. Bound the loop by the maximum
335 * number of CPU cycles in 3 consecutive 24 MHz counter periods.
336 */
337#define __sun50i_a64_read_reg(reg) ({ \
338 u64 _val; \
339 int _retries = 150; \
340 \
341 do { \
342 _val = read_sysreg(reg); \
343 _retries--; \
344 } while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries); \
345 \
346 WARN_ON_ONCE(!_retries); \
347 _val; \
348})
349
350static u64 notrace sun50i_a64_read_cntpct_el0(void)
351{
352 return __sun50i_a64_read_reg(cntpct_el0);
353}
354
355static u64 notrace sun50i_a64_read_cntvct_el0(void)
356{
357 return __sun50i_a64_read_reg(cntvct_el0);
358}
359
360static u32 notrace sun50i_a64_read_cntp_tval_el0(void)
361{
362 return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0();
363}
364
365static u32 notrace sun50i_a64_read_cntv_tval_el0(void)
366{
367 return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0();
368}
369#endif
370
329#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND 371#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
330DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround); 372DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround);
331EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); 373EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
@@ -423,6 +465,19 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
423 .read_cntvct_el0 = arm64_1188873_read_cntvct_el0, 465 .read_cntvct_el0 = arm64_1188873_read_cntvct_el0,
424 }, 466 },
425#endif 467#endif
468#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
469 {
470 .match_type = ate_match_dt,
471 .id = "allwinner,erratum-unknown1",
472 .desc = "Allwinner erratum UNKNOWN1",
473 .read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0,
474 .read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0,
475 .read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
476 .read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
477 .set_next_event_phys = erratum_set_next_event_tval_phys,
478 .set_next_event_virt = erratum_set_next_event_tval_virt,
479 },
480#endif
426}; 481};
427 482
428typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *, 483typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 7a244b681876..34bd250d46c6 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -10,14 +10,12 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#include <linux/sched.h>
14#include <linux/interrupt.h> 13#include <linux/interrupt.h>
15#include <linux/irq.h> 14#include <linux/irq.h>
16#include <linux/err.h> 15#include <linux/err.h>
17#include <linux/clk.h> 16#include <linux/clk.h>
18#include <linux/clockchips.h> 17#include <linux/clockchips.h>
19#include <linux/cpu.h> 18#include <linux/cpu.h>
20#include <linux/platform_device.h>
21#include <linux/delay.h> 19#include <linux/delay.h>
22#include <linux/percpu.h> 20#include <linux/percpu.h>
23#include <linux/of.h> 21#include <linux/of.h>
@@ -388,6 +386,13 @@ static void exynos4_mct_tick_start(unsigned long cycles,
388 exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET); 386 exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
389} 387}
390 388
389static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
390{
391 /* Clear the MCT tick interrupt */
392 if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1)
393 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
394}
395
391static int exynos4_tick_set_next_event(unsigned long cycles, 396static int exynos4_tick_set_next_event(unsigned long cycles,
392 struct clock_event_device *evt) 397 struct clock_event_device *evt)
393{ 398{
@@ -404,6 +409,7 @@ static int set_state_shutdown(struct clock_event_device *evt)
404 409
405 mevt = container_of(evt, struct mct_clock_event_device, evt); 410 mevt = container_of(evt, struct mct_clock_event_device, evt);
406 exynos4_mct_tick_stop(mevt); 411 exynos4_mct_tick_stop(mevt);
412 exynos4_mct_tick_clear(mevt);
407 return 0; 413 return 0;
408} 414}
409 415
@@ -420,8 +426,11 @@ static int set_state_periodic(struct clock_event_device *evt)
420 return 0; 426 return 0;
421} 427}
422 428
423static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) 429static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
424{ 430{
431 struct mct_clock_event_device *mevt = dev_id;
432 struct clock_event_device *evt = &mevt->evt;
433
425 /* 434 /*
426 * This is for supporting oneshot mode. 435 * This is for supporting oneshot mode.
427 * Mct would generate interrupt periodically 436 * Mct would generate interrupt periodically
@@ -430,16 +439,6 @@ static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
430 if (!clockevent_state_periodic(&mevt->evt)) 439 if (!clockevent_state_periodic(&mevt->evt))
431 exynos4_mct_tick_stop(mevt); 440 exynos4_mct_tick_stop(mevt);
432 441
433 /* Clear the MCT tick interrupt */
434 if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1)
435 exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
436}
437
438static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
439{
440 struct mct_clock_event_device *mevt = dev_id;
441 struct clock_event_device *evt = &mevt->evt;
442
443 exynos4_mct_tick_clear(mevt); 442 exynos4_mct_tick_clear(mevt);
444 443
445 evt->event_handler(evt); 444 evt->event_handler(evt);
@@ -507,13 +506,12 @@ static int __init exynos4_timer_resources(struct device_node *np, void __iomem *
507 int err, cpu; 506 int err, cpu;
508 struct clk *mct_clk, *tick_clk; 507 struct clk *mct_clk, *tick_clk;
509 508
510 tick_clk = np ? of_clk_get_by_name(np, "fin_pll") : 509 tick_clk = of_clk_get_by_name(np, "fin_pll");
511 clk_get(NULL, "fin_pll");
512 if (IS_ERR(tick_clk)) 510 if (IS_ERR(tick_clk))
513 panic("%s: unable to determine tick clock rate\n", __func__); 511 panic("%s: unable to determine tick clock rate\n", __func__);
514 clk_rate = clk_get_rate(tick_clk); 512 clk_rate = clk_get_rate(tick_clk);
515 513
516 mct_clk = np ? of_clk_get_by_name(np, "mct") : clk_get(NULL, "mct"); 514 mct_clk = of_clk_get_by_name(np, "mct");
517 if (IS_ERR(mct_clk)) 515 if (IS_ERR(mct_clk))
518 panic("%s: unable to retrieve mct clock instance\n", __func__); 516 panic("%s: unable to retrieve mct clock instance\n", __func__);
519 clk_prepare_enable(mct_clk); 517 clk_prepare_enable(mct_clk);
@@ -562,7 +560,19 @@ static int __init exynos4_timer_resources(struct device_node *np, void __iomem *
562 return 0; 560 return 0;
563 561
564out_irq: 562out_irq:
565 free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick); 563 if (mct_int_type == MCT_INT_PPI) {
564 free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick);
565 } else {
566 for_each_possible_cpu(cpu) {
567 struct mct_clock_event_device *pcpu_mevt =
568 per_cpu_ptr(&percpu_mct_tick, cpu);
569
570 if (pcpu_mevt->evt.irq != -1) {
571 free_irq(pcpu_mevt->evt.irq, pcpu_mevt);
572 pcpu_mevt->evt.irq = -1;
573 }
574 }
575 }
566 return err; 576 return err;
567} 577}
568 578
@@ -581,11 +591,7 @@ static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
581 * timer irqs are specified after the four global timer 591 * timer irqs are specified after the four global timer
582 * irqs are specified. 592 * irqs are specified.
583 */ 593 */
584#ifdef CONFIG_OF
585 nr_irqs = of_irq_count(np); 594 nr_irqs = of_irq_count(np);
586#else
587 nr_irqs = 0;
588#endif
589 for (i = MCT_L0_IRQ; i < nr_irqs; i++) 595 for (i = MCT_L0_IRQ; i < nr_irqs; i++)
590 mct_irqs[i] = irq_of_parse_and_map(np, i); 596 mct_irqs[i] = irq_of_parse_and_map(np, i);
591 597
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/timer-cs5535.c
index 1de8cac99a0e..1de8cac99a0e 100644
--- a/drivers/clocksource/cs5535-clockevt.c
+++ b/drivers/clocksource/timer-cs5535.c
diff --git a/drivers/clocksource/pxa_timer.c b/drivers/clocksource/timer-pxa.c
index 395837938301..395837938301 100644
--- a/drivers/clocksource/pxa_timer.c
+++ b/drivers/clocksource/timer-pxa.c
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index 431892200a08..e8163693e936 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -95,13 +95,30 @@ static int __init riscv_timer_init_dt(struct device_node *n)
95 struct clocksource *cs; 95 struct clocksource *cs;
96 96
97 hartid = riscv_of_processor_hartid(n); 97 hartid = riscv_of_processor_hartid(n);
98 if (hartid < 0) {
99 pr_warn("Not valid hartid for node [%pOF] error = [%d]\n",
100 n, hartid);
101 return hartid;
102 }
103
98 cpuid = riscv_hartid_to_cpuid(hartid); 104 cpuid = riscv_hartid_to_cpuid(hartid);
105 if (cpuid < 0) {
106 pr_warn("Invalid cpuid for hartid [%d]\n", hartid);
107 return cpuid;
108 }
99 109
100 if (cpuid != smp_processor_id()) 110 if (cpuid != smp_processor_id())
101 return 0; 111 return 0;
102 112
113 pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
114 __func__, cpuid, hartid);
103 cs = per_cpu_ptr(&riscv_clocksource, cpuid); 115 cs = per_cpu_ptr(&riscv_clocksource, cpuid);
104 clocksource_register_hz(cs, riscv_timebase); 116 error = clocksource_register_hz(cs, riscv_timebase);
117 if (error) {
118 pr_err("RISCV timer register failed [%d] for cpu = [%d]\n",
119 error, cpuid);
120 return error;
121 }
105 122
106 sched_clock_register(riscv_sched_clock, 123 sched_clock_register(riscv_sched_clock,
107 BITS_PER_LONG, riscv_timebase); 124 BITS_PER_LONG, riscv_timebase);
@@ -110,8 +127,8 @@ static int __init riscv_timer_init_dt(struct device_node *n)
110 "clockevents/riscv/timer:starting", 127 "clockevents/riscv/timer:starting",
111 riscv_timer_starting_cpu, riscv_timer_dying_cpu); 128 riscv_timer_starting_cpu, riscv_timer_dying_cpu);
112 if (error) 129 if (error)
113 pr_err("RISCV timer register failed [%d] for cpu = [%d]\n", 130 pr_err("cpu hp setup state failed for RISCV timer [%d]\n",
114 error, cpuid); 131 error);
115 return error; 132 return error;
116} 133}
117 134
diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
index 3b56ea3f52af..552c5254390c 100644
--- a/drivers/clocksource/timer-sun5i.c
+++ b/drivers/clocksource/timer-sun5i.c
@@ -202,6 +202,11 @@ static int __init sun5i_setup_clocksource(struct device_node *node,
202 } 202 }
203 203
204 rate = clk_get_rate(clk); 204 rate = clk_get_rate(clk);
205 if (!rate) {
206 pr_err("Couldn't get parent clock rate\n");
207 ret = -EINVAL;
208 goto err_disable_clk;
209 }
205 210
206 cs->timer.base = base; 211 cs->timer.base = base;
207 cs->timer.clk = clk; 212 cs->timer.clk = clk;
@@ -275,6 +280,11 @@ static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem
275 } 280 }
276 281
277 rate = clk_get_rate(clk); 282 rate = clk_get_rate(clk);
283 if (!rate) {
284 pr_err("Couldn't get parent clock rate\n");
285 ret = -EINVAL;
286 goto err_disable_clk;
287 }
278 288
279 ce->timer.base = base; 289 ce->timer.base = base;
280 ce->timer.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); 290 ce->timer.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/timer-tango-xtal.c
index 3f94e454ef99..3f94e454ef99 100644
--- a/drivers/clocksource/tango_xtal.c
+++ b/drivers/clocksource/timer-tango-xtal.c
diff --git a/drivers/clocksource/timer-tegra20.c b/drivers/clocksource/timer-tegra20.c
index 4293943f4e2b..fdb3d795a409 100644
--- a/drivers/clocksource/timer-tegra20.c
+++ b/drivers/clocksource/timer-tegra20.c
@@ -15,21 +15,24 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/init.h> 18#include <linux/clk.h>
19#include <linux/clockchips.h>
20#include <linux/cpu.h>
21#include <linux/cpumask.h>
22#include <linux/delay.h>
19#include <linux/err.h> 23#include <linux/err.h>
20#include <linux/time.h>
21#include <linux/interrupt.h> 24#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/clockchips.h>
24#include <linux/clocksource.h>
25#include <linux/clk.h>
26#include <linux/io.h>
27#include <linux/of_address.h> 25#include <linux/of_address.h>
28#include <linux/of_irq.h> 26#include <linux/of_irq.h>
27#include <linux/percpu.h>
29#include <linux/sched_clock.h> 28#include <linux/sched_clock.h>
30#include <linux/delay.h> 29#include <linux/time.h>
30
31#include "timer-of.h"
31 32
33#ifdef CONFIG_ARM
32#include <asm/mach/time.h> 34#include <asm/mach/time.h>
35#endif
33 36
34#define RTC_SECONDS 0x08 37#define RTC_SECONDS 0x08
35#define RTC_SHADOW_SECONDS 0x0c 38#define RTC_SHADOW_SECONDS 0x0c
@@ -39,74 +42,161 @@
39#define TIMERUS_USEC_CFG 0x14 42#define TIMERUS_USEC_CFG 0x14
40#define TIMERUS_CNTR_FREEZE 0x4c 43#define TIMERUS_CNTR_FREEZE 0x4c
41 44
42#define TIMER1_BASE 0x0 45#define TIMER_PTV 0x0
43#define TIMER2_BASE 0x8 46#define TIMER_PTV_EN BIT(31)
44#define TIMER3_BASE 0x50 47#define TIMER_PTV_PER BIT(30)
45#define TIMER4_BASE 0x58 48#define TIMER_PCR 0x4
46 49#define TIMER_PCR_INTR_CLR BIT(30)
47#define TIMER_PTV 0x0 50
48#define TIMER_PCR 0x4 51#ifdef CONFIG_ARM
49 52#define TIMER_CPU0 0x50 /* TIMER3 */
53#else
54#define TIMER_CPU0 0x90 /* TIMER10 */
55#define TIMER10_IRQ_IDX 10
56#define IRQ_IDX_FOR_CPU(cpu) (TIMER10_IRQ_IDX + cpu)
57#endif
58#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
59
60static u32 usec_config;
50static void __iomem *timer_reg_base; 61static void __iomem *timer_reg_base;
62#ifdef CONFIG_ARM
51static void __iomem *rtc_base; 63static void __iomem *rtc_base;
52
53static struct timespec64 persistent_ts; 64static struct timespec64 persistent_ts;
54static u64 persistent_ms, last_persistent_ms; 65static u64 persistent_ms, last_persistent_ms;
55
56static struct delay_timer tegra_delay_timer; 66static struct delay_timer tegra_delay_timer;
57 67#endif
58#define timer_writel(value, reg) \
59 writel_relaxed(value, timer_reg_base + (reg))
60#define timer_readl(reg) \
61 readl_relaxed(timer_reg_base + (reg))
62 68
63static int tegra_timer_set_next_event(unsigned long cycles, 69static int tegra_timer_set_next_event(unsigned long cycles,
64 struct clock_event_device *evt) 70 struct clock_event_device *evt)
65{ 71{
66 u32 reg; 72 void __iomem *reg_base = timer_of_base(to_timer_of(evt));
67 73
68 reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0); 74 writel(TIMER_PTV_EN |
69 timer_writel(reg, TIMER3_BASE + TIMER_PTV); 75 ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
76 reg_base + TIMER_PTV);
70 77
71 return 0; 78 return 0;
72} 79}
73 80
74static inline void timer_shutdown(struct clock_event_device *evt) 81static int tegra_timer_shutdown(struct clock_event_device *evt)
75{ 82{
76 timer_writel(0, TIMER3_BASE + TIMER_PTV); 83 void __iomem *reg_base = timer_of_base(to_timer_of(evt));
84
85 writel(0, reg_base + TIMER_PTV);
86
87 return 0;
77} 88}
78 89
79static int tegra_timer_shutdown(struct clock_event_device *evt) 90static int tegra_timer_set_periodic(struct clock_event_device *evt)
80{ 91{
81 timer_shutdown(evt); 92 void __iomem *reg_base = timer_of_base(to_timer_of(evt));
93
94 writel(TIMER_PTV_EN | TIMER_PTV_PER |
95 ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
96 reg_base + TIMER_PTV);
97
82 return 0; 98 return 0;
83} 99}
84 100
85static int tegra_timer_set_periodic(struct clock_event_device *evt) 101static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
102{
103 struct clock_event_device *evt = (struct clock_event_device *)dev_id;
104 void __iomem *reg_base = timer_of_base(to_timer_of(evt));
105
106 writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
107 evt->event_handler(evt);
108
109 return IRQ_HANDLED;
110}
111
112static void tegra_timer_suspend(struct clock_event_device *evt)
113{
114 void __iomem *reg_base = timer_of_base(to_timer_of(evt));
115
116 writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
117}
118
119static void tegra_timer_resume(struct clock_event_device *evt)
120{
121 writel(usec_config, timer_reg_base + TIMERUS_USEC_CFG);
122}
123
124#ifdef CONFIG_ARM64
125static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
126 .flags = TIMER_OF_CLOCK | TIMER_OF_BASE,
127
128 .clkevt = {
129 .name = "tegra_timer",
130 .rating = 460,
131 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
132 .set_next_event = tegra_timer_set_next_event,
133 .set_state_shutdown = tegra_timer_shutdown,
134 .set_state_periodic = tegra_timer_set_periodic,
135 .set_state_oneshot = tegra_timer_shutdown,
136 .tick_resume = tegra_timer_shutdown,
137 .suspend = tegra_timer_suspend,
138 .resume = tegra_timer_resume,
139 },
140};
141
142static int tegra_timer_setup(unsigned int cpu)
86{ 143{
87 u32 reg = 0xC0000000 | ((1000000 / HZ) - 1); 144 struct timer_of *to = per_cpu_ptr(&tegra_to, cpu);
145
146 irq_force_affinity(to->clkevt.irq, cpumask_of(cpu));
147 enable_irq(to->clkevt.irq);
148
149 clockevents_config_and_register(&to->clkevt, timer_of_rate(to),
150 1, /* min */
151 0x1fffffff); /* 29 bits */
88 152
89 timer_shutdown(evt);
90 timer_writel(reg, TIMER3_BASE + TIMER_PTV);
91 return 0; 153 return 0;
92} 154}
93 155
94static struct clock_event_device tegra_clockevent = { 156static int tegra_timer_stop(unsigned int cpu)
95 .name = "timer0", 157{
96 .rating = 300, 158 struct timer_of *to = per_cpu_ptr(&tegra_to, cpu);
97 .features = CLOCK_EVT_FEAT_ONESHOT | 159
98 CLOCK_EVT_FEAT_PERIODIC | 160 to->clkevt.set_state_shutdown(&to->clkevt);
99 CLOCK_EVT_FEAT_DYNIRQ, 161 disable_irq_nosync(to->clkevt.irq);
100 .set_next_event = tegra_timer_set_next_event, 162
101 .set_state_shutdown = tegra_timer_shutdown, 163 return 0;
102 .set_state_periodic = tegra_timer_set_periodic, 164}
103 .set_state_oneshot = tegra_timer_shutdown, 165#else /* CONFIG_ARM */
104 .tick_resume = tegra_timer_shutdown, 166static struct timer_of tegra_to = {
167 .flags = TIMER_OF_CLOCK | TIMER_OF_BASE | TIMER_OF_IRQ,
168
169 .clkevt = {
170 .name = "tegra_timer",
171 .rating = 300,
172 .features = CLOCK_EVT_FEAT_ONESHOT |
173 CLOCK_EVT_FEAT_PERIODIC |
174 CLOCK_EVT_FEAT_DYNIRQ,
175 .set_next_event = tegra_timer_set_next_event,
176 .set_state_shutdown = tegra_timer_shutdown,
177 .set_state_periodic = tegra_timer_set_periodic,
178 .set_state_oneshot = tegra_timer_shutdown,
179 .tick_resume = tegra_timer_shutdown,
180 .suspend = tegra_timer_suspend,
181 .resume = tegra_timer_resume,
182 .cpumask = cpu_possible_mask,
183 },
184
185 .of_irq = {
186 .index = 2,
187 .flags = IRQF_TIMER | IRQF_TRIGGER_HIGH,
188 .handler = tegra_timer_isr,
189 },
105}; 190};
106 191
107static u64 notrace tegra_read_sched_clock(void) 192static u64 notrace tegra_read_sched_clock(void)
108{ 193{
109 return timer_readl(TIMERUS_CNTR_1US); 194 return readl(timer_reg_base + TIMERUS_CNTR_1US);
195}
196
197static unsigned long tegra_delay_timer_read_counter_long(void)
198{
199 return readl(timer_reg_base + TIMERUS_CNTR_1US);
110} 200}
111 201
112/* 202/*
@@ -143,100 +233,155 @@ static void tegra_read_persistent_clock64(struct timespec64 *ts)
143 timespec64_add_ns(&persistent_ts, delta * NSEC_PER_MSEC); 233 timespec64_add_ns(&persistent_ts, delta * NSEC_PER_MSEC);
144 *ts = persistent_ts; 234 *ts = persistent_ts;
145} 235}
236#endif
146 237
147static unsigned long tegra_delay_timer_read_counter_long(void) 238static int tegra_timer_common_init(struct device_node *np, struct timer_of *to)
148{
149 return readl(timer_reg_base + TIMERUS_CNTR_1US);
150}
151
152static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
153{
154 struct clock_event_device *evt = (struct clock_event_device *)dev_id;
155 timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
156 evt->event_handler(evt);
157 return IRQ_HANDLED;
158}
159
160static struct irqaction tegra_timer_irq = {
161 .name = "timer0",
162 .flags = IRQF_TIMER | IRQF_TRIGGER_HIGH,
163 .handler = tegra_timer_interrupt,
164 .dev_id = &tegra_clockevent,
165};
166
167static int __init tegra20_init_timer(struct device_node *np)
168{ 239{
169 struct clk *clk; 240 int ret = 0;
170 unsigned long rate;
171 int ret;
172
173 timer_reg_base = of_iomap(np, 0);
174 if (!timer_reg_base) {
175 pr_err("Can't map timer registers\n");
176 return -ENXIO;
177 }
178 241
179 tegra_timer_irq.irq = irq_of_parse_and_map(np, 2); 242 ret = timer_of_init(np, to);
180 if (tegra_timer_irq.irq <= 0) { 243 if (ret < 0)
181 pr_err("Failed to map timer IRQ\n"); 244 goto out;
182 return -EINVAL;
183 }
184 245
185 clk = of_clk_get(np, 0); 246 timer_reg_base = timer_of_base(to);
186 if (IS_ERR(clk)) {
187 pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
188 rate = 12000000;
189 } else {
190 clk_prepare_enable(clk);
191 rate = clk_get_rate(clk);
192 }
193 247
194 switch (rate) { 248 /*
249 * Configure microsecond timers to have 1MHz clock
250 * Config register is 0xqqww, where qq is "dividend", ww is "divisor"
251 * Uses n+1 scheme
252 */
253 switch (timer_of_rate(to)) {
195 case 12000000: 254 case 12000000:
196 timer_writel(0x000b, TIMERUS_USEC_CFG); 255 usec_config = 0x000b; /* (11+1)/(0+1) */
256 break;
257 case 12800000:
258 usec_config = 0x043f; /* (63+1)/(4+1) */
197 break; 259 break;
198 case 13000000: 260 case 13000000:
199 timer_writel(0x000c, TIMERUS_USEC_CFG); 261 usec_config = 0x000c; /* (12+1)/(0+1) */
262 break;
263 case 16800000:
264 usec_config = 0x0453; /* (83+1)/(4+1) */
200 break; 265 break;
201 case 19200000: 266 case 19200000:
202 timer_writel(0x045f, TIMERUS_USEC_CFG); 267 usec_config = 0x045f; /* (95+1)/(4+1) */
203 break; 268 break;
204 case 26000000: 269 case 26000000:
205 timer_writel(0x0019, TIMERUS_USEC_CFG); 270 usec_config = 0x0019; /* (25+1)/(0+1) */
271 break;
272 case 38400000:
273 usec_config = 0x04bf; /* (191+1)/(4+1) */
274 break;
275 case 48000000:
276 usec_config = 0x002f; /* (47+1)/(0+1) */
206 break; 277 break;
207 default: 278 default:
208 WARN(1, "Unknown clock rate"); 279 ret = -EINVAL;
280 goto out;
281 }
282
283 writel(usec_config, timer_of_base(to) + TIMERUS_USEC_CFG);
284
285out:
286 return ret;
287}
288
289#ifdef CONFIG_ARM64
290static int __init tegra_init_timer(struct device_node *np)
291{
292 int cpu, ret = 0;
293 struct timer_of *to;
294
295 to = this_cpu_ptr(&tegra_to);
296 ret = tegra_timer_common_init(np, to);
297 if (ret < 0)
298 goto out;
299
300 for_each_possible_cpu(cpu) {
301 struct timer_of *cpu_to;
302
303 cpu_to = per_cpu_ptr(&tegra_to, cpu);
304 cpu_to->of_base.base = timer_reg_base + TIMER_BASE_FOR_CPU(cpu);
305 cpu_to->of_clk.rate = timer_of_rate(to);
306 cpu_to->clkevt.cpumask = cpumask_of(cpu);
307 cpu_to->clkevt.irq =
308 irq_of_parse_and_map(np, IRQ_IDX_FOR_CPU(cpu));
309 if (!cpu_to->clkevt.irq) {
310 pr_err("%s: can't map IRQ for CPU%d\n",
311 __func__, cpu);
312 ret = -EINVAL;
313 goto out;
314 }
315
316 irq_set_status_flags(cpu_to->clkevt.irq, IRQ_NOAUTOEN);
317 ret = request_irq(cpu_to->clkevt.irq, tegra_timer_isr,
318 IRQF_TIMER | IRQF_NOBALANCING,
319 cpu_to->clkevt.name, &cpu_to->clkevt);
320 if (ret) {
321 pr_err("%s: cannot setup irq %d for CPU%d\n",
322 __func__, cpu_to->clkevt.irq, cpu);
323 ret = -EINVAL;
324 goto out_irq;
325 }
326 }
327
328 cpuhp_setup_state(CPUHP_AP_TEGRA_TIMER_STARTING,
329 "AP_TEGRA_TIMER_STARTING", tegra_timer_setup,
330 tegra_timer_stop);
331
332 return ret;
333out_irq:
334 for_each_possible_cpu(cpu) {
335 struct timer_of *cpu_to;
336
337 cpu_to = per_cpu_ptr(&tegra_to, cpu);
338 if (cpu_to->clkevt.irq) {
339 free_irq(cpu_to->clkevt.irq, &cpu_to->clkevt);
340 irq_dispose_mapping(cpu_to->clkevt.irq);
341 }
209 } 342 }
343out:
344 timer_of_cleanup(to);
345 return ret;
346}
347#else /* CONFIG_ARM */
348static int __init tegra_init_timer(struct device_node *np)
349{
350 int ret = 0;
351
352 ret = tegra_timer_common_init(np, &tegra_to);
353 if (ret < 0)
354 goto out;
210 355
211 sched_clock_register(tegra_read_sched_clock, 32, 1000000); 356 tegra_to.of_base.base = timer_reg_base + TIMER_BASE_FOR_CPU(0);
357 tegra_to.of_clk.rate = 1000000; /* microsecond timer */
212 358
359 sched_clock_register(tegra_read_sched_clock, 32,
360 timer_of_rate(&tegra_to));
213 ret = clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US, 361 ret = clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
214 "timer_us", 1000000, 300, 32, 362 "timer_us", timer_of_rate(&tegra_to),
215 clocksource_mmio_readl_up); 363 300, 32, clocksource_mmio_readl_up);
216 if (ret) { 364 if (ret) {
217 pr_err("Failed to register clocksource\n"); 365 pr_err("Failed to register clocksource\n");
218 return ret; 366 goto out;
219 } 367 }
220 368
221 tegra_delay_timer.read_current_timer = 369 tegra_delay_timer.read_current_timer =
222 tegra_delay_timer_read_counter_long; 370 tegra_delay_timer_read_counter_long;
223 tegra_delay_timer.freq = 1000000; 371 tegra_delay_timer.freq = timer_of_rate(&tegra_to);
224 register_current_timer_delay(&tegra_delay_timer); 372 register_current_timer_delay(&tegra_delay_timer);
225 373
226 ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq); 374 clockevents_config_and_register(&tegra_to.clkevt,
227 if (ret) { 375 timer_of_rate(&tegra_to),
228 pr_err("Failed to register timer IRQ: %d\n", ret); 376 0x1,
229 return ret; 377 0x1fffffff);
230 }
231 378
232 tegra_clockevent.cpumask = cpu_possible_mask; 379 return ret;
233 tegra_clockevent.irq = tegra_timer_irq.irq; 380out:
234 clockevents_config_and_register(&tegra_clockevent, 1000000, 381 timer_of_cleanup(&tegra_to);
235 0x1, 0x1fffffff);
236 382
237 return 0; 383 return ret;
238} 384}
239TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer);
240 385
241static int __init tegra20_init_rtc(struct device_node *np) 386static int __init tegra20_init_rtc(struct device_node *np)
242{ 387{
@@ -261,3 +406,6 @@ static int __init tegra20_init_rtc(struct device_node *np)
261 return register_persistent_clock(tegra_read_persistent_clock64); 406 return register_persistent_clock(tegra_read_persistent_clock64);
262} 407}
263TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc); 408TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
409#endif
410TIMER_OF_DECLARE(tegra210_timer, "nvidia,tegra210-timer", tegra_init_timer);
411TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra_init_timer);
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index fe4481676da6..a0b03443d8c1 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -76,6 +76,7 @@ config ARCH_TEGRA_210_SOC
76 select PINCTRL_TEGRA210 76 select PINCTRL_TEGRA210
77 select SOC_TEGRA_FLOWCTRL 77 select SOC_TEGRA_FLOWCTRL
78 select SOC_TEGRA_PMC 78 select SOC_TEGRA_PMC
79 select TEGRA_TIMER
79 help 80 help
80 Enable support for the NVIDIA Tegra210 SoC. Also known as Tegra X1, 81 Enable support for the NVIDIA Tegra210 SoC. Also known as Tegra X1,
81 the Tegra210 has four Cortex-A57 cores paired with four Cortex-A53 82 the Tegra210 has four Cortex-A57 cores paired with four Cortex-A53
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index fd586d0301e7..e78281d07b70 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -121,6 +121,7 @@ enum cpuhp_state {
121 CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING, 121 CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
122 CPUHP_AP_ARM_TWD_STARTING, 122 CPUHP_AP_ARM_TWD_STARTING,
123 CPUHP_AP_QCOM_TIMER_STARTING, 123 CPUHP_AP_QCOM_TIMER_STARTING,
124 CPUHP_AP_TEGRA_TIMER_STARTING,
124 CPUHP_AP_ARMADA_TIMER_STARTING, 125 CPUHP_AP_ARMADA_TIMER_STARTING,
125 CPUHP_AP_MARCO_TIMER_STARTING, 126 CPUHP_AP_MARCO_TIMER_STARTING,
126 CPUHP_AP_MIPS_GIC_TIMER_STARTING, 127 CPUHP_AP_MIPS_GIC_TIMER_STARTING,