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.c53
1 files changed, 19 insertions, 34 deletions
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 49f335d301ba..ae0c7bb39ae8 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -31,7 +31,6 @@ static void __iomem *twd_base;
31 31
32static struct clk *twd_clk; 32static struct clk *twd_clk;
33static unsigned long twd_timer_rate; 33static unsigned long twd_timer_rate;
34static bool common_setup_called;
35static DEFINE_PER_CPU(bool, percpu_setup_called); 34static DEFINE_PER_CPU(bool, percpu_setup_called);
36 35
37static struct clock_event_device __percpu **twd_evt; 36static struct clock_event_device __percpu **twd_evt;
@@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
239 return IRQ_NONE; 238 return IRQ_NONE;
240} 239}
241 240
242static struct clk *twd_get_clock(void) 241static void twd_get_clock(struct device_node *np)
243{ 242{
244 struct clk *clk;
245 int err; 243 int err;
246 244
247 clk = clk_get_sys("smp_twd", NULL); 245 if (np)
248 if (IS_ERR(clk)) { 246 twd_clk = of_clk_get(np, 0);
249 pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk)); 247 else
250 return clk; 248 twd_clk = clk_get_sys("smp_twd", NULL);
249
250 if (IS_ERR(twd_clk)) {
251 pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
252 return;
251 } 253 }
252 254
253 err = clk_prepare_enable(clk); 255 err = clk_prepare_enable(twd_clk);
254 if (err) { 256 if (err) {
255 pr_err("smp_twd: clock failed to prepare+enable: %d\n", err); 257 pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
256 clk_put(clk); 258 clk_put(twd_clk);
257 return ERR_PTR(err); 259 return;
258 } 260 }
259 261
260 return clk; 262 twd_timer_rate = clk_get_rate(twd_clk);
261} 263}
262 264
263/* 265/*
@@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
280 } 282 }
281 per_cpu(percpu_setup_called, cpu) = true; 283 per_cpu(percpu_setup_called, cpu) = true;
282 284
283 /* 285 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 286
304 /* 287 /*
305 * The following is done once per CPU the first time .setup() is 288 * The following is done once per CPU the first time .setup() is
@@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
330 .stop = twd_timer_stop, 313 .stop = twd_timer_stop,
331}; 314};
332 315
333static int __init twd_local_timer_common_register(void) 316static int __init twd_local_timer_common_register(struct device_node *np)
334{ 317{
335 int err; 318 int err;
336 319
@@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void)
350 if (err) 333 if (err)
351 goto out_irq; 334 goto out_irq;
352 335
336 twd_get_clock(np);
337
353 return 0; 338 return 0;
354 339
355out_irq: 340out_irq:
@@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
373 if (!twd_base) 358 if (!twd_base)
374 return -ENOMEM; 359 return -ENOMEM;
375 360
376 return twd_local_timer_common_register(); 361 return twd_local_timer_common_register(NULL);
377} 362}
378 363
379#ifdef CONFIG_OF 364#ifdef CONFIG_OF
@@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void)
405 goto out; 390 goto out;
406 } 391 }
407 392
408 err = twd_local_timer_common_register(); 393 err = twd_local_timer_common_register(np);
409 394
410out: 395out:
411 WARN(err, "twd_local_timer_of_register failed (%d)\n", err); 396 WARN(err, "twd_local_timer_of_register failed (%d)\n", err);