aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-16 16:10:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-16 16:10:26 -0400
commita4ae54f90e0a7063799eb90852aa8648ccfbb791 (patch)
tree88fd7f7920c8849fed99c782ab1fc605da69a375 /drivers
parent3369d116934b70bd2755cdd8b2af9741d18a4047 (diff)
parent63ce2cc474ce962d936ae6dfaa6ae2354b1db5b2 (diff)
Merge branch 'timers/core' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer code update from Thomas Gleixner: - armada SoC clocksource overhaul with a trivial merge conflict - Minor improvements to various SoC clocksource drivers * 'timers/core' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: clocksource: armada-370-xp: Add detailed clock requirements in devicetree binding clocksource: armada-370-xp: Get reference fixed-clock by name clocksource: armada-370-xp: Replace WARN_ON with BUG_ON clocksource: armada-370-xp: Fix device-tree binding clocksource: armada-370-xp: Introduce new compatibles clocksource: armada-370-xp: Use CLOCKSOURCE_OF_DECLARE clocksource: armada-370-xp: Simplify TIMER_CTRL register access clocksource: armada-370-xp: Use BIT() ARM: timer-sp: Set dynamic irq affinity ARM: nomadik: add dynamic irq flag to the timer clocksource: sh_cmt: 32-bit control register support clocksource: em_sti: Convert to devm_* managed helpers
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clocksource/em_sti.c49
-rw-r--r--drivers/clocksource/nomadik-mtu.c3
-rw-r--r--drivers/clocksource/sh_cmt.c50
-rw-r--r--drivers/clocksource/time-armada-370-xp.c131
4 files changed, 129 insertions, 104 deletions
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c
index 4329a29a5310..b9c81b7c3a3b 100644
--- a/drivers/clocksource/em_sti.c
+++ b/drivers/clocksource/em_sti.c
@@ -315,68 +315,47 @@ static int em_sti_probe(struct platform_device *pdev)
315{ 315{
316 struct em_sti_priv *p; 316 struct em_sti_priv *p;
317 struct resource *res; 317 struct resource *res;
318 int irq, ret; 318 int irq;
319 319
320 p = kzalloc(sizeof(*p), GFP_KERNEL); 320 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
321 if (p == NULL) { 321 if (p == NULL) {
322 dev_err(&pdev->dev, "failed to allocate driver data\n"); 322 dev_err(&pdev->dev, "failed to allocate driver data\n");
323 ret = -ENOMEM; 323 return -ENOMEM;
324 goto err0;
325 } 324 }
326 325
327 p->pdev = pdev; 326 p->pdev = pdev;
328 platform_set_drvdata(pdev, p); 327 platform_set_drvdata(pdev, p);
329 328
330 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
331 if (!res) {
332 dev_err(&pdev->dev, "failed to get I/O memory\n");
333 ret = -EINVAL;
334 goto err0;
335 }
336
337 irq = platform_get_irq(pdev, 0); 329 irq = platform_get_irq(pdev, 0);
338 if (irq < 0) { 330 if (irq < 0) {
339 dev_err(&pdev->dev, "failed to get irq\n"); 331 dev_err(&pdev->dev, "failed to get irq\n");
340 ret = -EINVAL; 332 return -EINVAL;
341 goto err0;
342 } 333 }
343 334
344 /* map memory, let base point to the STI instance */ 335 /* map memory, let base point to the STI instance */
345 p->base = ioremap_nocache(res->start, resource_size(res)); 336 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
346 if (p->base == NULL) { 337 p->base = devm_ioremap_resource(&pdev->dev, res);
347 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 338 if (IS_ERR(p->base))
348 ret = -ENXIO; 339 return PTR_ERR(p->base);
349 goto err0;
350 }
351 340
352 /* get hold of clock */ 341 /* get hold of clock */
353 p->clk = clk_get(&pdev->dev, "sclk"); 342 p->clk = devm_clk_get(&pdev->dev, "sclk");
354 if (IS_ERR(p->clk)) { 343 if (IS_ERR(p->clk)) {
355 dev_err(&pdev->dev, "cannot get clock\n"); 344 dev_err(&pdev->dev, "cannot get clock\n");
356 ret = PTR_ERR(p->clk); 345 return PTR_ERR(p->clk);
357 goto err1;
358 } 346 }
359 347
360 if (request_irq(irq, em_sti_interrupt, 348 if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
361 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, 349 IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
362 dev_name(&pdev->dev), p)) { 350 dev_name(&pdev->dev), p)) {
363 dev_err(&pdev->dev, "failed to request low IRQ\n"); 351 dev_err(&pdev->dev, "failed to request low IRQ\n");
364 ret = -ENOENT; 352 return -ENOENT;
365 goto err2;
366 } 353 }
367 354
368 raw_spin_lock_init(&p->lock); 355 raw_spin_lock_init(&p->lock);
369 em_sti_register_clockevent(p); 356 em_sti_register_clockevent(p);
370 em_sti_register_clocksource(p); 357 em_sti_register_clocksource(p);
371 return 0; 358 return 0;
372
373err2:
374 clk_put(p->clk);
375err1:
376 iounmap(p->base);
377err0:
378 kfree(p);
379 return ret;
380} 359}
381 360
382static int em_sti_remove(struct platform_device *pdev) 361static int em_sti_remove(struct platform_device *pdev)
diff --git a/drivers/clocksource/nomadik-mtu.c b/drivers/clocksource/nomadik-mtu.c
index 7d2c2c56f73c..1b74bea12385 100644
--- a/drivers/clocksource/nomadik-mtu.c
+++ b/drivers/clocksource/nomadik-mtu.c
@@ -165,7 +165,8 @@ static void nmdk_clkevt_resume(struct clock_event_device *cedev)
165 165
166static struct clock_event_device nmdk_clkevt = { 166static struct clock_event_device nmdk_clkevt = {
167 .name = "mtu_1", 167 .name = "mtu_1",
168 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 168 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC |
169 CLOCK_EVT_FEAT_DYNIRQ,
169 .rating = 200, 170 .rating = 200,
170 .set_mode = nmdk_clkevt_mode, 171 .set_mode = nmdk_clkevt_mode,
171 .set_next_event = nmdk_clkevt_next, 172 .set_next_event = nmdk_clkevt_next,
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 08d0c418c94a..0965e9848b3d 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -37,6 +37,7 @@
37 37
38struct sh_cmt_priv { 38struct sh_cmt_priv {
39 void __iomem *mapbase; 39 void __iomem *mapbase;
40 void __iomem *mapbase_str;
40 struct clk *clk; 41 struct clk *clk;
41 unsigned long width; /* 16 or 32 bit version of hardware block */ 42 unsigned long width; /* 16 or 32 bit version of hardware block */
42 unsigned long overflow_bit; 43 unsigned long overflow_bit;
@@ -79,6 +80,12 @@ struct sh_cmt_priv {
79 * CMCSR 0xffca0060 16-bit 80 * CMCSR 0xffca0060 16-bit
80 * CMCNT 0xffca0064 32-bit 81 * CMCNT 0xffca0064 32-bit
81 * CMCOR 0xffca0068 32-bit 82 * CMCOR 0xffca0068 32-bit
83 *
84 * "32-bit counter and 32-bit control" as found on r8a73a4 and r8a7790:
85 * CMSTR 0xffca0500 32-bit
86 * CMCSR 0xffca0510 32-bit
87 * CMCNT 0xffca0514 32-bit
88 * CMCOR 0xffca0518 32-bit
82 */ 89 */
83 90
84static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs) 91static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs)
@@ -109,9 +116,7 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs,
109 116
110static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) 117static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p)
111{ 118{
112 struct sh_timer_config *cfg = p->pdev->dev.platform_data; 119 return p->read_control(p->mapbase_str, 0);
113
114 return p->read_control(p->mapbase - cfg->channel_offset, 0);
115} 120}
116 121
117static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) 122static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p)
@@ -127,9 +132,7 @@ static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p)
127static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, 132static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p,
128 unsigned long value) 133 unsigned long value)
129{ 134{
130 struct sh_timer_config *cfg = p->pdev->dev.platform_data; 135 p->write_control(p->mapbase_str, 0, value);
131
132 p->write_control(p->mapbase - cfg->channel_offset, 0, value);
133} 136}
134 137
135static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, 138static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p,
@@ -676,7 +679,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name,
676static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) 679static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
677{ 680{
678 struct sh_timer_config *cfg = pdev->dev.platform_data; 681 struct sh_timer_config *cfg = pdev->dev.platform_data;
679 struct resource *res; 682 struct resource *res, *res2;
680 int irq, ret; 683 int irq, ret;
681 ret = -ENXIO; 684 ret = -ENXIO;
682 685
@@ -694,6 +697,9 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
694 goto err0; 697 goto err0;
695 } 698 }
696 699
700 /* optional resource for the shared timer start/stop register */
701 res2 = platform_get_resource(p->pdev, IORESOURCE_MEM, 1);
702
697 irq = platform_get_irq(p->pdev, 0); 703 irq = platform_get_irq(p->pdev, 0);
698 if (irq < 0) { 704 if (irq < 0) {
699 dev_err(&p->pdev->dev, "failed to get irq\n"); 705 dev_err(&p->pdev->dev, "failed to get irq\n");
@@ -707,6 +713,15 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
707 goto err0; 713 goto err0;
708 } 714 }
709 715
716 /* map second resource for CMSTR */
717 p->mapbase_str = ioremap_nocache(res2 ? res2->start :
718 res->start - cfg->channel_offset,
719 res2 ? resource_size(res2) : 2);
720 if (p->mapbase_str == NULL) {
721 dev_err(&p->pdev->dev, "failed to remap I/O second memory\n");
722 goto err1;
723 }
724
710 /* request irq using setup_irq() (too early for request_irq()) */ 725 /* request irq using setup_irq() (too early for request_irq()) */
711 p->irqaction.name = dev_name(&p->pdev->dev); 726 p->irqaction.name = dev_name(&p->pdev->dev);
712 p->irqaction.handler = sh_cmt_interrupt; 727 p->irqaction.handler = sh_cmt_interrupt;
@@ -719,11 +734,17 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
719 if (IS_ERR(p->clk)) { 734 if (IS_ERR(p->clk)) {
720 dev_err(&p->pdev->dev, "cannot get clock\n"); 735 dev_err(&p->pdev->dev, "cannot get clock\n");
721 ret = PTR_ERR(p->clk); 736 ret = PTR_ERR(p->clk);
722 goto err1; 737 goto err2;
723 } 738 }
724 739
725 p->read_control = sh_cmt_read16; 740 if (res2 && (resource_size(res2) == 4)) {
726 p->write_control = sh_cmt_write16; 741 /* assume both CMSTR and CMCSR to be 32-bit */
742 p->read_control = sh_cmt_read32;
743 p->write_control = sh_cmt_write32;
744 } else {
745 p->read_control = sh_cmt_read16;
746 p->write_control = sh_cmt_write16;
747 }
727 748
728 if (resource_size(res) == 6) { 749 if (resource_size(res) == 6) {
729 p->width = 16; 750 p->width = 16;
@@ -752,22 +773,23 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
752 cfg->clocksource_rating); 773 cfg->clocksource_rating);
753 if (ret) { 774 if (ret) {
754 dev_err(&p->pdev->dev, "registration failed\n"); 775 dev_err(&p->pdev->dev, "registration failed\n");
755 goto err2; 776 goto err3;
756 } 777 }
757 p->cs_enabled = false; 778 p->cs_enabled = false;
758 779
759 ret = setup_irq(irq, &p->irqaction); 780 ret = setup_irq(irq, &p->irqaction);
760 if (ret) { 781 if (ret) {
761 dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); 782 dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
762 goto err2; 783 goto err3;
763 } 784 }
764 785
765 platform_set_drvdata(pdev, p); 786 platform_set_drvdata(pdev, p);
766 787
767 return 0; 788 return 0;
768err2: 789err3:
769 clk_put(p->clk); 790 clk_put(p->clk);
770 791err2:
792 iounmap(p->mapbase_str);
771err1: 793err1:
772 iounmap(p->mapbase); 794 iounmap(p->mapbase);
773err0: 795err0:
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c
index 847cab6f6e31..0198504ef6b0 100644
--- a/drivers/clocksource/time-armada-370-xp.c
+++ b/drivers/clocksource/time-armada-370-xp.c
@@ -13,6 +13,19 @@
13 * 13 *
14 * Timer 0 is used as free-running clocksource, while timer 1 is 14 * Timer 0 is used as free-running clocksource, while timer 1 is
15 * used as clock_event_device. 15 * used as clock_event_device.
16 *
17 * ---
18 * Clocksource driver for Armada 370 and Armada XP SoC.
19 * This driver implements one compatible string for each SoC, given
20 * each has its own characteristics:
21 *
22 * * Armada 370 has no 25 MHz fixed timer.
23 *
24 * * Armada XP cannot work properly without such 25 MHz fixed timer as
25 * doing otherwise leads to using a clocksource whose frequency varies
26 * when doing cpufreq frequency changes.
27 *
28 * See Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt
16 */ 29 */
17 30
18#include <linux/init.h> 31#include <linux/init.h>
@@ -30,19 +43,18 @@
30#include <linux/module.h> 43#include <linux/module.h>
31#include <linux/sched_clock.h> 44#include <linux/sched_clock.h>
32#include <linux/percpu.h> 45#include <linux/percpu.h>
33#include <linux/time-armada-370-xp.h>
34 46
35/* 47/*
36 * Timer block registers. 48 * Timer block registers.
37 */ 49 */
38#define TIMER_CTRL_OFF 0x0000 50#define TIMER_CTRL_OFF 0x0000
39#define TIMER0_EN 0x0001 51#define TIMER0_EN BIT(0)
40#define TIMER0_RELOAD_EN 0x0002 52#define TIMER0_RELOAD_EN BIT(1)
41#define TIMER0_25MHZ 0x0800 53#define TIMER0_25MHZ BIT(11)
42#define TIMER0_DIV(div) ((div) << 19) 54#define TIMER0_DIV(div) ((div) << 19)
43#define TIMER1_EN 0x0004 55#define TIMER1_EN BIT(2)
44#define TIMER1_RELOAD_EN 0x0008 56#define TIMER1_RELOAD_EN BIT(3)
45#define TIMER1_25MHZ 0x1000 57#define TIMER1_25MHZ BIT(12)
46#define TIMER1_DIV(div) ((div) << 22) 58#define TIMER1_DIV(div) ((div) << 22)
47#define TIMER_EVENTS_STATUS 0x0004 59#define TIMER_EVENTS_STATUS 0x0004
48#define TIMER0_CLR_MASK (~0x1) 60#define TIMER0_CLR_MASK (~0x1)
@@ -72,6 +84,18 @@ static u32 ticks_per_jiffy;
72 84
73static struct clock_event_device __percpu *armada_370_xp_evt; 85static struct clock_event_device __percpu *armada_370_xp_evt;
74 86
87static void timer_ctrl_clrset(u32 clr, u32 set)
88{
89 writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set,
90 timer_base + TIMER_CTRL_OFF);
91}
92
93static void local_timer_ctrl_clrset(u32 clr, u32 set)
94{
95 writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set,
96 local_base + TIMER_CTRL_OFF);
97}
98
75static u32 notrace armada_370_xp_read_sched_clock(void) 99static u32 notrace armada_370_xp_read_sched_clock(void)
76{ 100{
77 return ~readl(timer_base + TIMER0_VAL_OFF); 101 return ~readl(timer_base + TIMER0_VAL_OFF);
@@ -84,7 +108,6 @@ static int
84armada_370_xp_clkevt_next_event(unsigned long delta, 108armada_370_xp_clkevt_next_event(unsigned long delta,
85 struct clock_event_device *dev) 109 struct clock_event_device *dev)
86{ 110{
87 u32 u;
88 /* 111 /*
89 * Clear clockevent timer interrupt. 112 * Clear clockevent timer interrupt.
90 */ 113 */
@@ -98,11 +121,8 @@ armada_370_xp_clkevt_next_event(unsigned long delta,
98 /* 121 /*
99 * Enable the timer. 122 * Enable the timer.
100 */ 123 */
101 u = readl(local_base + TIMER_CTRL_OFF); 124 local_timer_ctrl_clrset(TIMER0_RELOAD_EN,
102 u = ((u & ~TIMER0_RELOAD_EN) | TIMER0_EN | 125 TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT));
103 TIMER0_DIV(TIMER_DIVIDER_SHIFT));
104 writel(u, local_base + TIMER_CTRL_OFF);
105
106 return 0; 126 return 0;
107} 127}
108 128
@@ -110,8 +130,6 @@ static void
110armada_370_xp_clkevt_mode(enum clock_event_mode mode, 130armada_370_xp_clkevt_mode(enum clock_event_mode mode,
111 struct clock_event_device *dev) 131 struct clock_event_device *dev)
112{ 132{
113 u32 u;
114
115 if (mode == CLOCK_EVT_MODE_PERIODIC) { 133 if (mode == CLOCK_EVT_MODE_PERIODIC) {
116 134
117 /* 135 /*
@@ -123,18 +141,14 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode,
123 /* 141 /*
124 * Enable timer. 142 * Enable timer.
125 */ 143 */
126 144 local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN |
127 u = readl(local_base + TIMER_CTRL_OFF); 145 TIMER0_EN |
128 146 TIMER0_DIV(TIMER_DIVIDER_SHIFT));
129 writel((u | TIMER0_EN | TIMER0_RELOAD_EN |
130 TIMER0_DIV(TIMER_DIVIDER_SHIFT)),
131 local_base + TIMER_CTRL_OFF);
132 } else { 147 } else {
133 /* 148 /*
134 * Disable timer. 149 * Disable timer.
135 */ 150 */
136 u = readl(local_base + TIMER_CTRL_OFF); 151 local_timer_ctrl_clrset(TIMER0_EN, 0);
137 writel(u & ~TIMER0_EN, local_base + TIMER_CTRL_OFF);
138 152
139 /* 153 /*
140 * ACK pending timer interrupt. 154 * ACK pending timer interrupt.
@@ -163,14 +177,14 @@ static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id)
163 */ 177 */
164static int armada_370_xp_timer_setup(struct clock_event_device *evt) 178static int armada_370_xp_timer_setup(struct clock_event_device *evt)
165{ 179{
166 u32 u; 180 u32 clr = 0, set = 0;
167 int cpu = smp_processor_id(); 181 int cpu = smp_processor_id();
168 182
169 u = readl(local_base + TIMER_CTRL_OFF);
170 if (timer25Mhz) 183 if (timer25Mhz)
171 writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); 184 set = TIMER0_25MHZ;
172 else 185 else
173 writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); 186 clr = TIMER0_25MHZ;
187 local_timer_ctrl_clrset(clr, set);
174 188
175 evt->name = "armada_370_xp_per_cpu_tick", 189 evt->name = "armada_370_xp_per_cpu_tick",
176 evt->features = CLOCK_EVT_FEAT_ONESHOT | 190 evt->features = CLOCK_EVT_FEAT_ONESHOT |
@@ -217,36 +231,21 @@ static struct notifier_block armada_370_xp_timer_cpu_nb = {
217 .notifier_call = armada_370_xp_timer_cpu_notify, 231 .notifier_call = armada_370_xp_timer_cpu_notify,
218}; 232};
219 233
220void __init armada_370_xp_timer_init(void) 234static void __init armada_370_xp_timer_common_init(struct device_node *np)
221{ 235{
222 u32 u; 236 u32 clr = 0, set = 0;
223 struct device_node *np;
224 int res; 237 int res;
225 238
226 np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
227 timer_base = of_iomap(np, 0); 239 timer_base = of_iomap(np, 0);
228 WARN_ON(!timer_base); 240 WARN_ON(!timer_base);
229 local_base = of_iomap(np, 1); 241 local_base = of_iomap(np, 1);
230 242
231 if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { 243 if (timer25Mhz)
232 /* The fixed 25MHz timer is available so let's use it */ 244 set = TIMER0_25MHZ;
233 u = readl(timer_base + TIMER_CTRL_OFF); 245 else
234 writel(u | TIMER0_25MHZ, 246 clr = TIMER0_25MHZ;
235 timer_base + TIMER_CTRL_OFF); 247 timer_ctrl_clrset(clr, set);
236 timer_clk = 25000000; 248 local_timer_ctrl_clrset(clr, set);
237 } else {
238 unsigned long rate = 0;
239 struct clk *clk = of_clk_get(np, 0);
240 WARN_ON(IS_ERR(clk));
241 rate = clk_get_rate(clk);
242
243 u = readl(timer_base + TIMER_CTRL_OFF);
244 writel(u & ~(TIMER0_25MHZ),
245 timer_base + TIMER_CTRL_OFF);
246
247 timer_clk = rate / TIMER_DIVIDER;
248 timer25Mhz = false;
249 }
250 249
251 /* 250 /*
252 * We use timer 0 as clocksource, and private(local) timer 0 251 * We use timer 0 as clocksource, and private(local) timer 0
@@ -268,10 +267,8 @@ void __init armada_370_xp_timer_init(void)
268 writel(0xffffffff, timer_base + TIMER0_VAL_OFF); 267 writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
269 writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); 268 writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
270 269
271 u = readl(timer_base + TIMER_CTRL_OFF); 270 timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN |
272 271 TIMER0_DIV(TIMER_DIVIDER_SHIFT));
273 writel((u | TIMER0_EN | TIMER0_RELOAD_EN |
274 TIMER0_DIV(TIMER_DIVIDER_SHIFT)), timer_base + TIMER_CTRL_OFF);
275 272
276 clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, 273 clocksource_mmio_init(timer_base + TIMER0_VAL_OFF,
277 "armada_370_xp_clocksource", 274 "armada_370_xp_clocksource",
@@ -293,3 +290,29 @@ void __init armada_370_xp_timer_init(void)
293 if (!res) 290 if (!res)
294 armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); 291 armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt));
295} 292}
293
294static void __init armada_xp_timer_init(struct device_node *np)
295{
296 struct clk *clk = of_clk_get_by_name(np, "fixed");
297
298 /* The 25Mhz fixed clock is mandatory, and must always be available */
299 BUG_ON(IS_ERR(clk));
300 timer_clk = clk_get_rate(clk);
301
302 armada_370_xp_timer_common_init(np);
303}
304CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
305 armada_xp_timer_init);
306
307static void __init armada_370_timer_init(struct device_node *np)
308{
309 struct clk *clk = of_clk_get(np, 0);
310
311 BUG_ON(IS_ERR(clk));
312 timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
313 timer25Mhz = false;
314
315 armada_370_xp_timer_common_init(np);
316}
317CLOCKSOURCE_OF_DECLARE(armada_370, "marvell,armada-370-timer",
318 armada_370_timer_init);