From: tip-bot for Benjamin Gaignard <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: hpa@zytor.com, linux-kernel@vger.kernel.org,
torvalds@linux-foundation.org, mingo@kernel.org,
mcoquelin.stm32@gmail.com, tglx@linutronix.de,
peterz@infradead.org, alexandre.torgue@st.com,
benjamin.gaignard@st.com, daniel.lezcano@linaro.org
Subject: [tip:timers/core] clocksource/drivers/stm32: Add oneshot mode
Date: Mon, 8 Jan 2018 09:32:38 -0800 [thread overview]
Message-ID: <tip-8e82df381b676ae5f6c93ab4a75f56d8f61babc4@git.kernel.org> (raw)
In-Reply-To: <1515418139-23276-16-git-send-email-daniel.lezcano@linaro.org>
Commit-ID: 8e82df381b676ae5f6c93ab4a75f56d8f61babc4
Gitweb: https://git.kernel.org/tip/8e82df381b676ae5f6c93ab4a75f56d8f61babc4
Author: Benjamin Gaignard <benjamin.gaignard@st.com>
AuthorDate: Mon, 8 Jan 2018 14:28:55 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Mon, 8 Jan 2018 17:57:26 +0100
clocksource/drivers/stm32: Add oneshot mode
The stm32 timer block is able to have a counter and a comparator.
Instead of using the auto-reload register for periodic events, we switch
to oneshot mode by using the comparator register.
The timer is able to generate an interrupt when the counter overflows but
we don't want that as this counter will be use as a clocksource in the next
patches. So it is disabled by the UDIS bit of the control register.
Tested-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Benjamin Gaignard <benjamin.gaignard@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1515418139-23276-16-git-send-email-daniel.lezcano@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
drivers/clocksource/timer-stm32.c | 56 ++++++++++++++++++++++++++++++---------
1 file changed, 44 insertions(+), 12 deletions(-)
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
index 928ac28..882037f 100644
--- a/drivers/clocksource/timer-stm32.c
+++ b/drivers/clocksource/timer-stm32.c
@@ -24,14 +24,18 @@
#define TIM_DIER 0x0c
#define TIM_SR 0x10
#define TIM_EGR 0x14
+#define TIM_CNT 0x24
#define TIM_PSC 0x28
#define TIM_ARR 0x2c
+#define TIM_CCR1 0x34
#define TIM_CR1_CEN BIT(0)
+#define TIM_CR1_UDIS BIT(1)
#define TIM_CR1_OPM BIT(3)
#define TIM_CR1_ARPE BIT(7)
#define TIM_DIER_UIE BIT(0)
+#define TIM_DIER_CC1IE BIT(1)
#define TIM_SR_UIF BIT(0)
@@ -40,33 +44,57 @@
#define TIM_PSC_MAX USHRT_MAX
#define TIM_PSC_CLKRATE 10000
+static void stm32_clock_event_disable(struct timer_of *to)
+{
+ writel_relaxed(0, timer_of_base(to) + TIM_DIER);
+}
+
+static void stm32_clock_event_enable(struct timer_of *to)
+{
+ writel_relaxed(TIM_CR1_UDIS | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1);
+}
+
static int stm32_clock_event_shutdown(struct clock_event_device *clkevt)
{
struct timer_of *to = to_timer_of(clkevt);
- writel_relaxed(0, timer_of_base(to) + TIM_CR1);
+ stm32_clock_event_disable(to);
return 0;
}
-static int stm32_clock_event_set_periodic(struct clock_event_device *clkevt)
+static int stm32_clock_event_set_next_event(unsigned long evt,
+ struct clock_event_device *clkevt)
{
struct timer_of *to = to_timer_of(clkevt);
+ unsigned long now, next;
+
+ next = readl_relaxed(timer_of_base(to) + TIM_CNT) + evt;
+ writel_relaxed(next, timer_of_base(to) + TIM_CCR1);
+ now = readl_relaxed(timer_of_base(to) + TIM_CNT);
+
+ if ((next - now) > evt)
+ return -ETIME;
- writel_relaxed(timer_of_period(to), timer_of_base(to) + TIM_ARR);
- writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, timer_of_base(to) + TIM_CR1);
+ writel_relaxed(TIM_DIER_CC1IE, timer_of_base(to) + TIM_DIER);
return 0;
}
-static int stm32_clock_event_set_next_event(unsigned long evt,
- struct clock_event_device *clkevt)
+static int stm32_clock_event_set_periodic(struct clock_event_device *clkevt)
+{
+ struct timer_of *to = to_timer_of(clkevt);
+
+ stm32_clock_event_enable(to);
+
+ return stm32_clock_event_set_next_event(timer_of_period(to), clkevt);
+}
+
+static int stm32_clock_event_set_oneshot(struct clock_event_device *clkevt)
{
struct timer_of *to = to_timer_of(clkevt);
- writel_relaxed(evt, timer_of_base(to) + TIM_ARR);
- writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN,
- timer_of_base(to) + TIM_CR1);
+ stm32_clock_event_enable(to);
return 0;
}
@@ -78,6 +106,11 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
writel_relaxed(0, timer_of_base(to) + TIM_SR);
+ if (clockevent_state_periodic(clkevt))
+ stm32_clock_event_set_periodic(clkevt);
+ else
+ stm32_clock_event_shutdown(clkevt);
+
clkevt->event_handler(clkevt);
return IRQ_HANDLED;
@@ -108,9 +141,10 @@ static void __init stm32_clockevent_init(struct timer_of *to)
to->clkevt.name = to->np->full_name;
to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
+ to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
to->clkevt.set_state_shutdown = stm32_clock_event_shutdown;
to->clkevt.set_state_periodic = stm32_clock_event_set_periodic;
- to->clkevt.set_state_oneshot = stm32_clock_event_shutdown;
+ to->clkevt.set_state_oneshot = stm32_clock_event_set_oneshot;
to->clkevt.tick_resume = stm32_clock_event_shutdown;
to->clkevt.set_next_event = stm32_clock_event_set_next_event;
@@ -129,12 +163,10 @@ static void __init stm32_clockevent_init(struct timer_of *to)
prescaler = prescaler < TIM_PSC_MAX ? prescaler : TIM_PSC_MAX;
to->clkevt.rating = 100;
}
- writel_relaxed(0, timer_of_base(to) + TIM_ARR);
writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
writel_relaxed(TIM_EGR_UG, timer_of_base(to) + TIM_EGR);
writel_relaxed(0, timer_of_base(to) + TIM_SR);
- writel_relaxed(TIM_DIER_UIE, timer_of_base(to) + TIM_DIER);
/* Adjust rate and period given the prescaler value */
to->of_clk.rate = DIV_ROUND_CLOSEST(to->of_clk.rate, prescaler);
next prev parent reply other threads:[~2018-01-08 17:37 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-08 13:27 [PULL] clockevents for 4.16 Daniel Lezcano
2018-01-08 13:28 ` [PATCH 01/20] dt-bindings: timer: Add Actions Semi S700 Daniel Lezcano
2018-01-08 13:28 ` [PATCH 02/20] clocksource/drivers/owl: Adopt TIMER_OF_DECLARE() Daniel Lezcano
2018-01-08 13:28 ` [PATCH 03/20] clocksource/drivers/owl: Add the S700 Daniel Lezcano
2018-01-08 13:28 ` [PATCH 04/20] clocksource/drivers/tcb_clksrc: Fix clock speed message Daniel Lezcano
2018-01-08 17:27 ` [tip:timers/core] " tip-bot for Romain Izard
2018-01-08 13:28 ` [PATCH 05/20] clocksource/drivers/timer-of: Fix function names Daniel Lezcano
2018-01-08 17:27 ` [tip:timers/core] " tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 06/20] clocksource/drivers/timer-of: Add kernel documentation Daniel Lezcano
2018-01-08 17:28 ` [tip:timers/core] " tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 07/20] dt-bindings: clocksource: Add Spreadtrum SC9860 timer Daniel Lezcano
2018-01-08 17:28 ` [tip:timers/core] dt-bindings/clocksource: Add Spreadtrum SC9860 timer documentation tip-bot for Baolin Wang
2018-01-08 13:28 ` [PATCH 08/20] clocksource/drivers/spreadtrum: Add timer driver for Spreadtrum SC9860 platform Daniel Lezcano
2018-01-08 17:29 ` [tip:timers/core] clocksource/drivers/spreadtrum: Add timer driver for the " tip-bot for Baolin Wang
2018-01-08 13:28 ` [PATCH 09/20] clocksource/drivers/timer-of: Store the device node pointer Daniel Lezcano
2018-01-08 17:29 ` [tip:timers/core] clocksource/drivers/timer-of: Store the device node pointer in 'struct timer_of' tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 10/20] clocksource/drivers/timer-of: Don't request the resource by name Daniel Lezcano
2018-01-08 17:30 ` [tip:timers/core] " tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 11/20] clocksource/drivers/stm32: Fix kernel panic with multiple timers Daniel Lezcano
2018-01-08 17:30 ` [tip:timers/core] " tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 12/20] clocksource/drivers/stm32: Convert the driver to timer-of Daniel Lezcano
2018-01-08 17:30 ` [tip:timers/core] clocksource/drivers/stm32: Convert the driver to timer_of primitives tip-bot for Benjamin Gaignard
2018-01-08 13:28 ` [PATCH 13/20] clocksource/drivers/stm32: Use the node name as timer name Daniel Lezcano
2018-01-08 17:31 ` [tip:timers/core] " tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 14/20] clocksource/drivers/stm32: Encapsulate the timer width sorting out function Daniel Lezcano
2018-01-08 17:31 ` [tip:timers/core] clocksource/drivers/stm32: Factor out the timer width sorting code tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 15/20] clocksource/drivers/stm32: Compute a prescaler value with a targeted rate Daniel Lezcano
2018-01-08 17:32 ` [tip:timers/core] " tip-bot for Benjamin Gaignard
2018-01-08 13:28 ` [PATCH 16/20] clocksource/drivers/stm32: Add the oneshot mode Daniel Lezcano
2018-01-08 17:32 ` tip-bot for Benjamin Gaignard [this message]
2018-01-08 13:28 ` [PATCH 17/20] clocksource/drivers/stm32: Encapsulate more the clockevent code Daniel Lezcano
2018-01-08 17:33 ` [tip:timers/core] clocksource/drivers/stm32: Factor out more of " tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 18/20] clocksource/drivers/stm32: Add the clocksource Daniel Lezcano
2018-01-08 17:33 ` [tip:timers/core] clocksource/drivers/stm32: Add clocksource functionality tip-bot for Benjamin Gaignard
2018-01-08 13:28 ` [PATCH 19/20] clocksource/drivers/stm32: Add the timer delay Daniel Lezcano
2018-01-08 17:33 ` [tip:timers/core] clocksource/drivers/stm32: Add the timer delay callback tip-bot for Daniel Lezcano
2018-01-08 13:28 ` [PATCH 20/20] clocksource/drivers/stm32: Start the timer's counter sooner Daniel Lezcano
2018-01-08 17:34 ` [tip:timers/core] " tip-bot for Daniel Lezcano
2018-01-08 16:58 ` [PULL] clockevents for 4.16 Ingo Molnar
2018-01-08 17:07 ` Daniel Lezcano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-8e82df381b676ae5f6c93ab4a75f56d8f61babc4@git.kernel.org \
--to=tipbot@zytor.com \
--cc=alexandre.torgue@st.com \
--cc=benjamin.gaignard@st.com \
--cc=daniel.lezcano@linaro.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mcoquelin.stm32@gmail.com \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).