aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-05 16:51:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-05 16:51:19 -0400
commitdfc25e4503aef6b82a1de4a0fbe19aafa8648fbe (patch)
tree0a4f3a07e2286918298e635186e42726f4658cbd /drivers/clocksource
parent9f800363bb0ea459e15bef0928a72c88d374e489 (diff)
parent8f881c67368f82d0e20e1072b50b21132cc2440d (diff)
Merge tag 'cleanup-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups from Arnd Bergmann: "These cleanup patches are mainly move stuff around and should all be harmless. They are mainly split out so that other branches can be based on top to avoid conflicts. Notable changes are: - We finally remove all mach/timex.h, after CLOCK_TICK_RATE is no longer used (Uwe Kleine-König) - The Qualcomm MSM platform is split out into legacy mach-msm and new-style mach-qcom, to allow easier maintainance of the new hardware support without regressions (Kumar Gala) - A rework of some of the Kconfig logic to simplify multiplatform support (Rob Herring) - Samsung Exynos gets closer to supporting multiplatform (Sachin Kamat and others) - mach-bcm3528 gets merged into mach-bcm (Stephen Warren) - at91 gains some common clock framework support (Alexandre Belloni, Jean-Jacques Hiblot and other French people)" * tag 'cleanup-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (89 commits) ARM: hisi: select HAVE_ARM_SCU only for SMP ARM: efm32: allow uncompress debug output ARM: prima2: build reset code standalone ARM: at91: add PWM clock ARM: at91: move sam9261 SoC to common clk ARM: at91: prepare common clk transition for sam9261 SoC ARM: at91: updated the at91_dt_defconfig with support for the ADS7846 ARM: at91: dt: sam9261: Device Tree support for the at91sam9261ek ARM: at91: dt: defconfig: Added the sam9261 to the list of DT-enabled SOCs ARM: at91: dt: Add at91sam9261 dt SoC support ARM: at91: switch sam9rl to common clock framework ARM: at91/dt: define main clk frequency of at91sam9rlek ARM: at91/dt: define at91sam9rl clocks ARM: at91: prepare common clk transition for sam9rl SoCs ARM: at91: prepare sam9 dt boards transition to common clk ARM: at91: dt: sam9rl: Device Tree for the at91sam9rlek ARM: at91/defconfig: Add the sam9rl to the list of DT-enabled SOCs ARM: at91: Add at91sam9rl DT SoC support ARM: at91: prepare at91sam9rl DT transition ARM: at91/defconfig: refresh at91sam9260_9g20_defconfig ...
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/Kconfig3
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/exynos_mct.c2
-rw-r--r--drivers/clocksource/qcom-timer.c330
-rw-r--r--drivers/clocksource/timer-marco.c13
-rw-r--r--drivers/clocksource/timer-prima2.c16
6 files changed, 351 insertions, 14 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 52e9329e3c51..96918e1f26a3 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -188,3 +188,6 @@ config EM_TIMER_STI
188 This enables build of a clocksource and clockevent driver for 188 This enables build of a clocksource and clockevent driver for
189 the 48-bit System Timer (STI) hardware available on a SoCs 189 the 48-bit System Timer (STI) hardware available on a SoCs
190 such as EMEV2 from former NEC Electronics. 190 such as EMEV2 from former NEC Electronics.
191
192config CLKSRC_QCOM
193 bool
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index f3fe4cb4974b..98cb6c51aa87 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
32obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o 32obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
33obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o 33obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
34obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o 34obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
35obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
35 36
36obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o 37obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
37obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o 38obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index c2e390efbdca..a6ee6d7cd63f 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -25,8 +25,6 @@
25#include <linux/of_address.h> 25#include <linux/of_address.h>
26#include <linux/clocksource.h> 26#include <linux/clocksource.h>
27 27
28#include <asm/mach/time.h>
29
30#define EXYNOS4_MCTREG(x) (x) 28#define EXYNOS4_MCTREG(x) (x)
31#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) 29#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
32#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104) 30#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104)
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
new file mode 100644
index 000000000000..e807acf4c665
--- /dev/null
+++ b/drivers/clocksource/qcom-timer.c
@@ -0,0 +1,330 @@
1/*
2 *
3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2009-2012,2014, The Linux Foundation. All rights reserved.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/clocksource.h>
18#include <linux/clockchips.h>
19#include <linux/cpu.h>
20#include <linux/init.h>
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/io.h>
24#include <linux/of.h>
25#include <linux/of_address.h>
26#include <linux/of_irq.h>
27#include <linux/sched_clock.h>
28
29#define TIMER_MATCH_VAL 0x0000
30#define TIMER_COUNT_VAL 0x0004
31#define TIMER_ENABLE 0x0008
32#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
33#define TIMER_ENABLE_EN BIT(0)
34#define TIMER_CLEAR 0x000C
35#define DGT_CLK_CTL 0x10
36#define DGT_CLK_CTL_DIV_4 0x3
37#define TIMER_STS_GPT0_CLR_PEND BIT(10)
38
39#define GPT_HZ 32768
40
41#define MSM_DGT_SHIFT 5
42
43static void __iomem *event_base;
44static void __iomem *sts_base;
45
46static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
47{
48 struct clock_event_device *evt = dev_id;
49 /* Stop the timer tick */
50 if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
51 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
52 ctrl &= ~TIMER_ENABLE_EN;
53 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
54 }
55 evt->event_handler(evt);
56 return IRQ_HANDLED;
57}
58
59static int msm_timer_set_next_event(unsigned long cycles,
60 struct clock_event_device *evt)
61{
62 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
63
64 ctrl &= ~TIMER_ENABLE_EN;
65 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
66
67 writel_relaxed(ctrl, event_base + TIMER_CLEAR);
68 writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
69
70 if (sts_base)
71 while (readl_relaxed(sts_base) & TIMER_STS_GPT0_CLR_PEND)
72 cpu_relax();
73
74 writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
75 return 0;
76}
77
78static void msm_timer_set_mode(enum clock_event_mode mode,
79 struct clock_event_device *evt)
80{
81 u32 ctrl;
82
83 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
84 ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
85
86 switch (mode) {
87 case CLOCK_EVT_MODE_RESUME:
88 case CLOCK_EVT_MODE_PERIODIC:
89 break;
90 case CLOCK_EVT_MODE_ONESHOT:
91 /* Timer is enabled in set_next_event */
92 break;
93 case CLOCK_EVT_MODE_UNUSED:
94 case CLOCK_EVT_MODE_SHUTDOWN:
95 break;
96 }
97 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
98}
99
100static struct clock_event_device __percpu *msm_evt;
101
102static void __iomem *source_base;
103
104static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
105{
106 return readl_relaxed(source_base + TIMER_COUNT_VAL);
107}
108
109static struct clocksource msm_clocksource = {
110 .name = "dg_timer",
111 .rating = 300,
112 .read = msm_read_timer_count,
113 .mask = CLOCKSOURCE_MASK(32),
114 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
115};
116
117static int msm_timer_irq;
118static int msm_timer_has_ppi;
119
120static int msm_local_timer_setup(struct clock_event_device *evt)
121{
122 int cpu = smp_processor_id();
123 int err;
124
125 evt->irq = msm_timer_irq;
126 evt->name = "msm_timer";
127 evt->features = CLOCK_EVT_FEAT_ONESHOT;
128 evt->rating = 200;
129 evt->set_mode = msm_timer_set_mode;
130 evt->set_next_event = msm_timer_set_next_event;
131 evt->cpumask = cpumask_of(cpu);
132
133 clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
134
135 if (msm_timer_has_ppi) {
136 enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
137 } else {
138 err = request_irq(evt->irq, msm_timer_interrupt,
139 IRQF_TIMER | IRQF_NOBALANCING |
140 IRQF_TRIGGER_RISING, "gp_timer", evt);
141 if (err)
142 pr_err("request_irq failed\n");
143 }
144
145 return 0;
146}
147
148static void msm_local_timer_stop(struct clock_event_device *evt)
149{
150 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
151 disable_percpu_irq(evt->irq);
152}
153
154static int msm_timer_cpu_notify(struct notifier_block *self,
155 unsigned long action, void *hcpu)
156{
157 /*
158 * Grab cpu pointer in each case to avoid spurious
159 * preemptible warnings
160 */
161 switch (action & ~CPU_TASKS_FROZEN) {
162 case CPU_STARTING:
163 msm_local_timer_setup(this_cpu_ptr(msm_evt));
164 break;
165 case CPU_DYING:
166 msm_local_timer_stop(this_cpu_ptr(msm_evt));
167 break;
168 }
169
170 return NOTIFY_OK;
171}
172
173static struct notifier_block msm_timer_cpu_nb = {
174 .notifier_call = msm_timer_cpu_notify,
175};
176
177static u64 notrace msm_sched_clock_read(void)
178{
179 return msm_clocksource.read(&msm_clocksource);
180}
181
182static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
183 bool percpu)
184{
185 struct clocksource *cs = &msm_clocksource;
186 int res = 0;
187
188 msm_timer_irq = irq;
189 msm_timer_has_ppi = percpu;
190
191 msm_evt = alloc_percpu(struct clock_event_device);
192 if (!msm_evt) {
193 pr_err("memory allocation failed for clockevents\n");
194 goto err;
195 }
196
197 if (percpu)
198 res = request_percpu_irq(irq, msm_timer_interrupt,
199 "gp_timer", msm_evt);
200
201 if (res) {
202 pr_err("request_percpu_irq failed\n");
203 } else {
204 res = register_cpu_notifier(&msm_timer_cpu_nb);
205 if (res) {
206 free_percpu_irq(irq, msm_evt);
207 goto err;
208 }
209
210 /* Immediately configure the timer on the boot CPU */
211 msm_local_timer_setup(__this_cpu_ptr(msm_evt));
212 }
213
214err:
215 writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
216 res = clocksource_register_hz(cs, dgt_hz);
217 if (res)
218 pr_err("clocksource_register failed\n");
219 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
220}
221
222#ifdef CONFIG_ARCH_QCOM
223static void __init msm_dt_timer_init(struct device_node *np)
224{
225 u32 freq;
226 int irq;
227 struct resource res;
228 u32 percpu_offset;
229 void __iomem *base;
230 void __iomem *cpu0_base;
231
232 base = of_iomap(np, 0);
233 if (!base) {
234 pr_err("Failed to map event base\n");
235 return;
236 }
237
238 /* We use GPT0 for the clockevent */
239 irq = irq_of_parse_and_map(np, 1);
240 if (irq <= 0) {
241 pr_err("Can't get irq\n");
242 return;
243 }
244
245 /* We use CPU0's DGT for the clocksource */
246 if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
247 percpu_offset = 0;
248
249 if (of_address_to_resource(np, 0, &res)) {
250 pr_err("Failed to parse DGT resource\n");
251 return;
252 }
253
254 cpu0_base = ioremap(res.start + percpu_offset, resource_size(&res));
255 if (!cpu0_base) {
256 pr_err("Failed to map source base\n");
257 return;
258 }
259
260 if (of_property_read_u32(np, "clock-frequency", &freq)) {
261 pr_err("Unknown frequency\n");
262 return;
263 }
264
265 event_base = base + 0x4;
266 sts_base = base + 0x88;
267 source_base = cpu0_base + 0x24;
268 freq /= 4;
269 writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
270
271 msm_timer_init(freq, 32, irq, !!percpu_offset);
272}
273CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
274CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
275#else
276
277static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
278 u32 sts)
279{
280 void __iomem *base;
281
282 base = ioremap(addr, SZ_256);
283 if (!base) {
284 pr_err("Failed to map timer base\n");
285 return -ENOMEM;
286 }
287 event_base = base + event;
288 source_base = base + source;
289 if (sts)
290 sts_base = base + sts;
291
292 return 0;
293}
294
295static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
296{
297 /*
298 * Shift timer count down by a constant due to unreliable lower bits
299 * on some targets.
300 */
301 return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
302}
303
304void __init msm7x01_timer_init(void)
305{
306 struct clocksource *cs = &msm_clocksource;
307
308 if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
309 return;
310 cs->read = msm_read_timer_count_shift;
311 cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
312 /* 600 KHz */
313 msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
314 false);
315}
316
317void __init msm7x30_timer_init(void)
318{
319 if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
320 return;
321 msm_timer_init(24576000 / 4, 32, 1, false);
322}
323
324void __init qsd8x50_timer_init(void)
325{
326 if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
327 return;
328 msm_timer_init(19200000 / 4, 32, 7, false);
329}
330#endif
diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c
index 09a17d9a6594..b52e1c078b99 100644
--- a/drivers/clocksource/timer-marco.c
+++ b/drivers/clocksource/timer-marco.c
@@ -19,7 +19,8 @@
19#include <linux/of_irq.h> 19#include <linux/of_irq.h>
20#include <linux/of_address.h> 20#include <linux/of_address.h>
21#include <linux/sched_clock.h> 21#include <linux/sched_clock.h>
22#include <asm/mach/time.h> 22
23#define MARCO_CLOCK_FREQ 1000000
23 24
24#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 25#define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000
25#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004 26#define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004
@@ -191,7 +192,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
191 ce->rating = 200; 192 ce->rating = 200;
192 ce->set_mode = sirfsoc_timer_set_mode; 193 ce->set_mode = sirfsoc_timer_set_mode;
193 ce->set_next_event = sirfsoc_timer_set_next_event; 194 ce->set_next_event = sirfsoc_timer_set_next_event;
194 clockevents_calc_mult_shift(ce, CLOCK_TICK_RATE, 60); 195 clockevents_calc_mult_shift(ce, MARCO_CLOCK_FREQ, 60);
195 ce->max_delta_ns = clockevent_delta2ns(-2, ce); 196 ce->max_delta_ns = clockevent_delta2ns(-2, ce);
196 ce->min_delta_ns = clockevent_delta2ns(2, ce); 197 ce->min_delta_ns = clockevent_delta2ns(2, ce);
197 ce->cpumask = cpumask_of(cpu); 198 ce->cpumask = cpumask_of(cpu);
@@ -263,11 +264,11 @@ static void __init sirfsoc_marco_timer_init(void)
263 BUG_ON(IS_ERR(clk)); 264 BUG_ON(IS_ERR(clk));
264 rate = clk_get_rate(clk); 265 rate = clk_get_rate(clk);
265 266
266 BUG_ON(rate < CLOCK_TICK_RATE); 267 BUG_ON(rate < MARCO_CLOCK_FREQ);
267 BUG_ON(rate % CLOCK_TICK_RATE); 268 BUG_ON(rate % MARCO_CLOCK_FREQ);
268 269
269 /* Initialize the timer dividers */ 270 /* Initialize the timer dividers */
270 timer_div = rate / CLOCK_TICK_RATE - 1; 271 timer_div = rate / MARCO_CLOCK_FREQ - 1;
271 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); 272 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
272 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL); 273 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
273 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL); 274 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
@@ -283,7 +284,7 @@ static void __init sirfsoc_marco_timer_init(void)
283 /* Clear all interrupts */ 284 /* Clear all interrupts */
284 writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); 285 writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
285 286
286 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); 287 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, MARCO_CLOCK_FREQ));
287 288
288 sirfsoc_clockevent_init(); 289 sirfsoc_clockevent_init();
289} 290}
diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c
index 8a492d34ff9f..1a6b2d6356d6 100644
--- a/drivers/clocksource/timer-prima2.c
+++ b/drivers/clocksource/timer-prima2.c
@@ -21,6 +21,8 @@
21#include <linux/sched_clock.h> 21#include <linux/sched_clock.h>
22#include <asm/mach/time.h> 22#include <asm/mach/time.h>
23 23
24#define PRIMA2_CLOCK_FREQ 1000000
25
24#define SIRFSOC_TIMER_COUNTER_LO 0x0000 26#define SIRFSOC_TIMER_COUNTER_LO 0x0000
25#define SIRFSOC_TIMER_COUNTER_HI 0x0004 27#define SIRFSOC_TIMER_COUNTER_HI 0x0004
26#define SIRFSOC_TIMER_MATCH_0 0x0008 28#define SIRFSOC_TIMER_MATCH_0 0x0008
@@ -173,7 +175,7 @@ static u64 notrace sirfsoc_read_sched_clock(void)
173static void __init sirfsoc_clockevent_init(void) 175static void __init sirfsoc_clockevent_init(void)
174{ 176{
175 sirfsoc_clockevent.cpumask = cpumask_of(0); 177 sirfsoc_clockevent.cpumask = cpumask_of(0);
176 clockevents_config_and_register(&sirfsoc_clockevent, CLOCK_TICK_RATE, 178 clockevents_config_and_register(&sirfsoc_clockevent, PRIMA2_CLOCK_FREQ,
177 2, -2); 179 2, -2);
178} 180}
179 181
@@ -190,8 +192,8 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np)
190 192
191 rate = clk_get_rate(clk); 193 rate = clk_get_rate(clk);
192 194
193 BUG_ON(rate < CLOCK_TICK_RATE); 195 BUG_ON(rate < PRIMA2_CLOCK_FREQ);
194 BUG_ON(rate % CLOCK_TICK_RATE); 196 BUG_ON(rate % PRIMA2_CLOCK_FREQ);
195 197
196 sirfsoc_timer_base = of_iomap(np, 0); 198 sirfsoc_timer_base = of_iomap(np, 0);
197 if (!sirfsoc_timer_base) 199 if (!sirfsoc_timer_base)
@@ -199,14 +201,16 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np)
199 201
200 sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); 202 sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0);
201 203
202 writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); 204 writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1,
205 sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
203 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); 206 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
204 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); 207 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
205 writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); 208 writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS);
206 209
207 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); 210 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource,
211 PRIMA2_CLOCK_FREQ));
208 212
209 sched_clock_register(sirfsoc_read_sched_clock, 64, CLOCK_TICK_RATE); 213 sched_clock_register(sirfsoc_read_sched_clock, 64, PRIMA2_CLOCK_FREQ);
210 214
211 BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); 215 BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
212 216