Skip to content

Commit

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

Pull clocksource/event updates from Daniel Lezcano:

  - Added DT bindings for Mediatek MT8188 (Johnson Wang)

  - Added DT bindings for Renesas r8a779f0 (Wolfram Sang)

  - Added support for RZ/V2L SoC (Lad Prabhakar)

  - Rename TIMER_IRQ_EN to TIMER_IRQ_CLEAR to prevent confusion on sun4i
    (Victor Hassan)

  - Added support for Exynos ARTPEC-8 MCT, including DT bindings
    (Vincent Whitchurch)

  - Fixed handling of ARM erratum 858921 on the ARM Arch timer (Kunkun
    Jiang)

  - Added missing call platform_device_put() in the error path on ther
    GXP timer (Lin Yujun)

  - Cleaned the timer TI DM driver by self-encapsulating the code,
    dropping dead code and simplifying some functions (Tony Lindgren)

  - Added a DT property to tell the driver the clock is no longer
    divided on recent NXP hardware (Peng Fan)

  - Fixed the CNTPCT_LO and CNTVCT_LO values in the ARM arch timer (Yang
    Guo)

Link: https://lore.kernel.org/r/b28ac4b0-5745-b3a9-b7e7-cc86dcb1b023@linaro.org
  • Loading branch information
Thomas Gleixner committed Oct 4, 2022
2 parents cceeeb6 + af246cc commit 6cb5ce1
Showing 13 changed files with 553 additions and 381 deletions.
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ Required properties:
For those SoCs that use SYST
* "mediatek,mt8183-timer" for MT8183 compatible timers (SYST)
* "mediatek,mt8186-timer" for MT8186 compatible timers (SYST)
* "mediatek,mt8188-timer" for MT8188 compatible timers (SYST)
* "mediatek,mt8192-timer" for MT8192 compatible timers (SYST)
* "mediatek,mt8195-timer" for MT8195 compatible timers (SYST)
* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/timer/nxp,sysctr-timer.yaml
Original file line number Diff line number Diff line change
@@ -32,6 +32,10 @@ properties:
clock-names:
const: per

nxp,no-divider:
description: if present, means there is no internal base clk divider.
type: boolean

required:
- compatible
- reg
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/timer/renesas,tmu.yaml
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ properties:
- renesas,tmu-r8a77990 # R-Car E3
- renesas,tmu-r8a77995 # R-Car D3
- renesas,tmu-r8a779a0 # R-Car V3U
- renesas,tmu-r8a779f0 # R-Car S4-8
- const: renesas,tmu

reg:
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ properties:
- samsung,exynos4412-mct
- items:
- enum:
- axis,artpec8-mct
- samsung,exynos3250-mct
- samsung,exynos5250-mct
- samsung,exynos5260-mct
@@ -45,6 +46,19 @@ properties:
reg:
maxItems: 1

samsung,frc-shared:
type: boolean
description: |
Indicates that the hardware requires that this processor share the
free-running counter with a different (main) processor.
samsung,local-timers:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 16
description: |
List of indices of local timers usable from this processor.
interrupts:
description: |
Interrupts should be put in specific order. This is, the local timer
@@ -74,6 +88,17 @@ required:
- reg

allOf:
- if:
not:
properties:
compatible:
contains:
enum:
- axis,artpec8-mct
then:
properties:
samsung,local-timers: false
samsung,frc-shared: false
- if:
properties:
compatible:
@@ -101,6 +126,7 @@ allOf:
compatible:
contains:
enum:
- axis,artpec8-mct
- samsung,exynos5260-mct
- samsung,exynos5420-mct
- samsung,exynos5433-mct
2 changes: 1 addition & 1 deletion drivers/clocksource/Kconfig
Original file line number Diff line number Diff line change
@@ -434,7 +434,7 @@ config ATMEL_TCB_CLKSRC
config CLKSRC_EXYNOS_MCT
bool "Exynos multi core timer driver" if COMPILE_TEST
depends on ARM || ARM64
depends on ARCH_EXYNOS || COMPILE_TEST
depends on ARCH_ARTPEC || ARCH_EXYNOS || COMPILE_TEST
help
Support for Multi Core Timer controller on Exynos SoCs.

6 changes: 4 additions & 2 deletions drivers/clocksource/arm_arch_timer.c
Original file line number Diff line number Diff line change
@@ -44,8 +44,8 @@
#define CNTACR_RWVT BIT(4)
#define CNTACR_RWPT BIT(5)

#define CNTVCT_LO 0x00
#define CNTPCT_LO 0x08
#define CNTPCT_LO 0x00
#define CNTVCT_LO 0x08
#define CNTFRQ 0x10
#define CNTP_CVAL_LO 0x20
#define CNTP_CTL 0x2c
@@ -473,6 +473,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
.desc = "ARM erratum 858921",
.read_cntpct_el0 = arm64_858921_read_cntpct_el0,
.read_cntvct_el0 = arm64_858921_read_cntvct_el0,
.set_next_event_phys = erratum_set_next_event_phys,
.set_next_event_virt = erratum_set_next_event_virt,
},
#endif
#ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
83 changes: 74 additions & 9 deletions drivers/clocksource/exynos_mct.c
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@
#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248)
#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C)
#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300)
#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x))
#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * (x)))
#define EXYNOS4_MCT_L_MASK (0xffffff00)

#define MCT_L_TCNTB_OFFSET (0x00)
@@ -66,6 +66,8 @@
#define MCT_L0_IRQ 4
/* Max number of IRQ as per DT binding document */
#define MCT_NR_IRQS 20
/* Max number of local timers */
#define MCT_NR_LOCAL (MCT_NR_IRQS - MCT_L0_IRQ)

enum {
MCT_INT_SPI,
@@ -233,9 +235,16 @@ static cycles_t exynos4_read_current_timer(void)
}
#endif

static int __init exynos4_clocksource_init(void)
static int __init exynos4_clocksource_init(bool frc_shared)
{
exynos4_mct_frc_start();
/*
* When the frc is shared, the main processer should have already
* turned it on and we shouldn't be writing to TCON.
*/
if (frc_shared)
mct_frc.resume = NULL;
else
exynos4_mct_frc_start();

#if defined(CONFIG_ARM)
exynos4_delay_timer.read_current_timer = &exynos4_read_current_timer;
@@ -449,7 +458,6 @@ static int exynos4_mct_starting_cpu(unsigned int cpu)
per_cpu_ptr(&percpu_mct_tick, cpu);
struct clock_event_device *evt = &mevt->evt;

mevt->base = EXYNOS4_MCT_L_BASE(cpu);
snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu);

evt->name = mevt->name;
@@ -520,8 +528,17 @@ static int __init exynos4_timer_resources(struct device_node *np)
return 0;
}

/**
* exynos4_timer_interrupts - initialize MCT interrupts
* @np: device node for MCT
* @int_type: interrupt type, MCT_INT_PPI or MCT_INT_SPI
* @local_idx: array mapping CPU numbers to local timer indices
* @nr_local: size of @local_idx array
*/
static int __init exynos4_timer_interrupts(struct device_node *np,
unsigned int int_type)
unsigned int int_type,
const u32 *local_idx,
size_t nr_local)
{
int nr_irqs, i, err, cpu;

@@ -554,13 +571,21 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
} else {
for_each_possible_cpu(cpu) {
int mct_irq;
unsigned int irq_idx;
struct mct_clock_event_device *pcpu_mevt =
per_cpu_ptr(&percpu_mct_tick, cpu);

if (cpu >= nr_local) {
err = -EINVAL;
goto out_irq;
}

irq_idx = MCT_L0_IRQ + local_idx[cpu];

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

irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
if (request_irq(mct_irq,
@@ -576,6 +601,17 @@ static int __init exynos4_timer_interrupts(struct device_node *np,
}
}

for_each_possible_cpu(cpu) {
struct mct_clock_event_device *mevt = per_cpu_ptr(&percpu_mct_tick, cpu);

if (cpu >= nr_local) {
err = -EINVAL;
goto out_irq;
}

mevt->base = EXYNOS4_MCT_L_BASE(local_idx[cpu]);
}

/* Install hotplug callbacks which configure the timer on this CPU */
err = cpuhp_setup_state(CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING,
"clockevents/exynos4/mct_timer:starting",
@@ -605,20 +641,49 @@ static int __init exynos4_timer_interrupts(struct device_node *np,

static int __init mct_init_dt(struct device_node *np, unsigned int int_type)
{
bool frc_shared = of_property_read_bool(np, "samsung,frc-shared");
u32 local_idx[MCT_NR_LOCAL] = {0};
int nr_local;
int ret;

nr_local = of_property_count_u32_elems(np, "samsung,local-timers");
if (nr_local == 0)
return -EINVAL;
if (nr_local > 0) {
if (nr_local > ARRAY_SIZE(local_idx))
return -EINVAL;

ret = of_property_read_u32_array(np, "samsung,local-timers",
local_idx, nr_local);
if (ret)
return ret;
} else {
int i;

nr_local = ARRAY_SIZE(local_idx);
for (i = 0; i < nr_local; i++)
local_idx[i] = i;
}

ret = exynos4_timer_resources(np);
if (ret)
return ret;

ret = exynos4_timer_interrupts(np, int_type);
ret = exynos4_timer_interrupts(np, int_type, local_idx, nr_local);
if (ret)
return ret;

ret = exynos4_clocksource_init();
ret = exynos4_clocksource_init(frc_shared);
if (ret)
return ret;

/*
* When the FRC is shared with a main processor, this secondary
* processor cannot use the global comparator.
*/
if (frc_shared)
return ret;

return exynos4_clockevent_init();
}

2 changes: 1 addition & 1 deletion drivers/clocksource/renesas-ostm.c
Original file line number Diff line number Diff line change
@@ -224,7 +224,7 @@ static int __init ostm_init(struct device_node *np)

TIMER_OF_DECLARE(ostm, "renesas,ostm", ostm_init);

#ifdef CONFIG_ARCH_R9A07G044
#ifdef CONFIG_ARCH_RZG2L
static int __init ostm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
7 changes: 6 additions & 1 deletion drivers/clocksource/timer-gxp.c
Original file line number Diff line number Diff line change
@@ -171,6 +171,7 @@ static int gxp_timer_probe(struct platform_device *pdev)
{
struct platform_device *gxp_watchdog_device;
struct device *dev = &pdev->dev;
int ret;

if (!gxp_timer) {
pr_err("Gxp Timer not initialized, cannot create watchdog");
@@ -187,7 +188,11 @@ static int gxp_timer_probe(struct platform_device *pdev)
gxp_watchdog_device->dev.platform_data = gxp_timer->counter;
gxp_watchdog_device->dev.parent = dev;

return platform_device_add(gxp_watchdog_device);
ret = platform_device_add(gxp_watchdog_device);
if (ret)
platform_device_put(gxp_watchdog_device);

return ret;
}

static const struct of_device_id gxp_timer_of_match[] = {
6 changes: 4 additions & 2 deletions drivers/clocksource/timer-imx-sysctr.c
Original file line number Diff line number Diff line change
@@ -134,8 +134,10 @@ static int __init sysctr_timer_init(struct device_node *np)
if (ret)
return ret;

/* system counter clock is divided by 3 internally */
to_sysctr.of_clk.rate /= SYS_CTR_CLK_DIV;
if (!of_property_read_bool(np, "nxp,no-divider")) {
/* system counter clock is divided by 3 internally */
to_sysctr.of_clk.rate /= SYS_CTR_CLK_DIV;
}

sys_ctr_base = timer_of_base(&to_sysctr);
cmpcr = readl(sys_ctr_base + CMPCR);
3 changes: 2 additions & 1 deletion drivers/clocksource/timer-sun4i.c
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@
#define TIMER_IRQ_EN_REG 0x00
#define TIMER_IRQ_EN(val) BIT(val)
#define TIMER_IRQ_ST_REG 0x04
#define TIMER_IRQ_CLEAR(val) BIT(val)
#define TIMER_CTL_REG(val) (0x10 * val + 0x10)
#define TIMER_CTL_ENABLE BIT(0)
#define TIMER_CTL_RELOAD BIT(1)
@@ -123,7 +124,7 @@ static int sun4i_clkevt_next_event(unsigned long evt,

static void sun4i_timer_clear_interrupt(void __iomem *base)
{
writel(TIMER_IRQ_EN(0), base + TIMER_IRQ_ST_REG);
writel(TIMER_IRQ_CLEAR(0), base + TIMER_IRQ_ST_REG);
}

static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id)
Loading

0 comments on commit 6cb5ce1

Please sign in to comment.