aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp_twd.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/smp_twd.c')
-rw-r--r--arch/arm/kernel/smp_twd.c54
1 files changed, 19 insertions, 35 deletions
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 49f335d301ba..c092115d903a 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -24,14 +24,12 @@
24 24
25#include <asm/smp_twd.h> 25#include <asm/smp_twd.h>
26#include <asm/localtimer.h> 26#include <asm/localtimer.h>
27#include <asm/hardware/gic.h>
28 27
29/* set up by the platform code */ 28/* set up by the platform code */
30static void __iomem *twd_base; 29static void __iomem *twd_base;
31 30
32static struct clk *twd_clk; 31static struct clk *twd_clk;
33static unsigned long twd_timer_rate; 32static unsigned long twd_timer_rate;
34static bool common_setup_called;
35static DEFINE_PER_CPU(bool, percpu_setup_called); 33static DEFINE_PER_CPU(bool, percpu_setup_called);
36 34
37static struct clock_event_device __percpu **twd_evt; 35static struct clock_event_device __percpu **twd_evt;
@@ -239,25 +237,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
239 return IRQ_NONE; 237 return IRQ_NONE;
240} 238}
241 239
242static struct clk *twd_get_clock(void) 240static void twd_get_clock(struct device_node *np)
243{ 241{
244 struct clk *clk;
245 int err; 242 int err;
246 243
247 clk = clk_get_sys("smp_twd", NULL); 244 if (np)
248 if (IS_ERR(clk)) { 245 twd_clk = of_clk_get(np, 0);
249 pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk)); 246 else
250 return clk; 247 twd_clk = clk_get_sys("smp_twd", NULL);
248
249 if (IS_ERR(twd_clk)) {
250 pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
251 return;
251 } 252 }
252 253
253 err = clk_prepare_enable(clk); 254 err = clk_prepare_enable(twd_clk);
254 if (err) { 255 if (err) {
255 pr_err("smp_twd: clock failed to prepare+enable: %d\n", err); 256 pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
256 clk_put(clk); 257 clk_put(twd_clk);
257 return ERR_PTR(err); 258 return;
258 } 259 }
259 260
260 return clk; 261 twd_timer_rate = clk_get_rate(twd_clk);
261} 262}
262 263
263/* 264/*
@@ -280,26 +281,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
280 } 281 }
281 per_cpu(percpu_setup_called, cpu) = true; 282 per_cpu(percpu_setup_called, cpu) = true;
282 283
283 /* 284 twd_calibrate_rate();
284 * This stuff only need to be done once for the entire TWD cluster
285 * during the runtime of the system.
286 */
287 if (!common_setup_called) {
288 twd_clk = twd_get_clock();
289
290 /*
291 * We use IS_ERR_OR_NULL() here, because if the clock stubs
292 * are active we will get a valid clk reference which is
293 * however NULL and will return the rate 0. In that case we
294 * need to calibrate the rate instead.
295 */
296 if (!IS_ERR_OR_NULL(twd_clk))
297 twd_timer_rate = clk_get_rate(twd_clk);
298 else
299 twd_calibrate_rate();
300
301 common_setup_called = true;
302 }
303 285
304 /* 286 /*
305 * The following is done once per CPU the first time .setup() is 287 * The following is done once per CPU the first time .setup() is
@@ -330,7 +312,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
330 .stop = twd_timer_stop, 312 .stop = twd_timer_stop,
331}; 313};
332 314
333static int __init twd_local_timer_common_register(void) 315static int __init twd_local_timer_common_register(struct device_node *np)
334{ 316{
335 int err; 317 int err;
336 318
@@ -350,6 +332,8 @@ static int __init twd_local_timer_common_register(void)
350 if (err) 332 if (err)
351 goto out_irq; 333 goto out_irq;
352 334
335 twd_get_clock(np);
336
353 return 0; 337 return 0;
354 338
355out_irq: 339out_irq:
@@ -373,7 +357,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
373 if (!twd_base) 357 if (!twd_base)
374 return -ENOMEM; 358 return -ENOMEM;
375 359
376 return twd_local_timer_common_register(); 360 return twd_local_timer_common_register(NULL);
377} 361}
378 362
379#ifdef CONFIG_OF 363#ifdef CONFIG_OF
@@ -405,7 +389,7 @@ void __init twd_local_timer_of_register(void)
405 goto out; 389 goto out;
406 } 390 }
407 391
408 err = twd_local_timer_common_register(); 392 err = twd_local_timer_common_register(np);
409 393
410out: 394out:
411 WARN(err, "twd_local_timer_of_register failed (%d)\n", err); 395 WARN(err, "twd_local_timer_of_register failed (%d)\n", err);