aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-vt8500/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-vt8500/timer.c')
-rw-r--r--arch/arm/mach-vt8500/timer.c67
1 files changed, 48 insertions, 19 deletions
diff --git a/arch/arm/mach-vt8500/timer.c b/arch/arm/mach-vt8500/timer.c
index d5376c592ab6..050e1833f2d0 100644
--- a/arch/arm/mach-vt8500/timer.c
+++ b/arch/arm/mach-vt8500/timer.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * arch/arm/mach-vt8500/timer.c 2 * arch/arm/mach-vt8500/timer_dt.c
3 * 3 *
4 * Copyright (C) 2012 Tony Prisk <linux@prisktech.co.nz>
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> 5 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -18,18 +19,25 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 20 */
20 21
22/*
23 * This file is copied and modified from the original timer.c provided by
24 * Alexey Charkov. Minor changes have been made for Device Tree Support.
25 */
26
21#include <linux/io.h> 27#include <linux/io.h>
22#include <linux/irq.h> 28#include <linux/irq.h>
23#include <linux/interrupt.h> 29#include <linux/interrupt.h>
24#include <linux/clocksource.h> 30#include <linux/clocksource.h>
25#include <linux/clockchips.h> 31#include <linux/clockchips.h>
26#include <linux/delay.h> 32#include <linux/delay.h>
27
28#include <asm/mach/time.h> 33#include <asm/mach/time.h>
29 34
30#include "devices.h" 35#include <linux/of.h>
36#include <linux/of_address.h>
37#include <linux/of_irq.h>
31 38
32#define VT8500_TIMER_OFFSET 0x0100 39#define VT8500_TIMER_OFFSET 0x0100
40#define VT8500_TIMER_HZ 3000000
33#define TIMER_MATCH_VAL 0x0000 41#define TIMER_MATCH_VAL 0x0000
34#define TIMER_COUNT_VAL 0x0010 42#define TIMER_COUNT_VAL 0x0010
35#define TIMER_STATUS_VAL 0x0014 43#define TIMER_STATUS_VAL 0x0014
@@ -39,7 +47,6 @@
39#define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */ 47#define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */
40#define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */ 48#define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */
41#define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */ 49#define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */
42#define VT8500_TIMER_HZ 3000000
43 50
44#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 51#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
45 52
@@ -55,7 +62,7 @@ static cycle_t vt8500_timer_read(struct clocksource *cs)
55 return readl(regbase + TIMER_COUNT_VAL); 62 return readl(regbase + TIMER_COUNT_VAL);
56} 63}
57 64
58struct clocksource clocksource = { 65static struct clocksource clocksource = {
59 .name = "vt8500_timer", 66 .name = "vt8500_timer",
60 .rating = 200, 67 .rating = 200,
61 .read = vt8500_timer_read, 68 .read = vt8500_timer_read,
@@ -98,7 +105,7 @@ static void vt8500_timer_set_mode(enum clock_event_mode mode,
98 } 105 }
99} 106}
100 107
101struct clock_event_device clockevent = { 108static struct clock_event_device clockevent = {
102 .name = "vt8500_timer", 109 .name = "vt8500_timer",
103 .features = CLOCK_EVT_FEAT_ONESHOT, 110 .features = CLOCK_EVT_FEAT_ONESHOT,
104 .rating = 200, 111 .rating = 200,
@@ -115,26 +122,51 @@ static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
115 return IRQ_HANDLED; 122 return IRQ_HANDLED;
116} 123}
117 124
118struct irqaction irq = { 125static struct irqaction irq = {
119 .name = "vt8500_timer", 126 .name = "vt8500_timer",
120 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 127 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
121 .handler = vt8500_timer_interrupt, 128 .handler = vt8500_timer_interrupt,
122 .dev_id = &clockevent, 129 .dev_id = &clockevent,
123}; 130};
124 131
125static void __init vt8500_timer_init(void) 132static struct of_device_id vt8500_timer_ids[] = {
133 { .compatible = "via,vt8500-timer" },
134 { }
135};
136
137void __init vt8500_timer_init(void)
126{ 138{
127 regbase = ioremap(wmt_pmc_base + VT8500_TIMER_OFFSET, 0x28); 139 struct device_node *np;
128 if (!regbase) 140 int timer_irq;
129 printk(KERN_ERR "vt8500_timer_init: failed to map MMIO registers\n"); 141
142 np = of_find_matching_node(NULL, vt8500_timer_ids);
143 if (!np) {
144 pr_err("%s: Timer description missing from Device Tree\n",
145 __func__);
146 return;
147 }
148 regbase = of_iomap(np, 0);
149 if (!regbase) {
150 pr_err("%s: Missing iobase description in Device Tree\n",
151 __func__);
152 of_node_put(np);
153 return;
154 }
155 timer_irq = irq_of_parse_and_map(np, 0);
156 if (!timer_irq) {
157 pr_err("%s: Missing irq description in Device Tree\n",
158 __func__);
159 of_node_put(np);
160 return;
161 }
130 162
131 writel(1, regbase + TIMER_CTRL_VAL); 163 writel(1, regbase + TIMER_CTRL_VAL);
132 writel(0xf, regbase + TIMER_STATUS_VAL); 164 writel(0xf, regbase + TIMER_STATUS_VAL);
133 writel(~0, regbase + TIMER_MATCH_VAL); 165 writel(~0, regbase + TIMER_MATCH_VAL);
134 166
135 if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ)) 167 if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ))
136 printk(KERN_ERR "vt8500_timer_init: clocksource_register failed for %s\n", 168 pr_err("%s: vt8500_timer_init: clocksource_register failed for %s\n",
137 clocksource.name); 169 __func__, clocksource.name);
138 170
139 clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4); 171 clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4);
140 172
@@ -144,12 +176,9 @@ static void __init vt8500_timer_init(void)
144 clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent); 176 clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent);
145 clockevent.cpumask = cpumask_of(0); 177 clockevent.cpumask = cpumask_of(0);
146 178
147 if (setup_irq(wmt_timer_irq, &irq)) 179 if (setup_irq(timer_irq, &irq))
148 printk(KERN_ERR "vt8500_timer_init: setup_irq failed for %s\n", 180 pr_err("%s: setup_irq failed for %s\n", __func__,
149 clockevent.name); 181 clockevent.name);
150 clockevents_register_device(&clockevent); 182 clockevents_register_device(&clockevent);
151} 183}
152 184
153struct sys_timer vt8500_timer = {
154 .init = vt8500_timer_init
155};