linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL] clockevents for 5.1
@ 2019-02-23 13:05 Daniel Lezcano
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
  0 siblings, 1 reply; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:05 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Anson Huang, Atish Patra, Biju Das, Chen-Yu Tsai, Daniel Lezcano,
	Joseph Lo, Krzysztof Kozlowski, Marek Szyprowski, Ryder Lee,
	Samuel Holland, Linux Kernel Mailing List


Hi Thomas,

this is a late pull request for clockevents 5.1.

 - 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)


Thanks!

  -- Daniel

-----------------------------------------------------------------

The following changes since commit 75b710af7139768fd4ba2d4e05335d2344796279:

  timers: Mark expected switch fall-throughs (2019-01-29 20:08:42 +0100)

are available in the Git repository at:

  https://git.linaro.org/people/daniel.lezcano/linux.git clockevents/5.1

for you to fetch changes up to f40f4fc9506d6b2b786920059b320aac3a831574:

  soc/tegra: default select TEGRA_TIMER for Tegra210 (2019-02-23
12:13:45 +0100)

----------------------------------------------------------------
Anson Huang (1):
      dt-bindings: timer: gpt: update binding doc

Atish Patra (1):
      clocksource/drivers/riscv: Add required checks during clock source
init

Biju Das (2):
      dt-bindings: timer: renesas, cmt: Document r8a774c0 CMT support
      dt-bindings: timer: renesas: tmu: Document r8a774c0 bindings

Chen-Yu Tsai (1):
      clocksource/drivers/sun5i: Fail gracefully when clock rate is
unavailable

Daniel Lezcano (3):
      clocksource/drivers/tango-xtal: Rename the file for consistency
      clocksource/drivers/timer-pxa: Rename the file for consistency
      clocksource/drivers/timer-cs5535: Rename the file for consistency

Joseph Lo (3):
      dt-bindings: timer: add Tegra210 timer
      clocksource/drivers/tegra: Add Tegra210 timer support
      soc/tegra: default select TEGRA_TIMER for Tegra210

Krzysztof Kozlowski (1):
      clocksource/drivers/exynos_mct: Remove unused header includes

Marek Szyprowski (2):
      clocksource/drivers/exynos_mct: Remove dead code
      clocksource/drivers/exynos_mct: Fix error path in timer resources
initialization

Ryder Lee (1):
      dt-bindings: timer: mediatek: update bindings for MT7629 SoC

Samuel Holland (1):
      clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer
instability

Stuart Menefy (2):
      clocksource/drivers/exynos_mct: Move one-shot check from tick
clear to ISR
      clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown

 Documentation/arm64/silicon-errata.txt                            |   2 +
 Documentation/devicetree/bindings/timer/fsl,imxgpt.txt            |  39
+++++--
 Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt    |  11 +-
 Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt |  36
+++++++
 Documentation/devicetree/bindings/timer/renesas,cmt.txt           |   2 +
 Documentation/devicetree/bindings/timer/renesas,tmu.txt           |   1 +
 drivers/clocksource/Kconfig                                       |  13 ++-
 drivers/clocksource/Makefile                                      |   6 +-
 drivers/clocksource/arm_arch_timer.c                              |  55
++++++++++
 drivers/clocksource/exynos_mct.c                                  |  48
+++++----
 drivers/clocksource/{cs5535-clockevt.c => timer-cs5535.c}         |   0
 drivers/clocksource/{pxa_timer.c => timer-pxa.c}                  |   0
 drivers/clocksource/timer-riscv.c                                 |  23
++++-
 drivers/clocksource/timer-sun5i.c                                 |  10 ++
 drivers/clocksource/{tango_xtal.c => timer-tango-xtal.c}          |   0
 drivers/clocksource/timer-tegra20.c                               | 370
++++++++++++++++++++++++++++++++++++++++++++++--------------------
 drivers/soc/tegra/Kconfig                                         |   1 +
 include/linux/cpuhotplug.h                                        |   1 +
 18 files changed, 470 insertions(+), 148 deletions(-)
 create mode 100644
Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt
 rename drivers/clocksource/{cs5535-clockevt.c => timer-cs5535.c} (100%)
 rename drivers/clocksource/{pxa_timer.c => timer-pxa.c} (100%)
 rename drivers/clocksource/{tango_xtal.c => timer-tango-xtal.c} (100%)


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable
  2019-02-23 13:05 [GIT PULL] clockevents for 5.1 Daniel Lezcano
@ 2019-02-23 13:06 ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 02/18] clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer instability Daniel Lezcano
                     ` (16 more replies)
  0 siblings, 17 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Chen-Yu Tsai, Maxime Ripard,
	moderated list:ARM/Allwinner sunXi SoC support

From: Chen-Yu Tsai <wens@csie.org>

If the clock tree is not fully populated when the timer-sun5i init code
is called, attempts to get the clock rate for the timer would fail and
return 0.

Make the init code for both clock events and clocksource check the
returned clock rate and fail gracefully if the result is 0, instead of
causing a divide by 0 exception later on.

Fixes: 4a59058f0b09 ("clocksource/drivers/sun5i: Refactor the current code")
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/timer-sun5i.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

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,
 	}
 
 	rate = clk_get_rate(clk);
+	if (!rate) {
+		pr_err("Couldn't get parent clock rate\n");
+		ret = -EINVAL;
+		goto err_disable_clk;
+	}
 
 	cs->timer.base = base;
 	cs->timer.clk = clk;
@@ -275,6 +280,11 @@ static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem
 	}
 
 	rate = clk_get_rate(clk);
+	if (!rate) {
+		pr_err("Couldn't get parent clock rate\n");
+		ret = -EINVAL;
+		goto err_disable_clk;
+	}
 
 	ce->timer.base = base;
 	ce->timer.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/18] clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer instability
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
       [not found]     ` <20190226212356.C6B68218A2@mail.kernel.org>
  2019-02-23 13:06   ` [PATCH 03/18] clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR Daniel Lezcano
                     ` (15 subsequent siblings)
  16 siblings, 1 reply; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Samuel Holland, stable, Maxime Ripard,
	Andre Przywara, Catalin Marinas, Will Deacon, Jonathan Corbet,
	Mark Rutland, Marc Zyngier,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list:DOCUMENTATION

From: Samuel Holland <samuel@sholland.org>

The Allwinner A64 SoC is known[1] to have an unstable architectural
timer, which manifests itself most obviously in the time jumping forward
a multiple of 95 years[2][3]. This coincides with 2^56 cycles at a
timer frequency of 24 MHz, implying that the time went slightly backward
(and this was interpreted by the kernel as it jumping forward and
wrapping around past the epoch).

Investigation revealed instability in the low bits of CNTVCT at the
point a high bit rolls over. This leads to power-of-two cycle forward
and backward jumps. (Testing shows that forward jumps are about twice as
likely as backward jumps.) Since the counter value returns to normal
after an indeterminate read, each "jump" really consists of both a
forward and backward jump from the software perspective.

Unless the kernel is trapping CNTVCT reads, a userspace program is able
to read the register in a loop faster than it changes. A test program
running on all 4 CPU cores that reported jumps larger than 100 ms was
run for 13.6 hours and reported the following:

 Count | Event
-------+---------------------------
  9940 | jumped backward      699ms
   268 | jumped backward     1398ms
     1 | jumped backward     2097ms
 16020 | jumped forward       175ms
  6443 | jumped forward       699ms
  2976 | jumped forward      1398ms
     9 | jumped forward    356516ms
     9 | jumped forward    357215ms
     4 | jumped forward    714430ms
     1 | jumped forward   3578440ms

This works out to a jump larger than 100 ms about every 5.5 seconds on
each CPU core.

The largest jump (almost an hour!) was the following sequence of reads:
    0x0000007fffffffff → 0x00000093feffffff → 0x0000008000000000

Note that the middle bits don't necessarily all read as all zeroes or
all ones during the anomalous behavior; however the low 10 bits checked
by the function in this patch have never been observed with any other
value.

Also note that smaller jumps are much more common, with backward jumps
of 2048 (2^11) cycles observed over 400 times per second on each core.
(Of course, this is partially explained by lower bits rolling over more
frequently.) Any one of these could have caused the 95 year time skip.

Similar anomalies were observed while reading CNTPCT (after patching the
kernel to allow reads from userspace). However, the CNTPCT jumps are
much less frequent, and only small jumps were observed. The same program
as before (except now reading CNTPCT) observed after 72 hours:

 Count | Event
-------+---------------------------
    17 | jumped backward      699ms
    52 | jumped forward       175ms
  2831 | jumped forward       699ms
     5 | jumped forward      1398ms

Further investigation showed that the instability in CNTPCT/CNTVCT also
affected the respective timer's TVAL register. The following values were
observed immediately after writing CNVT_TVAL to 0x10000000:

 CNTVCT             | CNTV_TVAL  | CNTV_CVAL          | CNTV_TVAL Error
--------------------+------------+--------------------+-----------------
 0x000000d4a2d8bfff | 0x10003fff | 0x000000d4b2d8bfff | +0x00004000
 0x000000d4a2d94000 | 0x0fffffff | 0x000000d4b2d97fff | -0x00004000
 0x000000d4a2d97fff | 0x10003fff | 0x000000d4b2d97fff | +0x00004000
 0x000000d4a2d9c000 | 0x0fffffff | 0x000000d4b2d9ffff | -0x00004000

The pattern of errors in CNTV_TVAL seemed to depend on exactly which
value was written to it. For example, after writing 0x10101010:

 CNTVCT             | CNTV_TVAL  | CNTV_CVAL          | CNTV_TVAL Error
--------------------+------------+--------------------+-----------------
 0x000001ac3effffff | 0x1110100f | 0x000001ac4f10100f | +0x1000000
 0x000001ac40000000 | 0x1010100f | 0x000001ac5110100f | -0x1000000
 0x000001ac58ffffff | 0x1110100f | 0x000001ac6910100f | +0x1000000
 0x000001ac66000000 | 0x1010100f | 0x000001ac7710100f | -0x1000000
 0x000001ac6affffff | 0x1110100f | 0x000001ac7b10100f | +0x1000000
 0x000001ac6e000000 | 0x1010100f | 0x000001ac7f10100f | -0x1000000

I was also twice able to reproduce the issue covered by Allwinner's
workaround[4], that writing to TVAL sometimes fails, and both CVAL and
TVAL are left with entirely bogus values. One was the following values:

 CNTVCT             | CNTV_TVAL  | CNTV_CVAL
--------------------+------------+--------------------------------------
 0x000000d4a2d6014c | 0x8fbd5721 | 0x000000d132935fff (615s in the past)
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>

========================================================================

Because the CPU can read the CNTPCT/CNTVCT registers faster than they
change, performing two reads of the register and comparing the high bits
(like other workarounds) is not a workable solution. And because the
timer can jump both forward and backward, no pair of reads can
distinguish a good value from a bad one. The only way to guarantee a
good value from consecutive reads would be to read _three_ times, and
take the middle value only if the three values are 1) each unique and
2) increasing. This takes at minimum 3 counter cycles (125 ns), or more
if an anomaly is detected.

However, since there is a distinct pattern to the bad values, we can
optimize the common case (1022/1024 of the time) to a single read by
simply ignoring values that match the error pattern. This still takes no
more than 3 cycles in the worst case, and requires much less code. As an
additional safety check, we still limit the loop iteration to the number
of max-frequency (1.2 GHz) CPU cycles in three 24 MHz counter periods.

For the TVAL registers, the simple solution is to not use them. Instead,
read or write the CVAL and calculate the TVAL value in software.

Although the manufacturer is aware of at least part of the erratum[4],
there is no official name for it. For now, use the kernel-internal name
"UNKNOWN1".

[1]: https://github.com/armbian/build/commit/a08cd6fe7ae9
[2]: https://forum.armbian.com/topic/3458-a64-datetime-clock-issue/
[3]: https://irclog.whitequark.org/linux-sunxi/2018-01-26
[4]: https://github.com/Allwinner-Homlet/H6-BSP4.9-linux/blob/master/drivers/clocksource/arm_arch_timer.c#L272

Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Samuel Holland <samuel@sholland.org>
Cc: stable@vger.kernel.org
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 Documentation/arm64/silicon-errata.txt |  2 +
 drivers/clocksource/Kconfig            | 10 +++++
 drivers/clocksource/arm_arch_timer.c   | 55 ++++++++++++++++++++++++++
 3 files changed, 67 insertions(+)

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.
 
 | Implementor    | Component       | Erratum ID      | Kconfig                     |
 +----------------+-----------------+-----------------+-----------------------------+
+| Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
+|                |                 |                 |                             |
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
 | ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069        |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..8dfd3bc448d0 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -360,6 +360,16 @@ config ARM64_ERRATUM_858921
 	  The workaround will be dynamically enabled when an affected
 	  core is detected.
 
+config SUN50I_ERRATUM_UNKNOWN1
+	bool "Workaround for Allwinner A64 erratum UNKNOWN1"
+	default y
+	depends on ARM_ARCH_TIMER && ARM64 && ARCH_SUNXI
+	select ARM_ARCH_TIMER_OOL_WORKAROUND
+	help
+	  This option enables a workaround for instability in the timer on
+	  the Allwinner A64 SoC. The workaround will only be active if the
+	  allwinner,erratum-unknown1 property is found in the timer node.
+
 config ARM_GLOBAL_TIMER
 	bool "Support for the ARM global timer" if COMPILE_TEST
 	select TIMER_OF if OF
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)
 }
 #endif
 
+#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
+/*
+ * The low bits of the counter registers are indeterminate while bit 10 or
+ * greater is rolling over. Since the counter value can jump both backward
+ * (7ff -> 000 -> 800) and forward (7ff -> fff -> 800), ignore register values
+ * with all ones or all zeros in the low bits. Bound the loop by the maximum
+ * number of CPU cycles in 3 consecutive 24 MHz counter periods.
+ */
+#define __sun50i_a64_read_reg(reg) ({					\
+	u64 _val;							\
+	int _retries = 150;						\
+									\
+	do {								\
+		_val = read_sysreg(reg);				\
+		_retries--;						\
+	} while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries);	\
+									\
+	WARN_ON_ONCE(!_retries);					\
+	_val;								\
+})
+
+static u64 notrace sun50i_a64_read_cntpct_el0(void)
+{
+	return __sun50i_a64_read_reg(cntpct_el0);
+}
+
+static u64 notrace sun50i_a64_read_cntvct_el0(void)
+{
+	return __sun50i_a64_read_reg(cntvct_el0);
+}
+
+static u32 notrace sun50i_a64_read_cntp_tval_el0(void)
+{
+	return read_sysreg(cntp_cval_el0) - sun50i_a64_read_cntpct_el0();
+}
+
+static u32 notrace sun50i_a64_read_cntv_tval_el0(void)
+{
+	return read_sysreg(cntv_cval_el0) - sun50i_a64_read_cntvct_el0();
+}
+#endif
+
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround);
 EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
@@ -423,6 +465,19 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
 		.read_cntvct_el0 = arm64_1188873_read_cntvct_el0,
 	},
 #endif
+#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
+	{
+		.match_type = ate_match_dt,
+		.id = "allwinner,erratum-unknown1",
+		.desc = "Allwinner erratum UNKNOWN1",
+		.read_cntp_tval_el0 = sun50i_a64_read_cntp_tval_el0,
+		.read_cntv_tval_el0 = sun50i_a64_read_cntv_tval_el0,
+		.read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
+		.read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
+		.set_next_event_phys = erratum_set_next_event_tval_phys,
+		.set_next_event_virt = erratum_set_next_event_tval_virt,
+	},
+#endif
 };
 
 typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/18] clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 02/18] clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer instability Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 04/18] clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown Daniel Lezcano
                     ` (14 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Stuart Menefy, stable, Marek Szyprowski,
	Kukjin Kim, Krzysztof Kozlowski,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES

From: Stuart Menefy <stuart.menefy@mathembedded.com>

When a timer tick occurs and the clock is in one-shot mode, the timer
needs to be stopped to prevent it triggering subsequent interrupts.
Currently this code is in exynos4_mct_tick_clear(), but as it is
only needed when an ISR occurs move it into exynos4_mct_tick_isr(),
leaving exynos4_mct_tick_clear() just doing what its name suggests it
should.

Signed-off-by: Stuart Menefy <stuart.menefy@mathembedded.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: stable@vger.kernel.org # v4.3+
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/exynos_mct.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 7a244b681876..1e325f89d408 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -388,6 +388,13 @@ static void exynos4_mct_tick_start(unsigned long cycles,
 	exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
 }
 
+static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
+{
+	/* Clear the MCT tick interrupt */
+	if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1)
+		exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
+}
+
 static int exynos4_tick_set_next_event(unsigned long cycles,
 				       struct clock_event_device *evt)
 {
@@ -420,8 +427,11 @@ static int set_state_periodic(struct clock_event_device *evt)
 	return 0;
 }
 
-static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
+static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
 {
+	struct mct_clock_event_device *mevt = dev_id;
+	struct clock_event_device *evt = &mevt->evt;
+
 	/*
 	 * This is for supporting oneshot mode.
 	 * Mct would generate interrupt periodically
@@ -430,16 +440,6 @@ static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
 	if (!clockevent_state_periodic(&mevt->evt))
 		exynos4_mct_tick_stop(mevt);
 
-	/* Clear the MCT tick interrupt */
-	if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1)
-		exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
-}
-
-static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
-{
-	struct mct_clock_event_device *mevt = dev_id;
-	struct clock_event_device *evt = &mevt->evt;
-
 	exynos4_mct_tick_clear(mevt);
 
 	evt->event_handler(evt);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/18] clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 02/18] clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer instability Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 03/18] clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 05/18] dt-bindings: timer: renesas, cmt: Document r8a774c0 CMT support Daniel Lezcano
                     ` (13 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Stuart Menefy, stable, Marek Szyprowski,
	Kukjin Kim, Krzysztof Kozlowski,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES

From: Stuart Menefy <stuart.menefy@mathembedded.com>

When shutting down the timer, ensure that after we have stopped the
timer any pending interrupts are cleared. This fixes a problem when
suspending, as interrupts are disabled before the timer is stopped,
so the timer interrupt may still be asserted, preventing the system
entering a low power state when the wfi is executed.

Signed-off-by: Stuart Menefy <stuart.menefy@mathembedded.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: <stable@vger.kernel.org> # v4.3+
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/exynos_mct.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 1e325f89d408..d55c30f6981d 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -411,6 +411,7 @@ static int set_state_shutdown(struct clock_event_device *evt)
 
 	mevt = container_of(evt, struct mct_clock_event_device, evt);
 	exynos4_mct_tick_stop(mevt);
+	exynos4_mct_tick_clear(mevt);
 	return 0;
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/18] dt-bindings: timer: renesas, cmt: Document r8a774c0 CMT support
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (2 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 04/18] clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 06/18] dt-bindings: timer: renesas: tmu: Document r8a774c0 bindings Daniel Lezcano
                     ` (12 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Biju Das, Rob Herring, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

From: Biju Das <biju.das@bp.renesas.com>

Document SoC specific bindings for RZ/G2E (r8a774c0) SoC.

Signed-off-by: Biju Das <biju.das@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 Documentation/devicetree/bindings/timer/renesas,cmt.txt | 2 ++
 1 file changed, 2 insertions(+)

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:
     - "renesas,r8a77470-cmt1" for the 48-bit CMT1 device included in r8a77470.
     - "renesas,r8a774a1-cmt0" for the 32-bit CMT0 device included in r8a774a1.
     - "renesas,r8a774a1-cmt1" for the 48-bit CMT1 device included in r8a774a1.
+    - "renesas,r8a774c0-cmt0" for the 32-bit CMT0 device included in r8a774c0.
+    - "renesas,r8a774c0-cmt1" for the 48-bit CMT1 device included in r8a774c0.
     - "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790.
     - "renesas,r8a7790-cmt1" for the 48-bit CMT1 device included in r8a7790.
     - "renesas,r8a7791-cmt0" for the 32-bit CMT0 device included in r8a7791.
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/18] dt-bindings: timer: renesas: tmu: Document r8a774c0 bindings
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (3 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 05/18] dt-bindings: timer: renesas, cmt: Document r8a774c0 CMT support Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 07/18] clocksource/drivers/riscv: Add required checks during clock source init Daniel Lezcano
                     ` (11 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Biju Das, Rob Herring, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

From: Biju Das <biju.das@bp.renesas.com>

Document RZ/G2E (R8A774C0) SoC in the Renesas TMU bindings.

Signed-off-by: Biju Das <biju.das@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 Documentation/devicetree/bindings/timer/renesas,tmu.txt | 1 +
 1 file changed, 1 insertion(+)

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:
 
   - compatible: must contain one or more of the following:
     - "renesas,tmu-r8a7740" for the r8a7740 TMU
+    - "renesas,tmu-r8a774c0" for the r8a774C0 TMU
     - "renesas,tmu-r8a7778" for the r8a7778 TMU
     - "renesas,tmu-r8a7779" for the r8a7779 TMU
     - "renesas,tmu-r8a77970" for the r8a77970 TMU
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/18] clocksource/drivers/riscv: Add required checks during clock source init
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (4 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 06/18] dt-bindings: timer: renesas: tmu: Document r8a774c0 bindings Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 08/18] clocksource/drivers/exynos_mct: Remove dead code Daniel Lezcano
                     ` (10 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Atish Patra, Palmer Dabbelt, Albert Ou,
	Paul Walmsley, open list:RISC-V ARCHITECTURE

From: Atish Patra <atish.patra@wdc.com>

Currently, clocksource registration happens for an invalid cpu for
non-smp kernels. This lead to kernel panic as cpu hotplug registration
will fail for those cpus. Moreover, riscv_hartid_to_cpuid can return
errors now.

Do not proceed if hartid or cpuid is invalid. Take this opportunity to
print appropriate error strings for different failure cases.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/timer-riscv.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

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)
 	struct clocksource *cs;
 
 	hartid = riscv_of_processor_hartid(n);
+	if (hartid < 0) {
+		pr_warn("Not valid hartid for node [%pOF] error = [%d]\n",
+			n, hartid);
+		return hartid;
+	}
+
 	cpuid = riscv_hartid_to_cpuid(hartid);
+	if (cpuid < 0) {
+		pr_warn("Invalid cpuid for hartid [%d]\n", hartid);
+		return cpuid;
+	}
 
 	if (cpuid != smp_processor_id())
 		return 0;
 
+	pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
+	       __func__, cpuid, hartid);
 	cs = per_cpu_ptr(&riscv_clocksource, cpuid);
-	clocksource_register_hz(cs, riscv_timebase);
+	error = clocksource_register_hz(cs, riscv_timebase);
+	if (error) {
+		pr_err("RISCV timer register failed [%d] for cpu = [%d]\n",
+		       error, cpuid);
+		return error;
+	}
 
 	sched_clock_register(riscv_sched_clock,
 			BITS_PER_LONG, riscv_timebase);
@@ -110,8 +127,8 @@ static int __init riscv_timer_init_dt(struct device_node *n)
 			 "clockevents/riscv/timer:starting",
 			 riscv_timer_starting_cpu, riscv_timer_dying_cpu);
 	if (error)
-		pr_err("RISCV timer register failed [%d] for cpu = [%d]\n",
-		       error, cpuid);
+		pr_err("cpu hp setup state failed for RISCV timer [%d]\n",
+		       error);
 	return error;
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/18] clocksource/drivers/exynos_mct: Remove dead code
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (5 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 07/18] clocksource/drivers/riscv: Add required checks during clock source init Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 09/18] clocksource/drivers/exynos_mct: Fix error path in timer resources initialization Daniel Lezcano
                     ` (9 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Marek Szyprowski, Kukjin Kim, Krzysztof Kozlowski,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES

From: Marek Szyprowski <m.szyprowski@samsung.com>

Exynos Multi-Core Timer driver is used only on device-tree based
systems, so remove non-dt related code. In case of !CONFIG_OF
the code is anyway equal because of_irq_count() has a stub
returning 0. Device node pointer is always provided when driver
has been probed from device tree.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/exynos_mct.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index d55c30f6981d..647ea9fc752f 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -508,13 +508,12 @@ static int __init exynos4_timer_resources(struct device_node *np, void __iomem *
 	int err, cpu;
 	struct clk *mct_clk, *tick_clk;
 
-	tick_clk = np ? of_clk_get_by_name(np, "fin_pll") :
-				clk_get(NULL, "fin_pll");
+	tick_clk = of_clk_get_by_name(np, "fin_pll");
 	if (IS_ERR(tick_clk))
 		panic("%s: unable to determine tick clock rate\n", __func__);
 	clk_rate = clk_get_rate(tick_clk);
 
-	mct_clk = np ? of_clk_get_by_name(np, "mct") : clk_get(NULL, "mct");
+	mct_clk = of_clk_get_by_name(np, "mct");
 	if (IS_ERR(mct_clk))
 		panic("%s: unable to retrieve mct clock instance\n", __func__);
 	clk_prepare_enable(mct_clk);
@@ -582,11 +581,7 @@ static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
 	 * timer irqs are specified after the four global timer
 	 * irqs are specified.
 	 */
-#ifdef CONFIG_OF
 	nr_irqs = of_irq_count(np);
-#else
-	nr_irqs = 0;
-#endif
 	for (i = MCT_L0_IRQ; i < nr_irqs; i++)
 		mct_irqs[i] = irq_of_parse_and_map(np, i);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/18] clocksource/drivers/exynos_mct: Fix error path in timer resources initialization
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (6 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 08/18] clocksource/drivers/exynos_mct: Remove dead code Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 10/18] dt-bindings: timer: mediatek: update bindings for MT7629 SoC Daniel Lezcano
                     ` (8 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Marek Szyprowski, Krzysztof Kozlowski, Kukjin Kim,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES

From: Marek Szyprowski <m.szyprowski@samsung.com>

While freeing interrupt handlers in error path, don't assume that all
requested interrupts are per-processor interrupts and properly release
standard interrupts too.

Reported-by: Krzysztof Kozlowski <krzk@kernel.org>
Fixes: 56a94f13919c ("clocksource: exynos_mct: Avoid blocking calls in the cpu hotplug notifier")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/exynos_mct.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 647ea9fc752f..33e90c080877 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -562,7 +562,19 @@ static int __init exynos4_timer_resources(struct device_node *np, void __iomem *
 	return 0;
 
 out_irq:
-	free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick);
+	if (mct_int_type == MCT_INT_PPI) {
+		free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick);
+	} else {
+		for_each_possible_cpu(cpu) {
+			struct mct_clock_event_device *pcpu_mevt =
+				per_cpu_ptr(&percpu_mct_tick, cpu);
+
+			if (pcpu_mevt->evt.irq != -1) {
+				free_irq(pcpu_mevt->evt.irq, pcpu_mevt);
+				pcpu_mevt->evt.irq = -1;
+			}
+		}
+	}
 	return err;
 }
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/18] dt-bindings: timer: mediatek: update bindings for MT7629 SoC
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (7 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 09/18] clocksource/drivers/exynos_mct: Fix error path in timer resources initialization Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:06   ` [PATCH 11/18] clocksource/drivers/exynos_mct: Remove unused header includes Daniel Lezcano
                     ` (7 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Ryder Lee, Rob Herring, Mark Rutland,
	Matthias Brugger,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/Mediatek SoC support,
	moderated list:ARM/Mediatek SoC support

From: Ryder Lee <ryder.lee@mediatek.com>

Update the binding for MT7629 SoC, which uses fallback compatible to
MT6765 SYST, so add more descriptions to distinguish it from the other
SoCs that use GPT.

Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 .../devicetree/bindings/timer/mediatek,mtk-timer.txt  | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

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 @@
-Mediatek Timers
+MediaTek Timers
 ---------------
 
-Mediatek SoCs have two different timers on different platforms,
+MediaTek SoCs have two different timers on different platforms,
 - GPT (General Purpose Timer)
 - SYST (System Timer)
 
@@ -9,6 +9,7 @@ The proper timer will be selected automatically by driver.
 
 Required properties:
 - compatible should contain:
+	For those SoCs that use GPT
 	* "mediatek,mt2701-timer" for MT2701 compatible timers (GPT)
 	* "mediatek,mt6580-timer" for MT6580 compatible timers (GPT)
 	* "mediatek,mt6589-timer" for MT6589 compatible timers (GPT)
@@ -17,7 +18,11 @@ Required properties:
 	* "mediatek,mt8135-timer" for MT8135 compatible timers (GPT)
 	* "mediatek,mt8173-timer" for MT8173 compatible timers (GPT)
 	* "mediatek,mt6577-timer" for MT6577 and all above compatible timers (GPT)
-	* "mediatek,mt6765-timer" for MT6765 compatible timers (SYST)
+
+	For those SoCs that use SYST
+	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
+	* "mediatek,mt6765-timer" for MT6765 and all above compatible timers (SYST)
+
 - reg: Should contain location and length for timer register.
 - clocks: Should contain system clock.
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/18] clocksource/drivers/exynos_mct: Remove unused header includes
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (8 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 10/18] dt-bindings: timer: mediatek: update bindings for MT7629 SoC Daniel Lezcano
@ 2019-02-23 13:06   ` Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 12/18] dt-bindings: timer: gpt: update binding doc Daniel Lezcano
                     ` (6 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:06 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Krzysztof Kozlowski, Kukjin Kim,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES,
	moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES

From: Krzysztof Kozlowski <krzk@kernel.org>

The driver does not use sched.h and platform_device.h.

Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/exynos_mct.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 33e90c080877..34bd250d46c6 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -10,14 +10,12 @@
  * published by the Free Software Foundation.
 */
 
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/cpu.h>
-#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/percpu.h>
 #include <linux/of.h>
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 12/18] dt-bindings: timer: gpt: update binding doc
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (9 preceding siblings ...)
  2019-02-23 13:06   ` [PATCH 11/18] clocksource/drivers/exynos_mct: Remove unused header includes Daniel Lezcano
@ 2019-02-23 13:07   ` Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 13/18] clocksource/drivers/tango-xtal: Rename the file for consistency Daniel Lezcano
                     ` (5 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:07 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Anson Huang, Anson Huang, Rob Herring,
	Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

From: Anson Huang <anson.huang@nxp.com>

The i.MX GPT timer driver binding doc is out of date,
update it according to current GPT timer driver.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 .../devicetree/bindings/timer/fsl,imxgpt.txt  | 39 ++++++++++++++++---
 1 file changed, 33 insertions(+), 6 deletions(-)

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)
 
 Required properties:
 
-- compatible : should be "fsl,<soc>-gpt"
-- reg : Specifies base physical address and size of the registers.
-- interrupts : A list of 4 interrupts; one per timer channel.
-- clocks : The clocks provided by the SoC to drive the timer.
+- compatible : should be one of following:
+  for i.MX1:
+  - "fsl,imx1-gpt";
+  for i.MX21:
+  - "fsl,imx21-gpt";
+  for i.MX27:
+  - "fsl,imx27-gpt", "fsl,imx21-gpt";
+  for i.MX31:
+  - "fsl,imx31-gpt";
+  for i.MX25:
+  - "fsl,imx25-gpt", "fsl,imx31-gpt";
+  for i.MX50:
+  - "fsl,imx50-gpt", "fsl,imx31-gpt";
+  for i.MX51:
+  - "fsl,imx51-gpt", "fsl,imx31-gpt";
+  for i.MX53:
+  - "fsl,imx53-gpt", "fsl,imx31-gpt";
+  for i.MX6Q:
+  - "fsl,imx6q-gpt", "fsl,imx31-gpt";
+  for i.MX6DL:
+  - "fsl,imx6dl-gpt";
+  for i.MX6SL:
+  - "fsl,imx6sl-gpt", "fsl,imx6dl-gpt";
+  for i.MX6SX:
+  - "fsl,imx6sx-gpt", "fsl,imx6dl-gpt";
+- reg : specifies base physical address and size of the registers.
+- interrupts : should be the gpt interrupt.
+- clocks : the clocks provided by the SoC to drive the timer, must contain
+           an entry for each entry in clock-names.
+- clock-names : must include "ipg" entry first, then "per" entry.
 
 Example:
 
 gpt1: timer@10003000 {
-	compatible = "fsl,imx27-gpt", "fsl,imx1-gpt";
+	compatible = "fsl,imx27-gpt", "fsl,imx21-gpt";
 	reg = <0x10003000 0x1000>;
 	interrupts = <26>;
-	clocks = <&clks 46>, <&clks 61>;
+	clocks = <&clks IMX27_CLK_GPT1_IPG_GATE>,
+		 <&clks IMX27_CLK_PER1_GATE>;
 	clock-names = "ipg", "per";
 };
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 13/18] clocksource/drivers/tango-xtal: Rename the file for consistency
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (10 preceding siblings ...)
  2019-02-23 13:07   ` [PATCH 12/18] dt-bindings: timer: gpt: update binding doc Daniel Lezcano
@ 2019-02-23 13:07   ` Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 14/18] clocksource/drivers/timer-pxa: " Daniel Lezcano
                     ` (4 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:07 UTC (permalink / raw)
  To: tglx; +Cc: linux-kernel

For the sake of consistency, let's rename the file to a name similar
to other file names in this directory.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/Makefile                             | 2 +-
 drivers/clocksource/{tango_xtal.c => timer-tango-xtal.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/clocksource/{tango_xtal.c => timer-tango-xtal.c} (100%)

diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..47052ea15f20 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -69,7 +69,7 @@ obj-$(CONFIG_KEYSTONE_TIMER)		+= timer-keystone.o
 obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= timer-integrator-ap.o
 obj-$(CONFIG_CLKSRC_VERSATILE)		+= timer-versatile.o
 obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
-obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= tango_xtal.o
+obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= timer-tango-xtal.o
 obj-$(CONFIG_CLKSRC_IMX_GPT)		+= timer-imx-gpt.o
 obj-$(CONFIG_CLKSRC_IMX_TPM)		+= timer-imx-tpm.o
 obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
diff --git a/drivers/clocksource/tango_xtal.c b/drivers/clocksource/timer-tango-xtal.c
similarity index 100%
rename from drivers/clocksource/tango_xtal.c
rename to drivers/clocksource/timer-tango-xtal.c
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 14/18] clocksource/drivers/timer-pxa: Rename the file for consistency
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (11 preceding siblings ...)
  2019-02-23 13:07   ` [PATCH 13/18] clocksource/drivers/tango-xtal: Rename the file for consistency Daniel Lezcano
@ 2019-02-23 13:07   ` Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 15/18] clocksource/drivers/timer-cs5535: " Daniel Lezcano
                     ` (3 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:07 UTC (permalink / raw)
  To: tglx; +Cc: linux-kernel

For the sake of consistency, let's rename the file to a name similar
to other file names in this directory.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/Makefile                     | 2 +-
 drivers/clocksource/{pxa_timer.c => timer-pxa.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/clocksource/{pxa_timer.c => timer-pxa.c} (100%)

diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 47052ea15f20..a9e7c642ecce 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -29,7 +29,7 @@ obj-$(CONFIG_BCM2835_TIMER)	+= bcm2835_timer.o
 obj-$(CONFIG_CLPS711X_TIMER)	+= clps711x-timer.o
 obj-$(CONFIG_ATLAS7_TIMER)	+= timer-atlas7.o
 obj-$(CONFIG_MXS_TIMER)		+= mxs_timer.o
-obj-$(CONFIG_CLKSRC_PXA)	+= pxa_timer.o
+obj-$(CONFIG_CLKSRC_PXA)	+= timer-pxa.o
 obj-$(CONFIG_PRIMA2_TIMER)	+= timer-prima2.o
 obj-$(CONFIG_U300_TIMER)	+= timer-u300.o
 obj-$(CONFIG_SUN4I_TIMER)	+= timer-sun4i.o
diff --git a/drivers/clocksource/pxa_timer.c b/drivers/clocksource/timer-pxa.c
similarity index 100%
rename from drivers/clocksource/pxa_timer.c
rename to drivers/clocksource/timer-pxa.c
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 15/18] clocksource/drivers/timer-cs5535: Rename the file for consistency
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (12 preceding siblings ...)
  2019-02-23 13:07   ` [PATCH 14/18] clocksource/drivers/timer-pxa: " Daniel Lezcano
@ 2019-02-23 13:07   ` Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 16/18] dt-bindings: timer: add Tegra210 timer Daniel Lezcano
                     ` (2 subsequent siblings)
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:07 UTC (permalink / raw)
  To: tglx; +Cc: linux-kernel

For the sake of consistency, let's rename the file to a name similar
to other file names in this directory.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/Makefile                              | 2 +-
 drivers/clocksource/{cs5535-clockevt.c => timer-cs5535.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/clocksource/{cs5535-clockevt.c => timer-cs5535.c} (100%)

diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index a9e7c642ecce..c4a8e9ef932a 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_ATMEL_ST)		+= timer-atmel-st.o
 obj-$(CONFIG_ATMEL_TCB_CLKSRC)	+= tcb_clksrc.o
 obj-$(CONFIG_X86_PM_TIMER)	+= acpi_pm.o
 obj-$(CONFIG_SCx200HR_TIMER)	+= scx200_hrt.o
-obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC)	+= cs5535-clockevt.o
+obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC)	+= timer-cs5535.o
 obj-$(CONFIG_CLKSRC_JCORE_PIT)		+= jcore-pit.o
 obj-$(CONFIG_SH_TIMER_CMT)	+= sh_cmt.o
 obj-$(CONFIG_SH_TIMER_MTU2)	+= sh_mtu2.o
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/timer-cs5535.c
similarity index 100%
rename from drivers/clocksource/cs5535-clockevt.c
rename to drivers/clocksource/timer-cs5535.c
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 16/18] dt-bindings: timer: add Tegra210 timer
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (13 preceding siblings ...)
  2019-02-23 13:07   ` [PATCH 15/18] clocksource/drivers/timer-cs5535: " Daniel Lezcano
@ 2019-02-23 13:07   ` Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 17/18] clocksource/drivers/tegra: Add Tegra210 timer support Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 18/18] soc/tegra: default select TEGRA_TIMER for Tegra210 Daniel Lezcano
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:07 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Joseph Lo, devicetree, Jon Hunter, Rob Herring,
	Mark Rutland, Thierry Reding,
	open list:TEGRA ARCHITECTURE SUPPORT

From: Joseph Lo <josephl@nvidia.com>

The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
(TMR10-TMR13). Each TMR can be programmed to generate one-shot periodic,
or watchdog interrupts.

Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Cc: devicetree@vger.kernel.org
Signed-off-by: Joseph Lo <josephl@nvidia.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 .../bindings/timer/nvidia,tegra210-timer.txt  | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

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 @@
+NVIDIA Tegra210 timer
+
+The Tegra210 timer provides fourteen 29-bit timer counters and one 32-bit
+timestamp counter. The TMRs run at either a fixed 1 MHz clock rate derived
+from the oscillator clock (TMR0-TMR9) or directly at the oscillator clock
+(TMR10-TMR13). Each TMR can be programmed to generate one-shot, periodic,
+or watchdog interrupts.
+
+Required properties:
+- compatible : "nvidia,tegra210-timer".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : A list of 14 interrupts; one per each timer channels 0 through
+  13.
+- clocks : Must contain one entry, for the module clock.
+  See ../clocks/clock-bindings.txt for details.
+
+timer@60005000 {
+	compatible = "nvidia,tegra210-timer";
+	reg = <0x0 0x60005000 0x0 0x400>;
+	interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&tegra_car TEGRA210_CLK_TIMER>;
+	clock-names = "timer";
+};
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 17/18] clocksource/drivers/tegra: Add Tegra210 timer support
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (14 preceding siblings ...)
  2019-02-23 13:07   ` [PATCH 16/18] dt-bindings: timer: add Tegra210 timer Daniel Lezcano
@ 2019-02-23 13:07   ` Daniel Lezcano
  2019-02-23 13:07   ` [PATCH 18/18] soc/tegra: default select TEGRA_TIMER for Tegra210 Daniel Lezcano
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:07 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Joseph Lo, Thierry Reding, Jon Hunter,
	Thierry Reding, Palmer Dabbelt, Peter Zijlstra, Will Deacon,
	James Hogan, Lucas Stach, Guo Ren, Hoan Tran, Arnd Bergmann,
	open list:TEGRA ARCHITECTURE SUPPORT

From: Joseph Lo <josephl@nvidia.com>

Add support for the Tegra210 timer that runs at oscillator clock
(TMR10-TMR13). We need these timers to work as clock event device and to
replace the ARMv8 architected timer due to it can't survive across the
power cycle of the CPU core or CPUPORESET signal. So it can't be a wake-up
source when CPU suspends in power down state.

Also convert the original driver to use timer-of API.

Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Joseph Lo <josephl@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/Kconfig         |   3 +-
 drivers/clocksource/timer-tegra20.c | 370 +++++++++++++++++++---------
 include/linux/cpuhotplug.h          |   1 +
 3 files changed, 262 insertions(+), 112 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8dfd3bc448d0..5d93e580e5dc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -131,7 +131,8 @@ config SUN5I_HSTIMER
 config TEGRA_TIMER
 	bool "Tegra timer driver" if COMPILE_TEST
 	select CLKSRC_MMIO
-	depends on ARM
+	select TIMER_OF
+	depends on ARM || ARM64
 	help
 	  Enables support for the Tegra driver.
 
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 @@
  *
  */
 
-#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
 #include <linux/err.h>
-#include <linux/time.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/clockchips.h>
-#include <linux/clocksource.h>
-#include <linux/clk.h>
-#include <linux/io.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/percpu.h>
 #include <linux/sched_clock.h>
-#include <linux/delay.h>
+#include <linux/time.h>
+
+#include "timer-of.h"
 
+#ifdef CONFIG_ARM
 #include <asm/mach/time.h>
+#endif
 
 #define RTC_SECONDS            0x08
 #define RTC_SHADOW_SECONDS     0x0c
@@ -39,74 +42,161 @@
 #define TIMERUS_USEC_CFG 0x14
 #define TIMERUS_CNTR_FREEZE 0x4c
 
-#define TIMER1_BASE 0x0
-#define TIMER2_BASE 0x8
-#define TIMER3_BASE 0x50
-#define TIMER4_BASE 0x58
-
-#define TIMER_PTV 0x0
-#define TIMER_PCR 0x4
-
+#define TIMER_PTV		0x0
+#define TIMER_PTV_EN		BIT(31)
+#define TIMER_PTV_PER		BIT(30)
+#define TIMER_PCR		0x4
+#define TIMER_PCR_INTR_CLR	BIT(30)
+
+#ifdef CONFIG_ARM
+#define TIMER_CPU0		0x50 /* TIMER3 */
+#else
+#define TIMER_CPU0		0x90 /* TIMER10 */
+#define TIMER10_IRQ_IDX		10
+#define IRQ_IDX_FOR_CPU(cpu)	(TIMER10_IRQ_IDX + cpu)
+#endif
+#define TIMER_BASE_FOR_CPU(cpu) (TIMER_CPU0 + (cpu) * 8)
+
+static u32 usec_config;
 static void __iomem *timer_reg_base;
+#ifdef CONFIG_ARM
 static void __iomem *rtc_base;
-
 static struct timespec64 persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
-
 static struct delay_timer tegra_delay_timer;
-
-#define timer_writel(value, reg) \
-	writel_relaxed(value, timer_reg_base + (reg))
-#define timer_readl(reg) \
-	readl_relaxed(timer_reg_base + (reg))
+#endif
 
 static int tegra_timer_set_next_event(unsigned long cycles,
 					 struct clock_event_device *evt)
 {
-	u32 reg;
+	void __iomem *reg_base = timer_of_base(to_timer_of(evt));
 
-	reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
-	timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+	writel(TIMER_PTV_EN |
+	       ((cycles > 1) ? (cycles - 1) : 0), /* n+1 scheme */
+	       reg_base + TIMER_PTV);
 
 	return 0;
 }
 
-static inline void timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_shutdown(struct clock_event_device *evt)
 {
-	timer_writel(0, TIMER3_BASE + TIMER_PTV);
+	void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+	writel(0, reg_base + TIMER_PTV);
+
+	return 0;
 }
 
-static int tegra_timer_shutdown(struct clock_event_device *evt)
+static int tegra_timer_set_periodic(struct clock_event_device *evt)
 {
-	timer_shutdown(evt);
+	void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+	writel(TIMER_PTV_EN | TIMER_PTV_PER |
+	       ((timer_of_rate(to_timer_of(evt)) / HZ) - 1),
+	       reg_base + TIMER_PTV);
+
 	return 0;
 }
 
-static int tegra_timer_set_periodic(struct clock_event_device *evt)
+static irqreturn_t tegra_timer_isr(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+	void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+	writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static void tegra_timer_suspend(struct clock_event_device *evt)
+{
+	void __iomem *reg_base = timer_of_base(to_timer_of(evt));
+
+	writel(TIMER_PCR_INTR_CLR, reg_base + TIMER_PCR);
+}
+
+static void tegra_timer_resume(struct clock_event_device *evt)
+{
+	writel(usec_config, timer_reg_base + TIMERUS_USEC_CFG);
+}
+
+#ifdef CONFIG_ARM64
+static DEFINE_PER_CPU(struct timer_of, tegra_to) = {
+	.flags = TIMER_OF_CLOCK | TIMER_OF_BASE,
+
+	.clkevt = {
+		.name = "tegra_timer",
+		.rating = 460,
+		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+		.set_next_event = tegra_timer_set_next_event,
+		.set_state_shutdown = tegra_timer_shutdown,
+		.set_state_periodic = tegra_timer_set_periodic,
+		.set_state_oneshot = tegra_timer_shutdown,
+		.tick_resume = tegra_timer_shutdown,
+		.suspend = tegra_timer_suspend,
+		.resume = tegra_timer_resume,
+	},
+};
+
+static int tegra_timer_setup(unsigned int cpu)
 {
-	u32 reg = 0xC0000000 | ((1000000 / HZ) - 1);
+	struct timer_of *to = per_cpu_ptr(&tegra_to, cpu);
+
+	irq_force_affinity(to->clkevt.irq, cpumask_of(cpu));
+	enable_irq(to->clkevt.irq);
+
+	clockevents_config_and_register(&to->clkevt, timer_of_rate(to),
+					1, /* min */
+					0x1fffffff); /* 29 bits */
 
-	timer_shutdown(evt);
-	timer_writel(reg, TIMER3_BASE + TIMER_PTV);
 	return 0;
 }
 
-static struct clock_event_device tegra_clockevent = {
-	.name			= "timer0",
-	.rating			= 300,
-	.features		= CLOCK_EVT_FEAT_ONESHOT |
-				  CLOCK_EVT_FEAT_PERIODIC |
-				  CLOCK_EVT_FEAT_DYNIRQ,
-	.set_next_event		= tegra_timer_set_next_event,
-	.set_state_shutdown	= tegra_timer_shutdown,
-	.set_state_periodic	= tegra_timer_set_periodic,
-	.set_state_oneshot	= tegra_timer_shutdown,
-	.tick_resume		= tegra_timer_shutdown,
+static int tegra_timer_stop(unsigned int cpu)
+{
+	struct timer_of *to = per_cpu_ptr(&tegra_to, cpu);
+
+	to->clkevt.set_state_shutdown(&to->clkevt);
+	disable_irq_nosync(to->clkevt.irq);
+
+	return 0;
+}
+#else /* CONFIG_ARM */
+static struct timer_of tegra_to = {
+	.flags = TIMER_OF_CLOCK | TIMER_OF_BASE | TIMER_OF_IRQ,
+
+	.clkevt = {
+		.name = "tegra_timer",
+		.rating	= 300,
+		.features = CLOCK_EVT_FEAT_ONESHOT |
+			    CLOCK_EVT_FEAT_PERIODIC |
+			    CLOCK_EVT_FEAT_DYNIRQ,
+		.set_next_event	= tegra_timer_set_next_event,
+		.set_state_shutdown = tegra_timer_shutdown,
+		.set_state_periodic = tegra_timer_set_periodic,
+		.set_state_oneshot = tegra_timer_shutdown,
+		.tick_resume = tegra_timer_shutdown,
+		.suspend = tegra_timer_suspend,
+		.resume = tegra_timer_resume,
+		.cpumask = cpu_possible_mask,
+	},
+
+	.of_irq = {
+		.index = 2,
+		.flags = IRQF_TIMER | IRQF_TRIGGER_HIGH,
+		.handler = tegra_timer_isr,
+	},
 };
 
 static u64 notrace tegra_read_sched_clock(void)
 {
-	return timer_readl(TIMERUS_CNTR_1US);
+	return readl(timer_reg_base + TIMERUS_CNTR_1US);
+}
+
+static unsigned long tegra_delay_timer_read_counter_long(void)
+{
+	return readl(timer_reg_base + TIMERUS_CNTR_1US);
 }
 
 /*
@@ -143,100 +233,155 @@ static void tegra_read_persistent_clock64(struct timespec64 *ts)
 	timespec64_add_ns(&persistent_ts, delta * NSEC_PER_MSEC);
 	*ts = persistent_ts;
 }
+#endif
 
-static unsigned long tegra_delay_timer_read_counter_long(void)
-{
-	return readl(timer_reg_base + TIMERUS_CNTR_1US);
-}
-
-static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
-	timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
-	evt->event_handler(evt);
-	return IRQ_HANDLED;
-}
-
-static struct irqaction tegra_timer_irq = {
-	.name		= "timer0",
-	.flags		= IRQF_TIMER | IRQF_TRIGGER_HIGH,
-	.handler	= tegra_timer_interrupt,
-	.dev_id		= &tegra_clockevent,
-};
-
-static int __init tegra20_init_timer(struct device_node *np)
+static int tegra_timer_common_init(struct device_node *np, struct timer_of *to)
 {
-	struct clk *clk;
-	unsigned long rate;
-	int ret;
-
-	timer_reg_base = of_iomap(np, 0);
-	if (!timer_reg_base) {
-		pr_err("Can't map timer registers\n");
-		return -ENXIO;
-	}
+	int ret = 0;
 
-	tegra_timer_irq.irq = irq_of_parse_and_map(np, 2);
-	if (tegra_timer_irq.irq <= 0) {
-		pr_err("Failed to map timer IRQ\n");
-		return -EINVAL;
-	}
+	ret = timer_of_init(np, to);
+	if (ret < 0)
+		goto out;
 
-	clk = of_clk_get(np, 0);
-	if (IS_ERR(clk)) {
-		pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
-		rate = 12000000;
-	} else {
-		clk_prepare_enable(clk);
-		rate = clk_get_rate(clk);
-	}
+	timer_reg_base = timer_of_base(to);
 
-	switch (rate) {
+	/*
+	 * Configure microsecond timers to have 1MHz clock
+	 * Config register is 0xqqww, where qq is "dividend", ww is "divisor"
+	 * Uses n+1 scheme
+	 */
+	switch (timer_of_rate(to)) {
 	case 12000000:
-		timer_writel(0x000b, TIMERUS_USEC_CFG);
+		usec_config = 0x000b; /* (11+1)/(0+1) */
+		break;
+	case 12800000:
+		usec_config = 0x043f; /* (63+1)/(4+1) */
 		break;
 	case 13000000:
-		timer_writel(0x000c, TIMERUS_USEC_CFG);
+		usec_config = 0x000c; /* (12+1)/(0+1) */
+		break;
+	case 16800000:
+		usec_config = 0x0453; /* (83+1)/(4+1) */
 		break;
 	case 19200000:
-		timer_writel(0x045f, TIMERUS_USEC_CFG);
+		usec_config = 0x045f; /* (95+1)/(4+1) */
 		break;
 	case 26000000:
-		timer_writel(0x0019, TIMERUS_USEC_CFG);
+		usec_config = 0x0019; /* (25+1)/(0+1) */
+		break;
+	case 38400000:
+		usec_config = 0x04bf; /* (191+1)/(4+1) */
+		break;
+	case 48000000:
+		usec_config = 0x002f; /* (47+1)/(0+1) */
 		break;
 	default:
-		WARN(1, "Unknown clock rate");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	writel(usec_config, timer_of_base(to) + TIMERUS_USEC_CFG);
+
+out:
+	return ret;
+}
+
+#ifdef CONFIG_ARM64
+static int __init tegra_init_timer(struct device_node *np)
+{
+	int cpu, ret = 0;
+	struct timer_of *to;
+
+	to = this_cpu_ptr(&tegra_to);
+	ret = tegra_timer_common_init(np, to);
+	if (ret < 0)
+		goto out;
+
+	for_each_possible_cpu(cpu) {
+		struct timer_of *cpu_to;
+
+		cpu_to = per_cpu_ptr(&tegra_to, cpu);
+		cpu_to->of_base.base = timer_reg_base + TIMER_BASE_FOR_CPU(cpu);
+		cpu_to->of_clk.rate = timer_of_rate(to);
+		cpu_to->clkevt.cpumask = cpumask_of(cpu);
+		cpu_to->clkevt.irq =
+			irq_of_parse_and_map(np, IRQ_IDX_FOR_CPU(cpu));
+		if (!cpu_to->clkevt.irq) {
+			pr_err("%s: can't map IRQ for CPU%d\n",
+			       __func__, cpu);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		irq_set_status_flags(cpu_to->clkevt.irq, IRQ_NOAUTOEN);
+		ret = request_irq(cpu_to->clkevt.irq, tegra_timer_isr,
+				  IRQF_TIMER | IRQF_NOBALANCING,
+				  cpu_to->clkevt.name, &cpu_to->clkevt);
+		if (ret) {
+			pr_err("%s: cannot setup irq %d for CPU%d\n",
+				__func__, cpu_to->clkevt.irq, cpu);
+			ret = -EINVAL;
+			goto out_irq;
+		}
+	}
+
+	cpuhp_setup_state(CPUHP_AP_TEGRA_TIMER_STARTING,
+			  "AP_TEGRA_TIMER_STARTING", tegra_timer_setup,
+			  tegra_timer_stop);
+
+	return ret;
+out_irq:
+	for_each_possible_cpu(cpu) {
+		struct timer_of *cpu_to;
+
+		cpu_to = per_cpu_ptr(&tegra_to, cpu);
+		if (cpu_to->clkevt.irq) {
+			free_irq(cpu_to->clkevt.irq, &cpu_to->clkevt);
+			irq_dispose_mapping(cpu_to->clkevt.irq);
+		}
 	}
+out:
+	timer_of_cleanup(to);
+	return ret;
+}
+#else /* CONFIG_ARM */
+static int __init tegra_init_timer(struct device_node *np)
+{
+	int ret = 0;
+
+	ret = tegra_timer_common_init(np, &tegra_to);
+	if (ret < 0)
+		goto out;
 
-	sched_clock_register(tegra_read_sched_clock, 32, 1000000);
+	tegra_to.of_base.base = timer_reg_base + TIMER_BASE_FOR_CPU(0);
+	tegra_to.of_clk.rate = 1000000; /* microsecond timer */
 
+	sched_clock_register(tegra_read_sched_clock, 32,
+			     timer_of_rate(&tegra_to));
 	ret = clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
-				    "timer_us", 1000000, 300, 32,
-				    clocksource_mmio_readl_up);
+				    "timer_us", timer_of_rate(&tegra_to),
+				    300, 32, clocksource_mmio_readl_up);
 	if (ret) {
 		pr_err("Failed to register clocksource\n");
-		return ret;
+		goto out;
 	}
 
 	tegra_delay_timer.read_current_timer =
 			tegra_delay_timer_read_counter_long;
-	tegra_delay_timer.freq = 1000000;
+	tegra_delay_timer.freq = timer_of_rate(&tegra_to);
 	register_current_timer_delay(&tegra_delay_timer);
 
-	ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
-	if (ret) {
-		pr_err("Failed to register timer IRQ: %d\n", ret);
-		return ret;
-	}
+	clockevents_config_and_register(&tegra_to.clkevt,
+					timer_of_rate(&tegra_to),
+					0x1,
+					0x1fffffff);
 
-	tegra_clockevent.cpumask = cpu_possible_mask;
-	tegra_clockevent.irq = tegra_timer_irq.irq;
-	clockevents_config_and_register(&tegra_clockevent, 1000000,
-					0x1, 0x1fffffff);
+	return ret;
+out:
+	timer_of_cleanup(&tegra_to);
 
-	return 0;
+	return ret;
 }
-TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer);
 
 static int __init tegra20_init_rtc(struct device_node *np)
 {
@@ -261,3 +406,6 @@ static int __init tegra20_init_rtc(struct device_node *np)
 	return register_persistent_clock(tegra_read_persistent_clock64);
 }
 TIMER_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
+#endif
+TIMER_OF_DECLARE(tegra210_timer, "nvidia,tegra210-timer", tegra_init_timer);
+TIMER_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra_init_timer);
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 {
 	CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
 	CPUHP_AP_ARM_TWD_STARTING,
 	CPUHP_AP_QCOM_TIMER_STARTING,
+	CPUHP_AP_TEGRA_TIMER_STARTING,
 	CPUHP_AP_ARMADA_TIMER_STARTING,
 	CPUHP_AP_MARCO_TIMER_STARTING,
 	CPUHP_AP_MIPS_GIC_TIMER_STARTING,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 18/18] soc/tegra: default select TEGRA_TIMER for Tegra210
  2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
                     ` (15 preceding siblings ...)
  2019-02-23 13:07   ` [PATCH 17/18] clocksource/drivers/tegra: Add Tegra210 timer support Daniel Lezcano
@ 2019-02-23 13:07   ` Daniel Lezcano
  16 siblings, 0 replies; 20+ messages in thread
From: Daniel Lezcano @ 2019-02-23 13:07 UTC (permalink / raw)
  To: tglx
  Cc: linux-kernel, Joseph Lo, Thierry Reding, Jon Hunter,
	Thierry Reding, Mikko Perttunen,
	open list:TEGRA ARCHITECTURE SUPPORT

From: Joseph Lo <josephl@nvidia.com>

The tegra timer is necessary for Tegra210 to support CPU idle power-down
state. So select it by default.

Signed-off-by: Joseph Lo <josephl@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/soc/tegra/Kconfig | 1 +
 1 file changed, 1 insertion(+)

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
 	select PINCTRL_TEGRA210
 	select SOC_TEGRA_FLOWCTRL
 	select SOC_TEGRA_PMC
+	select TEGRA_TIMER
 	help
 	  Enable support for the NVIDIA Tegra210 SoC. Also known as Tegra X1,
 	  the Tegra210 has four Cortex-A57 cores paired with four Cortex-A53
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 02/18] clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer instability
       [not found]     ` <20190226212356.C6B68218A2@mail.kernel.org>
@ 2019-02-27  2:55       ` Samuel Holland
  0 siblings, 0 replies; 20+ messages in thread
From: Samuel Holland @ 2019-02-27  2:55 UTC (permalink / raw)
  To: Sasha Levin, Daniel Lezcano, tglx; +Cc: linux-kernel, stable

On 02/26/19 15:23, Sasha Levin wrote:
> Hi,
> 
> [This is an automated email]
> 
> This commit has been processed because it contains a -stable tag.
> The stable tag indicates that it's relevant for the following trees: all
> 
> The bot has tested the following trees: v4.20.12, v4.19.25, v4.14.103, v4.9.160, v4.4.176, v3.18.136.
> 
<snip/>
> 
> How should we proceed with this patch?

This patch is actually only applicable to 4.14.y and newer. It doesn't apply
cleanly because fa8d815fac96 was not backported to 4.14 or 4.19. fa8d815fac96 is
not a dependency, so the extra part of the hunk just needs to be removed.
(Should I send a rebased version somewhere?)

> --
> Thanks,
> Sasha

Cheers,
Samuel

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2019-02-27  2:55 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-23 13:05 [GIT PULL] clockevents for 5.1 Daniel Lezcano
2019-02-23 13:06 ` [PATCH 01/18] clocksource/drivers/sun5i: Fail gracefully when clock rate is unavailable Daniel Lezcano
2019-02-23 13:06   ` [PATCH 02/18] clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer instability Daniel Lezcano
     [not found]     ` <20190226212356.C6B68218A2@mail.kernel.org>
2019-02-27  2:55       ` Samuel Holland
2019-02-23 13:06   ` [PATCH 03/18] clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR Daniel Lezcano
2019-02-23 13:06   ` [PATCH 04/18] clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown Daniel Lezcano
2019-02-23 13:06   ` [PATCH 05/18] dt-bindings: timer: renesas, cmt: Document r8a774c0 CMT support Daniel Lezcano
2019-02-23 13:06   ` [PATCH 06/18] dt-bindings: timer: renesas: tmu: Document r8a774c0 bindings Daniel Lezcano
2019-02-23 13:06   ` [PATCH 07/18] clocksource/drivers/riscv: Add required checks during clock source init Daniel Lezcano
2019-02-23 13:06   ` [PATCH 08/18] clocksource/drivers/exynos_mct: Remove dead code Daniel Lezcano
2019-02-23 13:06   ` [PATCH 09/18] clocksource/drivers/exynos_mct: Fix error path in timer resources initialization Daniel Lezcano
2019-02-23 13:06   ` [PATCH 10/18] dt-bindings: timer: mediatek: update bindings for MT7629 SoC Daniel Lezcano
2019-02-23 13:06   ` [PATCH 11/18] clocksource/drivers/exynos_mct: Remove unused header includes Daniel Lezcano
2019-02-23 13:07   ` [PATCH 12/18] dt-bindings: timer: gpt: update binding doc Daniel Lezcano
2019-02-23 13:07   ` [PATCH 13/18] clocksource/drivers/tango-xtal: Rename the file for consistency Daniel Lezcano
2019-02-23 13:07   ` [PATCH 14/18] clocksource/drivers/timer-pxa: " Daniel Lezcano
2019-02-23 13:07   ` [PATCH 15/18] clocksource/drivers/timer-cs5535: " Daniel Lezcano
2019-02-23 13:07   ` [PATCH 16/18] dt-bindings: timer: add Tegra210 timer Daniel Lezcano
2019-02-23 13:07   ` [PATCH 17/18] clocksource/drivers/tegra: Add Tegra210 timer support Daniel Lezcano
2019-02-23 13:07   ` [PATCH 18/18] soc/tegra: default select TEGRA_TIMER for Tegra210 Daniel Lezcano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).