From ad48bd618f3761922c53f08e05fe00f3c85ca275 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 13 Aug 2013 11:43:10 -0300 Subject: clocksource: armada-370-xp: Use BIT() This is a purely cosmetic commit: we replace hardcoded values that representing bits by BIT(), which is slightly more readable. Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano Reviewed-by: Andrew Lunn --- drivers/clocksource/time-armada-370-xp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/clocksource/time-armada-370-xp.c') diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 1b04b7e1d39b..a3d273943bce 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c @@ -35,13 +35,13 @@ * Timer block registers. */ #define TIMER_CTRL_OFF 0x0000 -#define TIMER0_EN 0x0001 -#define TIMER0_RELOAD_EN 0x0002 -#define TIMER0_25MHZ 0x0800 +#define TIMER0_EN BIT(0) +#define TIMER0_RELOAD_EN BIT(1) +#define TIMER0_25MHZ BIT(11) #define TIMER0_DIV(div) ((div) << 19) -#define TIMER1_EN 0x0004 -#define TIMER1_RELOAD_EN 0x0008 -#define TIMER1_25MHZ 0x1000 +#define TIMER1_EN BIT(2) +#define TIMER1_RELOAD_EN BIT(3) +#define TIMER1_25MHZ BIT(12) #define TIMER1_DIV(div) ((div) << 22) #define TIMER_EVENTS_STATUS 0x0004 #define TIMER0_CLR_MASK (~0x1) -- cgit v1.2.2 From 3579698e85ef9984e698ac3d8e2257a1adeeb722 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 13 Aug 2013 11:43:11 -0300 Subject: 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 Reviewed-by: Andrew Lunn Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano --- drivers/clocksource/time-armada-370-xp.c | 69 ++++++++++++++------------------ 1 file changed, 30 insertions(+), 39 deletions(-) (limited to 'drivers/clocksource/time-armada-370-xp.c') diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index a3d273943bce..abc2c9f04821 100644 --- 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 long delta, /* * 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_event_mode mode, /* * 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_interrupt(int irq, void *dev_id) */ static int 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_xp_local_timer_ops = { void __init armada_370_xp_timer_init(void) { - u32 u; + u32 clr = 0, set = 0; struct device_node *np; int res; @@ -223,29 +225,20 @@ void __init armada_370_xp_timer_init(void) 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 @@ -267,10 +260,8 @@ void __init armada_370_xp_timer_init(void) 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", -- cgit v1.2.2 From 573145f08c2b92c45498468afbbba909f6ce6135 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 13 Aug 2013 11:43:12 -0300 Subject: clocksource: armada-370-xp: Use CLOCKSOURCE_OF_DECLARE This is almost cosmetic: we achieve a bit of consistency with other clocksource drivers by using the CLOCKSOURCE_OF_DECLARE macro for the boilerplate code. Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano Reviewed-by: Andrew Lunn --- drivers/clocksource/time-armada-370-xp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/clocksource/time-armada-370-xp.c') diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index abc2c9f04821..1e4b523f27c1 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c @@ -212,13 +212,11 @@ static struct local_timer_ops armada_370_xp_local_timer_ops = { .stop = armada_370_xp_timer_stop, }; -void __init armada_370_xp_timer_init(void) +static void __init armada_370_xp_timer_init(struct device_node *np) { u32 clr = 0, set = 0; - struct device_node *np; int res; - np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer"); timer_base = of_iomap(np, 0); WARN_ON(!timer_base); local_base = of_iomap(np, 1); @@ -290,3 +288,5 @@ void __init armada_370_xp_timer_init(void) #endif } } +CLOCKSOURCE_OF_DECLARE(armada_370_xp, "marvell,armada-370-xp-timer", + armada_370_xp_timer_init); -- cgit v1.2.2 From 7cd6392c9bf5da6986103fcf5ca1b6fd0489d9b4 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 13 Aug 2013 11:43:13 -0300 Subject: clocksource: armada-370-xp: Introduce new compatibles The Armada XP SoC clocksource driver cannot work without the 25 MHz fixed timer. Therefore it's appropriate to introduce a new compatible string and use it to set the 25 MHz fixed timer. The 'marvell,timer-25MHz' property will be marked as deprecated. Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano Reviewed-by: Andrew Lunn --- drivers/clocksource/time-armada-370-xp.c | 54 +++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 15 deletions(-) (limited to 'drivers/clocksource/time-armada-370-xp.c') diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 1e4b523f27c1..86a354cca215 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c @@ -13,6 +13,19 @@ * * Timer 0 is used as free-running clocksource, while timer 1 is * used as clock_event_device. + * + * --- + * Clocksource driver for Armada 370 and Armada XP SoC. + * This driver implements one compatible string for each SoC, given + * each has its own characteristics: + * + * * Armada 370 has no 25 MHz fixed timer. + * + * * Armada XP cannot work properly without such 25 MHz fixed timer as + * doing otherwise leads to using a clocksource whose frequency varies + * when doing cpufreq frequency changes. + * + * See Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt */ #include @@ -212,7 +225,7 @@ static struct local_timer_ops armada_370_xp_local_timer_ops = { .stop = armada_370_xp_timer_stop, }; -static void __init armada_370_xp_timer_init(struct device_node *np) +static void __init armada_370_xp_timer_common_init(struct device_node *np) { u32 clr = 0, set = 0; int res; @@ -221,20 +234,10 @@ static void __init armada_370_xp_timer_init(struct device_node *np) WARN_ON(!timer_base); local_base = of_iomap(np, 1); - if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { - /* The fixed 25MHz timer is available so let's use it */ + if (timer25Mhz) 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); - timer_clk = rate / TIMER_DIVIDER; - + else clr = TIMER0_25MHZ; - timer25Mhz = false; - } timer_ctrl_clrset(clr, set); local_timer_ctrl_clrset(clr, set); @@ -288,5 +291,26 @@ static void __init armada_370_xp_timer_init(struct device_node *np) #endif } } -CLOCKSOURCE_OF_DECLARE(armada_370_xp, "marvell,armada-370-xp-timer", - armada_370_xp_timer_init); + +static void __init armada_xp_timer_init(struct device_node *np) +{ + /* The fixed 25MHz timer is required, timer25Mhz is true by default */ + timer_clk = 25000000; + + armada_370_xp_timer_common_init(np); +} +CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", + armada_xp_timer_init); + +static void __init armada_370_timer_init(struct device_node *np) +{ + struct clk *clk = of_clk_get(np, 0); + + WARN_ON(IS_ERR(clk)); + timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; + timer25Mhz = false; + + armada_370_xp_timer_common_init(np); +} +CLOCKSOURCE_OF_DECLARE(armada_370, "marvell,armada-370-timer", + armada_370_timer_init); -- cgit v1.2.2 From ec8e51120a5b167e22ee29f4f427a0cb66eb445b Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 20 Aug 2013 12:45:52 -0300 Subject: clocksource: armada-370-xp: Replace WARN_ON with BUG_ON If the clock fails to be obtained and the timer fails to be properly registered, the kernel will freeze real soon. Instead, let's BUG() where the actual problem is located. Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano Acked-by: Jason Cooper Acked-by: Gregory CLEMENT --- drivers/clocksource/time-armada-370-xp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource/time-armada-370-xp.c') diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 86a354cca215..6ca185df48c4 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c @@ -306,7 +306,7 @@ static void __init armada_370_timer_init(struct device_node *np) { struct clk *clk = of_clk_get(np, 0); - WARN_ON(IS_ERR(clk)); + BUG_ON(IS_ERR(clk)); timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; timer25Mhz = false; -- cgit v1.2.2 From 5e9fe6cb1ba5ad321473e7b9c39fbe164129520d Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 20 Aug 2013 12:45:53 -0300 Subject: clocksource: armada-370-xp: Get reference fixed-clock by name The Armada XP timer has two mandatory clock inputs: nbclk and refclk, as specified by the device-tree binding. This commit fixes the clock selection. Instead of hard-coding the clock rate for the 25 MHz reference fixed-clock, obtain the clock by its name. Signed-off-by: Ezequiel Garcia Signed-off-by: Daniel Lezcano Acked-by: Jason Cooper Acked-by: Gregory CLEMENT --- drivers/clocksource/time-armada-370-xp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/clocksource/time-armada-370-xp.c') diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 6ca185df48c4..44c4fff2f58c 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c @@ -294,8 +294,11 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np) static void __init armada_xp_timer_init(struct device_node *np) { - /* The fixed 25MHz timer is required, timer25Mhz is true by default */ - timer_clk = 25000000; + struct clk *clk = of_clk_get_by_name(np, "fixed"); + + /* The 25Mhz fixed clock is mandatory, and must always be available */ + BUG_ON(IS_ERR(clk)); + timer_clk = clk_get_rate(clk); armada_370_xp_timer_common_init(np); } -- cgit v1.2.2