Skip to content

Commit

Permalink
Merge tag 'timers-v5.18-rc1' of https://git.linaro.org/people/daniel.…
Browse files Browse the repository at this point in the history
…lezcano/linux into timers/core

Pull clocksource/events updates from Daniel Lezcano:

  - Fix return error code check for the timer-of layer when getting
    the base address (Guillaume Ranquet)

  - Remove MMIO dependency, add notrace annotation for sched_clock
    and increase the timer resolution for the Microchip
    PIT64b (Claudiu Beznea)

  - Convert DT bindings to yaml for the Tegra timer (David Heidelberg)

  - Fix compilation error on architecture other than ARM for the
    i.MX TPM (Nathan Chancellor)

  - Add support for the event stream scaling for 1GHz counter on
    the arch ARM timer (Marc Zyngier)

  - Support a higher number of interrupts by the Exynos MCT timer
    driver (Alim Akhtar)

  - Detect and prevent memory corruption when the specified number
    of interrupts in the DTS is greater than the array size in the
    code for the Exynos MCT timer (Krzysztof Kozlowski)

  - Fix regression from a previous errata fix on the TI DM
    timer (Drew Fustini)

  - Several fixes and code improvements for the i.MX TPM
    driver (Peng Fan)

Link: https://lore.kernel.org/all/a8cd9be9-7d70-80df-2b74-1a8226a215e1@linaro.org
  • Loading branch information
Thomas Gleixner committed Mar 14, 2022
2 parents 1f1893d + 4467b8b commit b166e52
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 134 deletions.
150 changes: 150 additions & 0 deletions Documentation/devicetree/bindings/timer/nvidia,tegra-timer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: "http://devicetree.org/schemas/timer/nvidia,tegra-timer.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: NVIDIA Tegra timer

maintainers:
- Stephen Warren <swarren@nvidia.com>

allOf:
- if:
properties:
compatible:
contains:
const: nvidia,tegra210-timer
then:
properties:
interrupts:
# Either a single combined interrupt or up to 14 individual interrupts
minItems: 1
maxItems: 14
description: >
A list of 14 interrupts; one per each timer channels 0 through 13
- if:
properties:
compatible:
oneOf:
- items:
- enum:
- nvidia,tegra114-timer
- nvidia,tegra124-timer
- nvidia,tegra132-timer
- const: nvidia,tegra30-timer
- items:
- const: nvidia,tegra30-timer
- const: nvidia,tegra20-timer
then:
properties:
interrupts:
# Either a single combined interrupt or up to 6 individual interrupts
minItems: 1
maxItems: 6
description: >
A list of 6 interrupts; one per each of timer channels 1 through 5,
and one for the shared interrupt for the remaining channels.
- if:
properties:
compatible:
const: nvidia,tegra20-timer
then:
properties:
interrupts:
# Either a single combined interrupt or up to 4 individual interrupts
minItems: 1
maxItems: 4
description: |
A list of 4 interrupts; one per timer channel.
properties:
compatible:
oneOf:
- const: nvidia,tegra210-timer
description: >
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.
- items:
- enum:
- nvidia,tegra114-timer
- nvidia,tegra124-timer
- nvidia,tegra132-timer
- const: nvidia,tegra30-timer
- items:
- const: nvidia,tegra30-timer
- const: nvidia,tegra20-timer
description: >
The Tegra30 timer provides ten 29-bit timer channels, a single 32-bit free
running counter, and 5 watchdog modules. The first two channels may also
trigger a legacy watchdog reset.
- const: nvidia,tegra20-timer
description: >
The Tegra20 timer provides four 29-bit timer channels and a single 32-bit free
running counter. The first two channels may also trigger a watchdog reset.
reg:
maxItems: 1

interrupts: true

clocks:
maxItems: 1

clock-names:
items:
- const: timer


required:
- compatible
- reg
- interrupts
- clocks

additionalProperties: false

examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
timer@60005000 {
compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
reg = <0x60005000 0x400>;
interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>,
<0 1 IRQ_TYPE_LEVEL_HIGH>,
<0 41 IRQ_TYPE_LEVEL_HIGH>,
<0 42 IRQ_TYPE_LEVEL_HIGH>,
<0 121 IRQ_TYPE_LEVEL_HIGH>,
<0 122 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car 214>;
};
- |
#include <dt-bindings/clock/tegra210-car.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
timer@60005000 {
compatible = "nvidia,tegra210-timer";
reg = <0x60005000 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";
};
24 changes: 0 additions & 24 deletions Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt

This file was deleted.

36 changes: 0 additions & 36 deletions Documentation/devicetree/bindings/timer/nvidia,tegra210-timer.txt

This file was deleted.

28 changes: 0 additions & 28 deletions Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt

This file was deleted.

5 changes: 2 additions & 3 deletions arch/arm/boot/dts/dra7-l4.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -3482,8 +3482,7 @@
ti,timer-pwm;
};
};

target-module@2c000 { /* 0x4882c000, ap 17 02.0 */
timer15_target: target-module@2c000 { /* 0x4882c000, ap 17 02.0 */
compatible = "ti,sysc-omap4-timer", "ti,sysc";
reg = <0x2c000 0x4>,
<0x2c010 0x4>;
Expand Down Expand Up @@ -3511,7 +3510,7 @@
};
};

target-module@2e000 { /* 0x4882e000, ap 19 14.0 */
timer16_target: target-module@2e000 { /* 0x4882e000, ap 19 14.0 */
compatible = "ti,sysc-omap4-timer", "ti,sysc";
reg = <0x2e000 0x4>,
<0x2e010 0x4>;
Expand Down
8 changes: 4 additions & 4 deletions arch/arm/boot/dts/dra7.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -1339,20 +1339,20 @@
};

/* Local timers, see ARM architected timer wrap erratum i940 */
&timer3_target {
&timer15_target {
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER3_CLKCTRL 24>;
assigned-clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER15_CLKCTRL 24>;
assigned-clock-parents = <&timer_sys_clk_div>;
};
};

&timer4_target {
&timer16_target {
ti,no-reset-on-init;
ti,no-idle;
timer@0 {
assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 24>;
assigned-clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER16_CLKCTRL 24>;
assigned-clock-parents = <&timer_sys_clk_div>;
};
};
1 change: 0 additions & 1 deletion drivers/clocksource/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,6 @@ config INGENIC_OST
config MICROCHIP_PIT64B
bool "Microchip PIT64B support"
depends on OF || COMPILE_TEST
select CLKSRC_MMIO
select TIMER_OF
help
This option enables Microchip PIT64B timer for Atmel
Expand Down
13 changes: 11 additions & 2 deletions drivers/clocksource/arm_arch_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -880,10 +880,19 @@ static void __arch_timer_setup(unsigned type,
clockevents_config_and_register(clk, arch_timer_rate, 0xf, max_delta);
}

static void arch_timer_evtstrm_enable(int divider)
static void arch_timer_evtstrm_enable(unsigned int divider)
{
u32 cntkctl = arch_timer_get_cntkctl();

#ifdef CONFIG_ARM64
/* ECV is likely to require a large divider. Use the EVNTIS flag. */
if (cpus_have_const_cap(ARM64_HAS_ECV) && divider > 15) {
cntkctl |= ARCH_TIMER_EVT_INTERVAL_SCALE;
divider -= 8;
}
#endif

divider = min(divider, 15U);
cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK;
/* Set the divider and enable virtual event stream */
cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT)
Expand Down Expand Up @@ -912,7 +921,7 @@ static void arch_timer_configure_evtstream(void)
lsb++;

/* enable event stream */
arch_timer_evtstrm_enable(max(0, min(lsb, 15)));
arch_timer_evtstrm_enable(max(0, lsb));
}

static void arch_counter_set_user_access(void)
Expand Down
39 changes: 21 additions & 18 deletions drivers/clocksource/exynos_mct.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,18 @@
#define MCT_CLKEVENTS_RATING 350
#endif

/* There are four Global timers starting with 0 offset */
#define MCT_G0_IRQ 0
/* Local timers count starts after global timer count */
#define MCT_L0_IRQ 4
/* Max number of IRQ as per DT binding document */
#define MCT_NR_IRQS 20

enum {
MCT_INT_SPI,
MCT_INT_PPI
};

enum {
MCT_G0_IRQ,
MCT_G1_IRQ,
MCT_G2_IRQ,
MCT_G3_IRQ,
MCT_L0_IRQ,
MCT_L1_IRQ,
MCT_L2_IRQ,
MCT_L3_IRQ,
MCT_L4_IRQ,
MCT_L5_IRQ,
MCT_L6_IRQ,
MCT_L7_IRQ,
MCT_NR_IRQS,
};

static void __iomem *reg_base;
static unsigned long clk_rate;
static unsigned int mct_int_type;
Expand All @@ -89,7 +80,11 @@ static int mct_irqs[MCT_NR_IRQS];
struct mct_clock_event_device {
struct clock_event_device evt;
unsigned long base;
char name[10];
/**
* The length of the name must be adjusted if number of
* local timer interrupts grow over two digits
*/
char name[11];
};

static void exynos4_mct_write(unsigned int value, unsigned long offset)
Expand Down Expand Up @@ -541,6 +536,11 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
* irqs are specified.
*/
nr_irqs = of_irq_count(np);
if (nr_irqs > ARRAY_SIZE(mct_irqs)) {
pr_err("exynos-mct: too many (%d) interrupts configured in DT\n",
nr_irqs);
nr_irqs = ARRAY_SIZE(mct_irqs);
}
for (i = MCT_L0_IRQ; i < nr_irqs; i++)
mct_irqs[i] = irq_of_parse_and_map(np, i);

Expand All @@ -553,11 +553,14 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
mct_irqs[MCT_L0_IRQ], err);
} else {
for_each_possible_cpu(cpu) {
int mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
int mct_irq;
struct mct_clock_event_device *pcpu_mevt =
per_cpu_ptr(&percpu_mct_tick, cpu);

pcpu_mevt->evt.irq = -1;
if (MCT_L0_IRQ + cpu >= ARRAY_SIZE(mct_irqs))
break;
mct_irq = mct_irqs[MCT_L0_IRQ + cpu];

irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
if (request_irq(mct_irq,
Expand Down
Loading

0 comments on commit b166e52

Please sign in to comment.