diff options
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch')
-rw-r--r-- | target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch b/target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch new file mode 100644 index 0000000000..109d52d7c2 --- /dev/null +++ b/target/linux/mvebu/patches-3.10/0167-clocksource-armada-370-xp-Simplify-TIMER_CTRL-regist.patch @@ -0,0 +1,174 @@ +From 7a5e03909417ccecc85819837d10cbb6ffe1d759 Mon Sep 17 00:00:00 2001 +From: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +Date: Tue, 13 Aug 2013 11:43:11 -0300 +Subject: [PATCH 167/203] 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: Gregory CLEMENT <gregory.clement@free-electrons.com> +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +--- + drivers/clocksource/time-armada-370-xp.c | 69 ++++++++++++++------------------ + 1 file changed, 30 insertions(+), 39 deletions(-) + +--- a/drivers/clocksource/time-armada-370-xp.c ++++ b/drivers/clocksource/time-armada-370-xp.c +@@ -71,6 +71,18 @@ static u32 ticks_per_jiffy; + + 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) + { + return ~readl(timer_base + TIMER0_VAL_OFF); +@@ -83,7 +95,6 @@ static int + armada_370_xp_clkevt_next_event(unsigned long delta, + struct clock_event_device *dev) + { +- u32 u; + /* + * Clear clockevent timer interrupt. + */ +@@ -97,11 +108,8 @@ armada_370_xp_clkevt_next_event(unsigned + /* + * Enable the timer. + */ +- u = readl(local_base + TIMER_CTRL_OFF); +- u = ((u & ~TIMER0_RELOAD_EN) | TIMER0_EN | +- TIMER0_DIV(TIMER_DIVIDER_SHIFT)); +- writel(u, local_base + TIMER_CTRL_OFF); +- ++ local_timer_ctrl_clrset(TIMER0_RELOAD_EN, ++ TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); + return 0; + } + +@@ -109,8 +117,6 @@ static void + armada_370_xp_clkevt_mode(enum clock_event_mode mode, + struct clock_event_device *dev) + { +- u32 u; +- + if (mode == CLOCK_EVT_MODE_PERIODIC) { + + /* +@@ -122,18 +128,14 @@ armada_370_xp_clkevt_mode(enum clock_eve + /* + * Enable timer. + */ +- +- u = readl(local_base + TIMER_CTRL_OFF); +- +- writel((u | TIMER0_EN | TIMER0_RELOAD_EN | +- TIMER0_DIV(TIMER_DIVIDER_SHIFT)), +- local_base + TIMER_CTRL_OFF); ++ local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | ++ TIMER0_EN | ++ TIMER0_DIV(TIMER_DIVIDER_SHIFT)); + } else { + /* + * Disable timer. + */ +- u = readl(local_base + TIMER_CTRL_OFF); +- writel(u & ~TIMER0_EN, local_base + TIMER_CTRL_OFF); ++ local_timer_ctrl_clrset(TIMER0_EN, 0); + + /* + * ACK pending timer interrupt. +@@ -169,18 +171,18 @@ static irqreturn_t armada_370_xp_timer_i + */ + static int __cpuinit armada_370_xp_timer_setup(struct clock_event_device *evt) + { +- u32 u; ++ u32 clr = 0, set = 0; + int cpu = smp_processor_id(); + + /* Use existing clock_event for cpu 0 */ + if (!smp_processor_id()) + return 0; + +- u = readl(local_base + TIMER_CTRL_OFF); + if (timer25Mhz) +- writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); ++ set = TIMER0_25MHZ; + 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->irq = armada_370_xp_clkevt.irq; +@@ -212,7 +214,7 @@ static struct local_timer_ops armada_370 + + static void __init armada_370_xp_timer_init(struct device_node *np) + { +- u32 u; ++ u32 clr = 0, set = 0; + int res; + + timer_base = of_iomap(np, 0); +@@ -221,29 +223,20 @@ static void __init armada_370_xp_timer_i + + if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { + /* The fixed 25MHz timer is available so let's use it */ +- 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); ++ set = TIMER0_25MHZ; + timer_clk = 25000000; + } else { + unsigned long rate = 0; + struct clk *clk = of_clk_get(np, 0); + WARN_ON(IS_ERR(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; ++ ++ clr = TIMER0_25MHZ; + timer25Mhz = false; + } ++ timer_ctrl_clrset(clr, set); ++ local_timer_ctrl_clrset(clr, set); + + /* + * We use timer 0 as clocksource, and private(local) timer 0 +@@ -265,10 +258,8 @@ static void __init armada_370_xp_timer_i + writel(0xffffffff, timer_base + TIMER0_VAL_OFF); + writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); + +- u = readl(timer_base + TIMER_CTRL_OFF); +- +- writel((u | TIMER0_EN | TIMER0_RELOAD_EN | +- TIMER0_DIV(TIMER_DIVIDER_SHIFT)), timer_base + TIMER_CTRL_OFF); ++ timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN | ++ TIMER0_DIV(TIMER_DIVIDER_SHIFT)); + + clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, + "armada_370_xp_clocksource", |