Skip to content

Commit

Permalink
clocksource/atlas7: Convert to hotplug state machine
Browse files Browse the repository at this point in the history
Install the callbacks via the state machine and let the core invoke
the callbacks on the already online CPUs.

Signed-off-by: Richard Cochran <[email protected]>
Signed-off-by: Anna-Maria Gleixner <[email protected]>
Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
Cc: Barry Song <[email protected]>
Cc: Daniel Lezcano <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Richard Cochran authored and Ingo Molnar committed Jul 15, 2016
1 parent 2c48fef commit eb0a9d8
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 32 deletions.
41 changes: 9 additions & 32 deletions drivers/clocksource/timer-atlas7.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ static struct irqaction sirfsoc_timer1_irq = {
.handler = sirfsoc_timer_interrupt,
};

static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
static int sirfsoc_local_timer_starting_cpu(unsigned int cpu)
{
int cpu = smp_processor_id();
struct clock_event_device *ce = per_cpu_ptr(sirfsoc_clockevent, cpu);
struct irqaction *action;

if (cpu == 0)
Expand Down Expand Up @@ -203,50 +203,27 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
return 0;
}

static void sirfsoc_local_timer_stop(struct clock_event_device *ce)
static int sirfsoc_local_timer_dying_cpu(unsigned int cpu)
{
int cpu = smp_processor_id();

sirfsoc_timer_count_disable(1);

if (cpu == 0)
remove_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq);
else
remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq);
return 0;
}

static int sirfsoc_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
/*
* Grab cpu pointer in each case to avoid spurious
* preemptible warnings
*/
switch (action & ~CPU_TASKS_FROZEN) {
case CPU_STARTING:
sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent));
break;
case CPU_DYING:
sirfsoc_local_timer_stop(this_cpu_ptr(sirfsoc_clockevent));
break;
}

return NOTIFY_OK;
}

static struct notifier_block sirfsoc_cpu_nb = {
.notifier_call = sirfsoc_cpu_notify,
};

static int __init sirfsoc_clockevent_init(void)
{
sirfsoc_clockevent = alloc_percpu(struct clock_event_device);
BUG_ON(!sirfsoc_clockevent);

BUG_ON(register_cpu_notifier(&sirfsoc_cpu_nb));

/* Immediately configure the timer on the boot CPU */
return sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent));
/* Install and invoke hotplug callbacks */
return cpuhp_setup_state(CPUHP_AP_MARCO_TIMER_STARTING,
"AP_MARCO_TIMER_STARTING",
sirfsoc_local_timer_starting_cpu,
sirfsoc_local_timer_dying_cpu);
}

/* initialize the kernel jiffy timer source */
Expand Down
1 change: 1 addition & 0 deletions include/linux/cpuhotplug.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ enum cpuhp_state {
CPUHP_AP_METAG_TIMER_STARTING,
CPUHP_AP_QCOM_TIMER_STARTING,
CPUHP_AP_ARMADA_TIMER_STARTING,
CPUHP_AP_MARCO_TIMER_STARTING,
CPUHP_AP_MIPS_GIC_TIMER_STARTING,
CPUHP_AP_KVM_STARTING,
CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
Expand Down

0 comments on commit eb0a9d8

Please sign in to comment.