mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
A set of updates for clocksource and clockevent drivers:
- A fix for the prescaler of the ARM global timer where the prescaler mask define only covered 4 bits while it is actully 8 bits wide. This restricted obviously the possible range of the prescaler adjustments. - A fix for the RISC-V timer which prevents a timer interrupt being raised while the timer is initialized. - A set of device tree updates to support new system on chips in various drivers. - Kernel-doc and other cleanups all over the place. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmX/MDcTHHRnbHhAbGlu dXRyb25peC5kZQAKCRCmGPVMDXSYofUcD/9hZjJp11tNJNibLGjJrZUIg1Zpiu7c avlrG/KT9BgElyp8D4WG3GTY7ng9vzJ7XNXG5eXyrkMClzlDYmXt5oeoUM3KRFDg G/kX0ee/+vcP5IKVsYR3w1MQ7QGe7VfE5FU4CxtR3OjG3T5Gueim1AKBtM26QazK wHe1/yp0vIPjZO1awlWQm9CJ+DSD2Mb1oPo8c9Bitd5KXXjPg8uR3bk2kOVYMdzC B6xYvQWF3Pl7NXcQKOnIazqsNlphsYiBGc5ZbKp5zjDggmp/ChBedt6ePCccU3DO VXE6D4eyZ5hmQbFzSEZUYsWcNzkeH8ZWnxkjeAoG60Y2vErLVsceytaIja061VOl BP2j8QbQ7ztwLOTtZc8KwJsVfxBh1xhwAUwe5Mpl171m7K2n+zquR8Clq4SqL2DK mjUcHKIZzyhZ4HX3rRwVOpJmfbJlRxSRjiLp+oPulJBB9pLMjarxwQ6Ij68yrPst kVow4Ur45abmXsDRj3lc3+bDcfMr8AM3l/HjD7AZamC2TAvkp1hkYPghhazdolx5 qQA3swdQl0tq49SNvvLbVRjRiCiQmUdpOGpnevvqxEO/BESGquVfPrihOYqIQuwh +yurmba5L8uxpsBCPtGfiMse9fbE7GVQJkMqhr9KNNOfER30rEe8bmqr6r71+uZJ 19Jp2U76zNfVXA== =M9Gu -----END PGP SIGNATURE----- Merge tag 'timers-core-2024-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull more clocksource updates from Thomas Gleixner: "A set of updates for clocksource and clockevent drivers: - A fix for the prescaler of the ARM global timer where the prescaler mask define only covered 4 bits while it is actully 8 bits wide. This obviously restricted the possible range of prescaler adjustments - A fix for the RISC-V timer which prevents a timer interrupt being raised while the timer is initialized - A set of device tree updates to support new system on chips in various drivers - Kernel-doc and other cleanups all over the place" * tag 'timers-core-2024-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: clocksource/drivers/timer-riscv: Clear timer interrupt on timer initialization dt-bindings: timer: Add support for cadence TTC PWM clocksource/drivers/arm_global_timer: Simplify prescaler register access clocksource/drivers/arm_global_timer: Guard against division by zero clocksource/drivers/arm_global_timer: Make gt_target_rate unsigned long dt-bindings: timer: add Ralink SoCs system tick counter clocksource: arm_global_timer: fix non-kernel-doc comment clocksource/drivers/arm_global_timer: Remove stray tab clocksource/drivers/arm_global_timer: Fix maximum prescaler value clocksource/drivers/imx-sysctr: Add i.MX95 support clocksource/drivers/imx-sysctr: Drop use global variables dt-bindings: timer: nxp,sysctr-timer: support i.MX95 dt-bindings: timer: renesas: ostm: Document RZ/Five SoC dt-bindings: timer: renesas,tmu: Document input capture interrupt clocksource/drivers/ti-32K: Fix misuse of "/**" comment clocksource/drivers/stm32: Fix all kernel-doc warnings dt-bindings: timer: exynos4210-mct: Add google,gs101-mct compatible clocksource/drivers/imx: Fix -Wunused-but-set-variable warning
This commit is contained in:
commit
00164f477f
@ -32,12 +32,23 @@ properties:
|
||||
description: |
|
||||
Bit width of the timer, necessary if not 16.
|
||||
|
||||
"#pwm-cells":
|
||||
const: 3
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
not:
|
||||
required:
|
||||
- "#pwm-cells"
|
||||
then:
|
||||
required:
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
@ -50,3 +61,12 @@ examples:
|
||||
clocks = <&cpu_clk 3>;
|
||||
timer-width = <32>;
|
||||
};
|
||||
|
||||
- |
|
||||
pwm: pwm@f8002000 {
|
||||
compatible = "cdns,ttc";
|
||||
reg = <0xf8002000 0x1000>;
|
||||
clocks = <&cpu_clk 3>;
|
||||
timer-width = <32>;
|
||||
#pwm-cells = <3>;
|
||||
};
|
||||
|
@ -18,7 +18,9 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: nxp,sysctr-timer
|
||||
enum:
|
||||
- nxp,imx95-sysctr-timer
|
||||
- nxp,sysctr-timer
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -0,0 +1,38 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/ralink,cevt-systick.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: System tick counter present in Ralink family SoCs
|
||||
|
||||
maintainers:
|
||||
- Sergio Paracuellos <sergio.paracuellos@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ralink,cevt-systick
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
systick@d00 {
|
||||
compatible = "ralink,cevt-systick";
|
||||
reg = <0xd00 0x10>;
|
||||
|
||||
interrupt-parent = <&cpuintc>;
|
||||
interrupts = <7>;
|
||||
};
|
||||
...
|
@ -23,7 +23,7 @@ properties:
|
||||
- enum:
|
||||
- renesas,r7s72100-ostm # RZ/A1H
|
||||
- renesas,r7s9210-ostm # RZ/A2M
|
||||
- renesas,r9a07g043-ostm # RZ/G2UL
|
||||
- renesas,r9a07g043-ostm # RZ/G2UL and RZ/Five
|
||||
- renesas,r9a07g044-ostm # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-ostm # RZ/V2L
|
||||
- const: renesas,ostm # Generic
|
||||
|
@ -46,7 +46,19 @@ properties:
|
||||
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
items:
|
||||
- description: Underflow interrupt, channel 0
|
||||
- description: Underflow interrupt, channel 1
|
||||
- description: Underflow interrupt, channel 2
|
||||
- description: Input capture interrupt, channel 2
|
||||
|
||||
interrupt-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: tuni0
|
||||
- const: tuni1
|
||||
- const: tuni2
|
||||
- const: ticpi2
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
@ -100,7 +112,9 @@ examples:
|
||||
reg = <0xffd80000 0x30>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
||||
<GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
|
||||
clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
|
||||
clock-names = "fck";
|
||||
power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
|
||||
|
@ -26,6 +26,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- axis,artpec8-mct
|
||||
- google,gs101-mct
|
||||
- samsung,exynos3250-mct
|
||||
- samsung,exynos5250-mct
|
||||
- samsung,exynos5260-mct
|
||||
@ -127,6 +128,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- axis,artpec8-mct
|
||||
- google,gs101-mct
|
||||
- samsung,exynos5260-mct
|
||||
- samsung,exynos5420-mct
|
||||
- samsung,exynos5433-mct
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpu.h>
|
||||
@ -31,10 +32,7 @@
|
||||
#define GT_CONTROL_COMP_ENABLE BIT(1) /* banked */
|
||||
#define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */
|
||||
#define GT_CONTROL_AUTO_INC BIT(3) /* banked */
|
||||
#define GT_CONTROL_PRESCALER_SHIFT 8
|
||||
#define GT_CONTROL_PRESCALER_MAX 0xF
|
||||
#define GT_CONTROL_PRESCALER_MASK (GT_CONTROL_PRESCALER_MAX << \
|
||||
GT_CONTROL_PRESCALER_SHIFT)
|
||||
#define GT_CONTROL_PRESCALER_MASK GENMASK(15, 8)
|
||||
|
||||
#define GT_INT_STATUS 0x0c
|
||||
#define GT_INT_STATUS_EVENT_FLAG BIT(0)
|
||||
@ -52,7 +50,8 @@
|
||||
*/
|
||||
static void __iomem *gt_base;
|
||||
static struct notifier_block gt_clk_rate_change_nb;
|
||||
static u32 gt_psv_new, gt_psv_bck, gt_target_rate;
|
||||
static u32 gt_psv_new, gt_psv_bck;
|
||||
static unsigned long gt_target_rate;
|
||||
static int gt_ppi;
|
||||
static struct clock_event_device __percpu *gt_evt;
|
||||
|
||||
@ -88,7 +87,7 @@ static u64 gt_counter_read(void)
|
||||
return _gt_counter_read();
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* To ensure that updates to comparator value register do not set the
|
||||
* Interrupt Status Register proceed as follows:
|
||||
* 1. Clear the Comp Enable bit in the Timer Control Register.
|
||||
@ -247,7 +246,7 @@ static void gt_write_presc(u32 psv)
|
||||
|
||||
reg = readl(gt_base + GT_CONTROL);
|
||||
reg &= ~GT_CONTROL_PRESCALER_MASK;
|
||||
reg |= psv << GT_CONTROL_PRESCALER_SHIFT;
|
||||
reg |= FIELD_PREP(GT_CONTROL_PRESCALER_MASK, psv);
|
||||
writel(reg, gt_base + GT_CONTROL);
|
||||
}
|
||||
|
||||
@ -256,8 +255,7 @@ static u32 gt_read_presc(void)
|
||||
u32 reg;
|
||||
|
||||
reg = readl(gt_base + GT_CONTROL);
|
||||
reg &= GT_CONTROL_PRESCALER_MASK;
|
||||
return reg >> GT_CONTROL_PRESCALER_SHIFT;
|
||||
return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg);
|
||||
}
|
||||
|
||||
static void __init gt_delay_timer_init(void)
|
||||
@ -272,9 +270,9 @@ static int __init gt_clocksource_init(void)
|
||||
writel(0, gt_base + GT_COUNTER0);
|
||||
writel(0, gt_base + GT_COUNTER1);
|
||||
/* set prescaler and enable timer on all the cores */
|
||||
writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) <<
|
||||
GT_CONTROL_PRESCALER_SHIFT)
|
||||
| GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
|
||||
writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK,
|
||||
CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) |
|
||||
GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
|
||||
|
||||
#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
|
||||
sched_clock_register(gt_sched_clock_read, 64, gt_target_rate);
|
||||
@ -290,18 +288,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
|
||||
switch (event) {
|
||||
case PRE_RATE_CHANGE:
|
||||
{
|
||||
int psv;
|
||||
unsigned long psv;
|
||||
|
||||
psv = DIV_ROUND_CLOSEST(ndata->new_rate,
|
||||
gt_target_rate);
|
||||
|
||||
if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
|
||||
psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate);
|
||||
if (!psv ||
|
||||
abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
|
||||
return NOTIFY_BAD;
|
||||
|
||||
psv--;
|
||||
|
||||
/* prescaler within legal range? */
|
||||
if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
|
||||
if (!FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv))
|
||||
return NOTIFY_BAD;
|
||||
|
||||
/*
|
||||
@ -411,7 +408,7 @@ static int __init global_timer_of_register(struct device_node *np)
|
||||
err = gt_clocksource_init();
|
||||
if (err)
|
||||
goto out_irq;
|
||||
|
||||
|
||||
err = cpuhp_setup_state(CPUHP_AP_ARM_GLOBAL_TIMER_STARTING,
|
||||
"clockevents/arm/global_timer:starting",
|
||||
gt_starting_cpu, gt_dying_cpu);
|
||||
|
@ -258,9 +258,8 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *ced = dev_id;
|
||||
struct imx_timer *imxtm = to_imx_timer(ced);
|
||||
uint32_t tstat;
|
||||
|
||||
tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat);
|
||||
readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat);
|
||||
|
||||
imxtm->gpt->gpt_irq_acknowledge(imxtm);
|
||||
|
||||
|
@ -4,48 +4,62 @@
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "timer-of.h"
|
||||
|
||||
#define CMP_OFFSET 0x10000
|
||||
#define RD_OFFSET 0x20000
|
||||
|
||||
#define CNTCV_LO 0x8
|
||||
#define CNTCV_HI 0xc
|
||||
#define CMPCV_LO (CMP_OFFSET + 0x20)
|
||||
#define CMPCV_HI (CMP_OFFSET + 0x24)
|
||||
#define CMPCR (CMP_OFFSET + 0x2c)
|
||||
#define CNTCV_LO_IMX95 (RD_OFFSET + 0x8)
|
||||
#define CNTCV_HI_IMX95 (RD_OFFSET + 0xc)
|
||||
|
||||
#define SYS_CTR_EN 0x1
|
||||
#define SYS_CTR_IRQ_MASK 0x2
|
||||
|
||||
#define SYS_CTR_CLK_DIV 0x3
|
||||
|
||||
static void __iomem *sys_ctr_base __ro_after_init;
|
||||
static u32 cmpcr __ro_after_init;
|
||||
struct sysctr_private {
|
||||
u32 cmpcr;
|
||||
u32 lo_off;
|
||||
u32 hi_off;
|
||||
};
|
||||
|
||||
static void sysctr_timer_enable(bool enable)
|
||||
static void sysctr_timer_enable(struct clock_event_device *evt, bool enable)
|
||||
{
|
||||
writel(enable ? cmpcr | SYS_CTR_EN : cmpcr, sys_ctr_base + CMPCR);
|
||||
struct timer_of *to = to_timer_of(evt);
|
||||
struct sysctr_private *priv = to->private_data;
|
||||
void __iomem *base = timer_of_base(to);
|
||||
|
||||
writel(enable ? priv->cmpcr | SYS_CTR_EN : priv->cmpcr, base + CMPCR);
|
||||
}
|
||||
|
||||
static void sysctr_irq_acknowledge(void)
|
||||
static void sysctr_irq_acknowledge(struct clock_event_device *evt)
|
||||
{
|
||||
/*
|
||||
* clear the enable bit(EN =0) will clear
|
||||
* the status bit(ISTAT = 0), then the interrupt
|
||||
* signal will be negated(acknowledged).
|
||||
*/
|
||||
sysctr_timer_enable(false);
|
||||
sysctr_timer_enable(evt, false);
|
||||
}
|
||||
|
||||
static inline u64 sysctr_read_counter(void)
|
||||
static inline u64 sysctr_read_counter(struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_of *to = to_timer_of(evt);
|
||||
struct sysctr_private *priv = to->private_data;
|
||||
void __iomem *base = timer_of_base(to);
|
||||
u32 cnt_hi, tmp_hi, cnt_lo;
|
||||
|
||||
do {
|
||||
cnt_hi = readl_relaxed(sys_ctr_base + CNTCV_HI);
|
||||
cnt_lo = readl_relaxed(sys_ctr_base + CNTCV_LO);
|
||||
tmp_hi = readl_relaxed(sys_ctr_base + CNTCV_HI);
|
||||
cnt_hi = readl_relaxed(base + priv->hi_off);
|
||||
cnt_lo = readl_relaxed(base + priv->lo_off);
|
||||
tmp_hi = readl_relaxed(base + priv->hi_off);
|
||||
} while (tmp_hi != cnt_hi);
|
||||
|
||||
return ((u64) cnt_hi << 32) | cnt_lo;
|
||||
@ -54,22 +68,24 @@ static inline u64 sysctr_read_counter(void)
|
||||
static int sysctr_set_next_event(unsigned long delta,
|
||||
struct clock_event_device *evt)
|
||||
{
|
||||
struct timer_of *to = to_timer_of(evt);
|
||||
void __iomem *base = timer_of_base(to);
|
||||
u32 cmp_hi, cmp_lo;
|
||||
u64 next;
|
||||
|
||||
sysctr_timer_enable(false);
|
||||
sysctr_timer_enable(evt, false);
|
||||
|
||||
next = sysctr_read_counter();
|
||||
next = sysctr_read_counter(evt);
|
||||
|
||||
next += delta;
|
||||
|
||||
cmp_hi = (next >> 32) & 0x00fffff;
|
||||
cmp_lo = next & 0xffffffff;
|
||||
|
||||
writel_relaxed(cmp_hi, sys_ctr_base + CMPCV_HI);
|
||||
writel_relaxed(cmp_lo, sys_ctr_base + CMPCV_LO);
|
||||
writel_relaxed(cmp_hi, base + CMPCV_HI);
|
||||
writel_relaxed(cmp_lo, base + CMPCV_LO);
|
||||
|
||||
sysctr_timer_enable(true);
|
||||
sysctr_timer_enable(evt, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -81,7 +97,7 @@ static int sysctr_set_state_oneshot(struct clock_event_device *evt)
|
||||
|
||||
static int sysctr_set_state_shutdown(struct clock_event_device *evt)
|
||||
{
|
||||
sysctr_timer_enable(false);
|
||||
sysctr_timer_enable(evt, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -90,7 +106,7 @@ static irqreturn_t sysctr_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = dev_id;
|
||||
|
||||
sysctr_irq_acknowledge();
|
||||
sysctr_irq_acknowledge(evt);
|
||||
|
||||
evt->event_handler(evt);
|
||||
|
||||
@ -117,34 +133,75 @@ static struct timer_of to_sysctr = {
|
||||
},
|
||||
};
|
||||
|
||||
static void __init sysctr_clockevent_init(void)
|
||||
static int __init __sysctr_timer_init(struct device_node *np)
|
||||
{
|
||||
to_sysctr.clkevt.cpumask = cpu_possible_mask;
|
||||
struct sysctr_private *priv;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
clockevents_config_and_register(&to_sysctr.clkevt,
|
||||
timer_of_rate(&to_sysctr),
|
||||
0xff, 0x7fffffff);
|
||||
}
|
||||
|
||||
static int __init sysctr_timer_init(struct device_node *np)
|
||||
{
|
||||
int ret = 0;
|
||||
priv = kzalloc(sizeof(struct sysctr_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = timer_of_init(np, &to_sysctr);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
kfree(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
cmpcr &= ~SYS_CTR_EN;
|
||||
to_sysctr.clkevt.cpumask = cpu_possible_mask;
|
||||
to_sysctr.private_data = priv;
|
||||
|
||||
sysctr_clockevent_init();
|
||||
base = timer_of_base(&to_sysctr);
|
||||
priv->cmpcr = readl(base + CMPCR) & ~SYS_CTR_EN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init sysctr_timer_init(struct device_node *np)
|
||||
{
|
||||
struct sysctr_private *priv;
|
||||
int ret;
|
||||
|
||||
ret = __sysctr_timer_init(np);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv = to_sysctr.private_data;
|
||||
priv->lo_off = CNTCV_LO;
|
||||
priv->hi_off = CNTCV_HI;
|
||||
|
||||
clockevents_config_and_register(&to_sysctr.clkevt,
|
||||
timer_of_rate(&to_sysctr),
|
||||
0xff, 0x7fffffff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init sysctr_timer_imx95_init(struct device_node *np)
|
||||
{
|
||||
struct sysctr_private *priv;
|
||||
int ret;
|
||||
|
||||
ret = __sysctr_timer_init(np);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv = to_sysctr.private_data;
|
||||
priv->lo_off = CNTCV_LO_IMX95;
|
||||
priv->hi_off = CNTCV_HI_IMX95;
|
||||
|
||||
clockevents_config_and_register(&to_sysctr.clkevt,
|
||||
timer_of_rate(&to_sysctr),
|
||||
0xff, 0x7fffffff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TIMER_OF_DECLARE(sysctr_timer, "nxp,sysctr-timer", sysctr_timer_init);
|
||||
TIMER_OF_DECLARE(sysctr_timer_imx95, "nxp,imx95-sysctr-timer", sysctr_timer_imx95_init);
|
||||
|
@ -108,6 +108,9 @@ static int riscv_timer_starting_cpu(unsigned int cpu)
|
||||
{
|
||||
struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu);
|
||||
|
||||
/* Clear timer interrupt */
|
||||
riscv_clock_event_stop();
|
||||
|
||||
ce->cpumask = cpumask_of(cpu);
|
||||
ce->irq = riscv_clock_event_irq;
|
||||
if (riscv_timer_cannot_wake_cpu)
|
||||
|
@ -73,7 +73,7 @@ static void stm32_timer_of_bits_set(struct timer_of *to, int bits)
|
||||
* Accessor helper to get the number of bits in the timer-of private
|
||||
* structure.
|
||||
*
|
||||
* Returns an integer corresponding to the number of bits.
|
||||
* Returns: an integer corresponding to the number of bits.
|
||||
*/
|
||||
static int stm32_timer_of_bits_get(struct timer_of *to)
|
||||
{
|
||||
@ -177,7 +177,7 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
|
||||
}
|
||||
|
||||
/**
|
||||
* stm32_timer_width - Sort out the timer width (32/16)
|
||||
* stm32_timer_set_width - Sort out the timer width (32/16)
|
||||
* @to: a pointer to a timer-of structure
|
||||
*
|
||||
* Write the 32-bit max value and read/return the result. If the timer
|
||||
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/**
|
||||
/*
|
||||
* timer-ti-32k.c - OMAP2 32k Timer Support
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
|
Loading…
Reference in New Issue
Block a user