Commit 86c54c84 authored by Thomas Gleixner's avatar Thomas Gleixner

Merge tag 'timers-v6.9-rc1' of https://git.linaro.org/people/daniel.lezcano/linux into timers/core

Pull clocksource/event driver updates from Daniel Lezcano:

  - Fix -Wunused-but-set-variable warning for the iMX GPT timer (Daniel
    Lezcano)

  - Add Pixel6 compatible string for Exynos 4210 MCT timer (Peter Griffin)

  - Fix all kernel-doc warnings and misuse of comment format (Randy
    Dunlap)

  - Document in the DT bindings the interrupt used for input capture
    interrupt and udpate the example to match the reality (Geert
    Uytterhoeven)

  - Document RZ/Five SoC DT bindings (Lad Prabhakar)

  - Add DT bindings support for the i.MX95, reorganize the driver to
    move globale variables to a timer private structure and introduce
    the i.MX95 timer support (Peng Fan)

  - Fix prescalar value to conform to the ARM global timer
    documentation. Fix data types and comparison, guard the divide by
    zero code section and use the available macros for bit manipulation
    (Martin Blumenstingl)

  - Add Ralink SoCs system tick counter (Sergio Paracuellos)

  - Add support for cadence TTC PWM (Mubin Sayyed)

  - Clear timer interrupt on timer initialization to prevent the
    interrupt to fire during setup (Ley Foon Tan)

Link: https://lore.kernel.org/r/5552010a-1ce2-46a1-a740-a69f2e9a2cf2@linaro.org
parents 8ca18367 8248ca30
...@@ -32,12 +32,23 @@ properties: ...@@ -32,12 +32,23 @@ properties:
description: | description: |
Bit width of the timer, necessary if not 16. Bit width of the timer, necessary if not 16.
"#pwm-cells":
const: 3
required: required:
- compatible - compatible
- reg - reg
- interrupts
- clocks - clocks
allOf:
- if:
not:
required:
- "#pwm-cells"
then:
required:
- interrupts
additionalProperties: false additionalProperties: false
examples: examples:
...@@ -50,3 +61,12 @@ examples: ...@@ -50,3 +61,12 @@ examples:
clocks = <&cpu_clk 3>; clocks = <&cpu_clk 3>;
timer-width = <32>; 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: | ...@@ -18,7 +18,9 @@ description: |
properties: properties:
compatible: compatible:
const: nxp,sysctr-timer enum:
- nxp,imx95-sysctr-timer
- nxp,sysctr-timer
reg: reg:
maxItems: 1 maxItems: 1
......
# 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: ...@@ -23,7 +23,7 @@ properties:
- enum: - enum:
- renesas,r7s72100-ostm # RZ/A1H - renesas,r7s72100-ostm # RZ/A1H
- renesas,r7s9210-ostm # RZ/A2M - 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,r9a07g044-ostm # RZ/G2{L,LC}
- renesas,r9a07g054-ostm # RZ/V2L - renesas,r9a07g054-ostm # RZ/V2L
- const: renesas,ostm # Generic - const: renesas,ostm # Generic
......
...@@ -46,7 +46,19 @@ properties: ...@@ -46,7 +46,19 @@ properties:
interrupts: interrupts:
minItems: 2 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: clocks:
maxItems: 1 maxItems: 1
...@@ -100,7 +112,9 @@ examples: ...@@ -100,7 +112,9 @@ examples:
reg = <0xffd80000 0x30>; reg = <0xffd80000 0x30>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>, interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 33 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>; clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
clock-names = "fck"; clock-names = "fck";
power-domains = <&sysc R8A7779_PD_ALWAYS_ON>; power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
......
...@@ -26,6 +26,7 @@ properties: ...@@ -26,6 +26,7 @@ properties:
- items: - items:
- enum: - enum:
- axis,artpec8-mct - axis,artpec8-mct
- google,gs101-mct
- samsung,exynos3250-mct - samsung,exynos3250-mct
- samsung,exynos5250-mct - samsung,exynos5250-mct
- samsung,exynos5260-mct - samsung,exynos5260-mct
...@@ -127,6 +128,7 @@ allOf: ...@@ -127,6 +128,7 @@ allOf:
contains: contains:
enum: enum:
- axis,artpec8-mct - axis,artpec8-mct
- google,gs101-mct
- samsung,exynos5260-mct - samsung,exynos5260-mct
- samsung,exynos5420-mct - samsung,exynos5420-mct
- samsung,exynos5433-mct - samsung,exynos5433-mct
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/bitfield.h>
#include <linux/clocksource.h> #include <linux/clocksource.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/cpu.h> #include <linux/cpu.h>
...@@ -31,10 +32,7 @@ ...@@ -31,10 +32,7 @@
#define GT_CONTROL_COMP_ENABLE BIT(1) /* banked */ #define GT_CONTROL_COMP_ENABLE BIT(1) /* banked */
#define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */ #define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */
#define GT_CONTROL_AUTO_INC BIT(3) /* banked */ #define GT_CONTROL_AUTO_INC BIT(3) /* banked */
#define GT_CONTROL_PRESCALER_SHIFT 8 #define GT_CONTROL_PRESCALER_MASK GENMASK(15, 8)
#define GT_CONTROL_PRESCALER_MAX 0xF
#define GT_CONTROL_PRESCALER_MASK (GT_CONTROL_PRESCALER_MAX << \
GT_CONTROL_PRESCALER_SHIFT)
#define GT_INT_STATUS 0x0c #define GT_INT_STATUS 0x0c
#define GT_INT_STATUS_EVENT_FLAG BIT(0) #define GT_INT_STATUS_EVENT_FLAG BIT(0)
...@@ -52,7 +50,8 @@ ...@@ -52,7 +50,8 @@
*/ */
static void __iomem *gt_base; static void __iomem *gt_base;
static struct notifier_block gt_clk_rate_change_nb; 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 int gt_ppi;
static struct clock_event_device __percpu *gt_evt; static struct clock_event_device __percpu *gt_evt;
...@@ -88,7 +87,7 @@ static u64 gt_counter_read(void) ...@@ -88,7 +87,7 @@ static u64 gt_counter_read(void)
return _gt_counter_read(); return _gt_counter_read();
} }
/** /*
* To ensure that updates to comparator value register do not set the * To ensure that updates to comparator value register do not set the
* Interrupt Status Register proceed as follows: * Interrupt Status Register proceed as follows:
* 1. Clear the Comp Enable bit in the Timer Control Register. * 1. Clear the Comp Enable bit in the Timer Control Register.
...@@ -247,7 +246,7 @@ static void gt_write_presc(u32 psv) ...@@ -247,7 +246,7 @@ static void gt_write_presc(u32 psv)
reg = readl(gt_base + GT_CONTROL); reg = readl(gt_base + GT_CONTROL);
reg &= ~GT_CONTROL_PRESCALER_MASK; 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); writel(reg, gt_base + GT_CONTROL);
} }
...@@ -256,8 +255,7 @@ static u32 gt_read_presc(void) ...@@ -256,8 +255,7 @@ static u32 gt_read_presc(void)
u32 reg; u32 reg;
reg = readl(gt_base + GT_CONTROL); reg = readl(gt_base + GT_CONTROL);
reg &= GT_CONTROL_PRESCALER_MASK; return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg);
return reg >> GT_CONTROL_PRESCALER_SHIFT;
} }
static void __init gt_delay_timer_init(void) static void __init gt_delay_timer_init(void)
...@@ -272,9 +270,9 @@ static int __init gt_clocksource_init(void) ...@@ -272,9 +270,9 @@ static int __init gt_clocksource_init(void)
writel(0, gt_base + GT_COUNTER0); writel(0, gt_base + GT_COUNTER0);
writel(0, gt_base + GT_COUNTER1); writel(0, gt_base + GT_COUNTER1);
/* set prescaler and enable timer on all the cores */ /* set prescaler and enable timer on all the cores */
writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) << writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK,
GT_CONTROL_PRESCALER_SHIFT) CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) |
| GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
sched_clock_register(gt_sched_clock_read, 64, gt_target_rate); 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, ...@@ -290,18 +288,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb,
switch (event) { switch (event) {
case PRE_RATE_CHANGE: 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; return NOTIFY_BAD;
psv--; psv--;
/* prescaler within legal range? */ /* prescaler within legal range? */
if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX) if (!FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv))
return NOTIFY_BAD; return NOTIFY_BAD;
/* /*
......
...@@ -258,9 +258,8 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) ...@@ -258,9 +258,8 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
{ {
struct clock_event_device *ced = dev_id; struct clock_event_device *ced = dev_id;
struct imx_timer *imxtm = to_imx_timer(ced); 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); imxtm->gpt->gpt_irq_acknowledge(imxtm);
......
...@@ -4,48 +4,62 @@ ...@@ -4,48 +4,62 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/slab.h>
#include "timer-of.h" #include "timer-of.h"
#define CMP_OFFSET 0x10000 #define CMP_OFFSET 0x10000
#define RD_OFFSET 0x20000
#define CNTCV_LO 0x8 #define CNTCV_LO 0x8
#define CNTCV_HI 0xc #define CNTCV_HI 0xc
#define CMPCV_LO (CMP_OFFSET + 0x20) #define CMPCV_LO (CMP_OFFSET + 0x20)
#define CMPCV_HI (CMP_OFFSET + 0x24) #define CMPCV_HI (CMP_OFFSET + 0x24)
#define CMPCR (CMP_OFFSET + 0x2c) #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_EN 0x1
#define SYS_CTR_IRQ_MASK 0x2 #define SYS_CTR_IRQ_MASK 0x2
#define SYS_CTR_CLK_DIV 0x3 #define SYS_CTR_CLK_DIV 0x3
static void __iomem *sys_ctr_base __ro_after_init; struct sysctr_private {
static u32 cmpcr __ro_after_init; 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 * clear the enable bit(EN =0) will clear
* the status bit(ISTAT = 0), then the interrupt * the status bit(ISTAT = 0), then the interrupt
* signal will be negated(acknowledged). * 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; u32 cnt_hi, tmp_hi, cnt_lo;
do { do {
cnt_hi = readl_relaxed(sys_ctr_base + CNTCV_HI); cnt_hi = readl_relaxed(base + priv->hi_off);
cnt_lo = readl_relaxed(sys_ctr_base + CNTCV_LO); cnt_lo = readl_relaxed(base + priv->lo_off);
tmp_hi = readl_relaxed(sys_ctr_base + CNTCV_HI); tmp_hi = readl_relaxed(base + priv->hi_off);
} while (tmp_hi != cnt_hi); } while (tmp_hi != cnt_hi);
return ((u64) cnt_hi << 32) | cnt_lo; return ((u64) cnt_hi << 32) | cnt_lo;
...@@ -54,22 +68,24 @@ static inline u64 sysctr_read_counter(void) ...@@ -54,22 +68,24 @@ static inline u64 sysctr_read_counter(void)
static int sysctr_set_next_event(unsigned long delta, static int sysctr_set_next_event(unsigned long delta,
struct clock_event_device *evt) 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; u32 cmp_hi, cmp_lo;
u64 next; u64 next;
sysctr_timer_enable(false); sysctr_timer_enable(evt, false);
next = sysctr_read_counter(); next = sysctr_read_counter(evt);
next += delta; next += delta;
cmp_hi = (next >> 32) & 0x00fffff; cmp_hi = (next >> 32) & 0x00fffff;
cmp_lo = next & 0xffffffff; cmp_lo = next & 0xffffffff;
writel_relaxed(cmp_hi, sys_ctr_base + CMPCV_HI); writel_relaxed(cmp_hi, base + CMPCV_HI);
writel_relaxed(cmp_lo, sys_ctr_base + CMPCV_LO); writel_relaxed(cmp_lo, base + CMPCV_LO);
sysctr_timer_enable(true); sysctr_timer_enable(evt, true);
return 0; return 0;
} }
...@@ -81,7 +97,7 @@ static int sysctr_set_state_oneshot(struct clock_event_device *evt) ...@@ -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) static int sysctr_set_state_shutdown(struct clock_event_device *evt)
{ {
sysctr_timer_enable(false); sysctr_timer_enable(evt, false);
return 0; return 0;
} }
...@@ -90,7 +106,7 @@ static irqreturn_t sysctr_timer_interrupt(int irq, void *dev_id) ...@@ -90,7 +106,7 @@ static irqreturn_t sysctr_timer_interrupt(int irq, void *dev_id)
{ {
struct clock_event_device *evt = dev_id; struct clock_event_device *evt = dev_id;
sysctr_irq_acknowledge(); sysctr_irq_acknowledge(evt);
evt->event_handler(evt); evt->event_handler(evt);
...@@ -117,34 +133,75 @@ static struct timer_of to_sysctr = { ...@@ -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)
{ {
struct sysctr_private *priv;
void __iomem *base;
int ret;
priv = kzalloc(sizeof(struct sysctr_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
ret = timer_of_init(np, &to_sysctr);
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;
}
to_sysctr.clkevt.cpumask = cpu_possible_mask; to_sysctr.clkevt.cpumask = cpu_possible_mask;
to_sysctr.private_data = priv;
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, clockevents_config_and_register(&to_sysctr.clkevt,
timer_of_rate(&to_sysctr), timer_of_rate(&to_sysctr),
0xff, 0x7fffffff); 0xff, 0x7fffffff);
return 0;
} }
static int __init sysctr_timer_init(struct device_node *np) static int __init sysctr_timer_imx95_init(struct device_node *np)
{ {
int ret = 0; struct sysctr_private *priv;
int ret;
ret = timer_of_init(np, &to_sysctr); ret = __sysctr_timer_init(np);
if (ret) if (ret)
return ret; return ret;
if (!of_property_read_bool(np, "nxp,no-divider")) { priv = to_sysctr.private_data;
/* system counter clock is divided by 3 internally */ priv->lo_off = CNTCV_LO_IMX95;
to_sysctr.of_clk.rate /= SYS_CTR_CLK_DIV; priv->hi_off = CNTCV_HI_IMX95;
}
sys_ctr_base = timer_of_base(&to_sysctr);
cmpcr = readl(sys_ctr_base + CMPCR);
cmpcr &= ~SYS_CTR_EN;
sysctr_clockevent_init(); clockevents_config_and_register(&to_sysctr.clkevt,
timer_of_rate(&to_sysctr),
0xff, 0x7fffffff);
return 0; return 0;
} }
TIMER_OF_DECLARE(sysctr_timer, "nxp,sysctr-timer", sysctr_timer_init); 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) ...@@ -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); 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->cpumask = cpumask_of(cpu);
ce->irq = riscv_clock_event_irq; ce->irq = riscv_clock_event_irq;
if (riscv_timer_cannot_wake_cpu) if (riscv_timer_cannot_wake_cpu)
......
...@@ -73,7 +73,7 @@ static void stm32_timer_of_bits_set(struct timer_of *to, int bits) ...@@ -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 * Accessor helper to get the number of bits in the timer-of private
* structure. * 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) 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) ...@@ -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 * @to: a pointer to a timer-of structure
* *
* Write the 32-bit max value and read/return the result. If the timer * Write the 32-bit max value and read/return the result. If the timer
......
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* timer-ti-32k.c - OMAP2 32k Timer Support * timer-ti-32k.c - OMAP2 32k Timer Support
* *
* Copyright (C) 2009 Nokia Corporation * Copyright (C) 2009 Nokia Corporation
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment