Commit 3579698e authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Daniel Lezcano

clocksource: armada-370-xp: Simplify TIMER_CTRL register access

This commit creates two functions to access the TIMER_CTRL register:
one for global one for the per-cpu. This makes the code much more
readable. In addition, since the TIMER_CTRL register is also used for
watchdog, this is preparation work for future thread-safe improvements.
Acked-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarEzequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
parent ad48bd61
...@@ -71,6 +71,18 @@ static u32 ticks_per_jiffy; ...@@ -71,6 +71,18 @@ static u32 ticks_per_jiffy;
static struct clock_event_device __percpu **percpu_armada_370_xp_evt; static struct clock_event_device __percpu **percpu_armada_370_xp_evt;
static void timer_ctrl_clrset(u32 clr, u32 set)
{
writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set,
timer_base + TIMER_CTRL_OFF);
}
static void local_timer_ctrl_clrset(u32 clr, u32 set)
{
writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set,
local_base + TIMER_CTRL_OFF);
}
static u32 notrace armada_370_xp_read_sched_clock(void) static u32 notrace armada_370_xp_read_sched_clock(void)
{ {
return ~readl(timer_base + TIMER0_VAL_OFF); return ~readl(timer_base + TIMER0_VAL_OFF);
...@@ -83,7 +95,6 @@ static int ...@@ -83,7 +95,6 @@ static int
armada_370_xp_clkevt_next_event(unsigned long delta, armada_370_xp_clkevt_next_event(unsigned long delta,
struct clock_event_device *dev) struct clock_event_device *dev)
{ {
u32 u;
/* /*
* Clear clockevent timer interrupt. * Clear clockevent timer interrupt.
*/ */
...@@ -97,11 +108,8 @@ armada_370_xp_clkevt_next_event(unsigned long delta, ...@@ -97,11 +108,8 @@ armada_370_xp_clkevt_next_event(unsigned long delta,
/* /*
* Enable the timer. * Enable the timer.
*/ */
u = readl(local_base + TIMER_CTRL_OFF); local_timer_ctrl_clrset(TIMER0_RELOAD_EN,
u = ((u & ~TIMER0_RELOAD_EN) | TIMER0_EN | TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT));
TIMER0_DIV(TIMER_DIVIDER_SHIFT));
writel(u, local_base + TIMER_CTRL_OFF);
return 0; return 0;
} }
...@@ -109,8 +117,6 @@ static void ...@@ -109,8 +117,6 @@ static void
armada_370_xp_clkevt_mode(enum clock_event_mode mode, armada_370_xp_clkevt_mode(enum clock_event_mode mode,
struct clock_event_device *dev) struct clock_event_device *dev)
{ {
u32 u;
if (mode == CLOCK_EVT_MODE_PERIODIC) { if (mode == CLOCK_EVT_MODE_PERIODIC) {
/* /*
...@@ -122,18 +128,14 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode, ...@@ -122,18 +128,14 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode,
/* /*
* Enable timer. * Enable timer.
*/ */
local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN |
u = readl(local_base + TIMER_CTRL_OFF); TIMER0_EN |
TIMER0_DIV(TIMER_DIVIDER_SHIFT));
writel((u | TIMER0_EN | TIMER0_RELOAD_EN |
TIMER0_DIV(TIMER_DIVIDER_SHIFT)),
local_base + TIMER_CTRL_OFF);
} else { } else {
/* /*
* Disable timer. * Disable timer.
*/ */
u = readl(local_base + TIMER_CTRL_OFF); local_timer_ctrl_clrset(TIMER0_EN, 0);
writel(u & ~TIMER0_EN, local_base + TIMER_CTRL_OFF);
/* /*
* ACK pending timer interrupt. * ACK pending timer interrupt.
...@@ -169,18 +171,18 @@ static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) ...@@ -169,18 +171,18 @@ static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id)
*/ */
static int armada_370_xp_timer_setup(struct clock_event_device *evt) static int armada_370_xp_timer_setup(struct clock_event_device *evt)
{ {
u32 u; u32 clr = 0, set = 0;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
/* Use existing clock_event for cpu 0 */ /* Use existing clock_event for cpu 0 */
if (!smp_processor_id()) if (!smp_processor_id())
return 0; return 0;
u = readl(local_base + TIMER_CTRL_OFF);
if (timer25Mhz) if (timer25Mhz)
writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); set = TIMER0_25MHZ;
else else
writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); clr = TIMER0_25MHZ;
local_timer_ctrl_clrset(clr, set);
evt->name = armada_370_xp_clkevt.name; evt->name = armada_370_xp_clkevt.name;
evt->irq = armada_370_xp_clkevt.irq; evt->irq = armada_370_xp_clkevt.irq;
...@@ -212,7 +214,7 @@ static struct local_timer_ops armada_370_xp_local_timer_ops = { ...@@ -212,7 +214,7 @@ static struct local_timer_ops armada_370_xp_local_timer_ops = {
void __init armada_370_xp_timer_init(void) void __init armada_370_xp_timer_init(void)
{ {
u32 u; u32 clr = 0, set = 0;
struct device_node *np; struct device_node *np;
int res; int res;
...@@ -223,29 +225,20 @@ void __init armada_370_xp_timer_init(void) ...@@ -223,29 +225,20 @@ void __init armada_370_xp_timer_init(void)
if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { if (of_find_property(np, "marvell,timer-25Mhz", NULL)) {
/* The fixed 25MHz timer is available so let's use it */ /* The fixed 25MHz timer is available so let's use it */
u = readl(local_base + TIMER_CTRL_OFF); set = TIMER0_25MHZ;
writel(u | TIMER0_25MHZ,
local_base + TIMER_CTRL_OFF);
u = readl(timer_base + TIMER_CTRL_OFF);
writel(u | TIMER0_25MHZ,
timer_base + TIMER_CTRL_OFF);
timer_clk = 25000000; timer_clk = 25000000;
} else { } else {
unsigned long rate = 0; unsigned long rate = 0;
struct clk *clk = of_clk_get(np, 0); struct clk *clk = of_clk_get(np, 0);
WARN_ON(IS_ERR(clk)); WARN_ON(IS_ERR(clk));
rate = clk_get_rate(clk); rate = clk_get_rate(clk);
u = readl(local_base + TIMER_CTRL_OFF);
writel(u & ~(TIMER0_25MHZ),
local_base + TIMER_CTRL_OFF);
u = readl(timer_base + TIMER_CTRL_OFF);
writel(u & ~(TIMER0_25MHZ),
timer_base + TIMER_CTRL_OFF);
timer_clk = rate / TIMER_DIVIDER; timer_clk = rate / TIMER_DIVIDER;
clr = TIMER0_25MHZ;
timer25Mhz = false; timer25Mhz = false;
} }
timer_ctrl_clrset(clr, set);
local_timer_ctrl_clrset(clr, set);
/* /*
* We use timer 0 as clocksource, and private(local) timer 0 * We use timer 0 as clocksource, and private(local) timer 0
...@@ -267,10 +260,8 @@ void __init armada_370_xp_timer_init(void) ...@@ -267,10 +260,8 @@ void __init armada_370_xp_timer_init(void)
writel(0xffffffff, timer_base + TIMER0_VAL_OFF); writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
u = readl(timer_base + TIMER_CTRL_OFF); timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN |
TIMER0_DIV(TIMER_DIVIDER_SHIFT));
writel((u | TIMER0_EN | TIMER0_RELOAD_EN |
TIMER0_DIV(TIMER_DIVIDER_SHIFT)), timer_base + TIMER_CTRL_OFF);
clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, clocksource_mmio_init(timer_base + TIMER0_VAL_OFF,
"armada_370_xp_clocksource", "armada_370_xp_clocksource",
......
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