98 lines
3.0 KiB
Diff
98 lines
3.0 KiB
Diff
|
From 6d879eb6b852c61d3422860cd39aba0774b383ed Mon Sep 17 00:00:00 2001
|
||
|
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||
|
Date: Wed, 9 Mar 2016 10:51:06 +0100
|
||
|
Subject: [PATCH 031/365] arm: at91: do not disable/enable clocks in a row
|
||
|
|
||
|
Currently the driver will disable the clock and enable it one line later
|
||
|
if it is switching from periodic mode into one shot.
|
||
|
This can be avoided and causes a needless warning on -RT.
|
||
|
|
||
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
||
|
---
|
||
|
drivers/clocksource/tcb_clksrc.c | 33 ++++++++++++++++++++++++++++----
|
||
|
1 file changed, 29 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
|
||
|
index 4da2af9694a2..ed1ae4445e8d 100644
|
||
|
--- a/drivers/clocksource/tcb_clksrc.c
|
||
|
+++ b/drivers/clocksource/tcb_clksrc.c
|
||
|
@@ -74,6 +74,7 @@ static struct clocksource clksrc = {
|
||
|
struct tc_clkevt_device {
|
||
|
struct clock_event_device clkevt;
|
||
|
struct clk *clk;
|
||
|
+ bool clk_enabled;
|
||
|
void __iomem *regs;
|
||
|
};
|
||
|
|
||
|
@@ -91,6 +92,24 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt)
|
||
|
*/
|
||
|
static u32 timer_clock;
|
||
|
|
||
|
+static void tc_clk_disable(struct clock_event_device *d)
|
||
|
+{
|
||
|
+ struct tc_clkevt_device *tcd = to_tc_clkevt(d);
|
||
|
+
|
||
|
+ clk_disable(tcd->clk);
|
||
|
+ tcd->clk_enabled = false;
|
||
|
+}
|
||
|
+
|
||
|
+static void tc_clk_enable(struct clock_event_device *d)
|
||
|
+{
|
||
|
+ struct tc_clkevt_device *tcd = to_tc_clkevt(d);
|
||
|
+
|
||
|
+ if (tcd->clk_enabled)
|
||
|
+ return;
|
||
|
+ clk_enable(tcd->clk);
|
||
|
+ tcd->clk_enabled = true;
|
||
|
+}
|
||
|
+
|
||
|
static int tc_shutdown(struct clock_event_device *d)
|
||
|
{
|
||
|
struct tc_clkevt_device *tcd = to_tc_clkevt(d);
|
||
|
@@ -98,8 +117,14 @@ static int tc_shutdown(struct clock_event_device *d)
|
||
|
|
||
|
__raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
|
||
|
__raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int tc_shutdown_clk_off(struct clock_event_device *d)
|
||
|
+{
|
||
|
+ tc_shutdown(d);
|
||
|
if (!clockevent_state_detached(d))
|
||
|
- clk_disable(tcd->clk);
|
||
|
+ tc_clk_disable(d);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -112,7 +137,7 @@ static int tc_set_oneshot(struct clock_event_device *d)
|
||
|
if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
|
||
|
tc_shutdown(d);
|
||
|
|
||
|
- clk_enable(tcd->clk);
|
||
|
+ tc_clk_enable(d);
|
||
|
|
||
|
/* slow clock, count up to RC, then irq and stop */
|
||
|
__raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE |
|
||
|
@@ -134,7 +159,7 @@ static int tc_set_periodic(struct clock_event_device *d)
|
||
|
/* By not making the gentime core emulate periodic mode on top
|
||
|
* of oneshot, we get lower overhead and improved accuracy.
|
||
|
*/
|
||
|
- clk_enable(tcd->clk);
|
||
|
+ tc_clk_enable(d);
|
||
|
|
||
|
/* slow clock, count up to RC, then irq and restart */
|
||
|
__raw_writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
|
||
|
@@ -168,7 +193,7 @@ static struct tc_clkevt_device clkevt = {
|
||
|
/* Should be lower than at91rm9200's system timer */
|
||
|
.rating = 125,
|
||
|
.set_next_event = tc_next_event,
|
||
|
- .set_state_shutdown = tc_shutdown,
|
||
|
+ .set_state_shutdown = tc_shutdown_clk_off,
|
||
|
.set_state_periodic = tc_set_periodic,
|
||
|
.set_state_oneshot = tc_set_oneshot,
|
||
|
},
|
||
|
--
|
||
|
2.28.0
|
||
|
|