aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/arm_arch_timer.c
diff options
context:
space:
mode:
authorRichard Cochran <rcochran@linutronix.de>2016-07-13 13:16:39 -0400
committerIngo Molnar <mingo@kernel.org>2016-07-15 04:40:24 -0400
commit7e86e8bd8dd67649d176e08d8dfb90039f0a1e98 (patch)
tree27d075e1a8d404276455061b6756efc4156e4b15 /drivers/clocksource/arm_arch_timer.c
parente1272f541c6ad476426ef24b56b4e1d3403db513 (diff)
clocksource/arm_arch_timer: Convert to hotplug state machine
Install the callbacks via the state machine and let the core invoke the callbacks on the already online CPUs. Signed-off-by: Richard Cochran <rcochran@linutronix.de> Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160713153336.048259040@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r--drivers/clocksource/arm_arch_timer.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 5effd3027319..28bce3f4f81d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -370,8 +370,10 @@ static bool arch_timer_has_nonsecure_ppi(void)
370 arch_timer_ppi[PHYS_NONSECURE_PPI]); 370 arch_timer_ppi[PHYS_NONSECURE_PPI]);
371} 371}
372 372
373static int arch_timer_setup(struct clock_event_device *clk) 373static int arch_timer_starting_cpu(unsigned int cpu)
374{ 374{
375 struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
376
375 __arch_timer_setup(ARCH_CP15_TIMER, clk); 377 __arch_timer_setup(ARCH_CP15_TIMER, clk);
376 378
377 enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], 0); 379 enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], 0);
@@ -527,29 +529,14 @@ static void arch_timer_stop(struct clock_event_device *clk)
527 clk->set_state_shutdown(clk); 529 clk->set_state_shutdown(clk);
528} 530}
529 531
530static int arch_timer_cpu_notify(struct notifier_block *self, 532static int arch_timer_dying_cpu(unsigned int cpu)
531 unsigned long action, void *hcpu)
532{ 533{
533 /* 534 struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
534 * Grab cpu pointer in each case to avoid spurious
535 * preemptible warnings
536 */
537 switch (action & ~CPU_TASKS_FROZEN) {
538 case CPU_STARTING:
539 arch_timer_setup(this_cpu_ptr(arch_timer_evt));
540 break;
541 case CPU_DYING:
542 arch_timer_stop(this_cpu_ptr(arch_timer_evt));
543 break;
544 }
545 535
546 return NOTIFY_OK; 536 arch_timer_stop(clk);
537 return 0;
547} 538}
548 539
549static struct notifier_block arch_timer_cpu_nb = {
550 .notifier_call = arch_timer_cpu_notify,
551};
552
553#ifdef CONFIG_CPU_PM 540#ifdef CONFIG_CPU_PM
554static unsigned int saved_cntkctl; 541static unsigned int saved_cntkctl;
555static int arch_timer_cpu_pm_notify(struct notifier_block *self, 542static int arch_timer_cpu_pm_notify(struct notifier_block *self,
@@ -570,11 +557,21 @@ static int __init arch_timer_cpu_pm_init(void)
570{ 557{
571 return cpu_pm_register_notifier(&arch_timer_cpu_pm_notifier); 558 return cpu_pm_register_notifier(&arch_timer_cpu_pm_notifier);
572} 559}
560
561static void __init arch_timer_cpu_pm_deinit(void)
562{
563 WARN_ON(cpu_pm_unregister_notifier(&arch_timer_cpu_pm_notifier));
564}
565
573#else 566#else
574static int __init arch_timer_cpu_pm_init(void) 567static int __init arch_timer_cpu_pm_init(void)
575{ 568{
576 return 0; 569 return 0;
577} 570}
571
572static void __init arch_timer_cpu_pm_deinit(void)
573{
574}
578#endif 575#endif
579 576
580static int __init arch_timer_register(void) 577static int __init arch_timer_register(void)
@@ -621,22 +618,23 @@ static int __init arch_timer_register(void)
621 goto out_free; 618 goto out_free;
622 } 619 }
623 620
624 err = register_cpu_notifier(&arch_timer_cpu_nb);
625 if (err)
626 goto out_free_irq;
627
628 err = arch_timer_cpu_pm_init(); 621 err = arch_timer_cpu_pm_init();
629 if (err) 622 if (err)
630 goto out_unreg_notify; 623 goto out_unreg_notify;
631 624
632 /* Immediately configure the timer on the boot CPU */
633 arch_timer_setup(this_cpu_ptr(arch_timer_evt));
634 625
626 /* Register and immediately configure the timer on the boot CPU */
627 err = cpuhp_setup_state(CPUHP_AP_ARM_ARCH_TIMER_STARTING,
628 "AP_ARM_ARCH_TIMER_STARTING",
629 arch_timer_starting_cpu, arch_timer_dying_cpu);
630 if (err)
631 goto out_unreg_cpupm;
635 return 0; 632 return 0;
636 633
634out_unreg_cpupm:
635 arch_timer_cpu_pm_deinit();
636
637out_unreg_notify: 637out_unreg_notify:
638 unregister_cpu_notifier(&arch_timer_cpu_nb);
639out_free_irq:
640 free_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], arch_timer_evt); 638 free_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], arch_timer_evt);
641 if (arch_timer_has_nonsecure_ppi()) 639 if (arch_timer_has_nonsecure_ppi())
642 free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 640 free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],