aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/qcom-timer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-07-29 16:55:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-29 16:55:30 -0400
commita6408f6cb63ac0958fee7dbce7861ffb540d8a49 (patch)
treec94a835d343974171951e3b805e6bbbb02852ebc /drivers/clocksource/qcom-timer.c
parent1a81a8f2a5918956e214bb718099a89e500e7ec5 (diff)
parent4fae16dffb812f0e0d98a0b2b0856ca48ca63e6c (diff)
Merge branch 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull smp hotplug updates from Thomas Gleixner: "This is the next part of the hotplug rework. - Convert all notifiers with a priority assigned - Convert all CPU_STARTING/DYING notifiers The final removal of the STARTING/DYING infrastructure will happen when the merge window closes. Another 700 hundred line of unpenetrable maze gone :)" * 'smp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits) timers/core: Correct callback order during CPU hot plug leds/trigger/cpu: Move from CPU_STARTING to ONLINE level powerpc/numa: Convert to hotplug state machine arm/perf: Fix hotplug state machine conversion irqchip/armada: Avoid unused function warnings ARC/time: Convert to hotplug state machine clocksource/atlas7: Convert to hotplug state machine clocksource/armada-370-xp: Convert to hotplug state machine clocksource/exynos_mct: Convert to hotplug state machine clocksource/arm_global_timer: Convert to hotplug state machine rcu: Convert rcutree to hotplug state machine KVM/arm/arm64/vgic-new: Convert to hotplug state machine smp/cfd: Convert core to hotplug state machine x86/x2apic: Convert to CPU hotplug state machine profile: Convert to hotplug state machine timers/core: Convert to hotplug state machine hrtimer: Convert to hotplug state machine x86/tboot: Convert to hotplug state machine arm64/armv8 deprecated: Convert to hotplug state machine hwtracing/coresight-etm4x: Convert to hotplug state machine ...
Diffstat (limited to 'drivers/clocksource/qcom-timer.c')
-rw-r--r--drivers/clocksource/qcom-timer.c41
1 files changed, 11 insertions, 30 deletions
diff --git a/drivers/clocksource/qcom-timer.c b/drivers/clocksource/qcom-timer.c
index 662576339049..3283cfa2aa52 100644
--- a/drivers/clocksource/qcom-timer.c
+++ b/drivers/clocksource/qcom-timer.c
@@ -105,9 +105,9 @@ static struct clocksource msm_clocksource = {
105static int msm_timer_irq; 105static int msm_timer_irq;
106static int msm_timer_has_ppi; 106static int msm_timer_has_ppi;
107 107
108static int msm_local_timer_setup(struct clock_event_device *evt) 108static int msm_local_timer_starting_cpu(unsigned int cpu)
109{ 109{
110 int cpu = smp_processor_id(); 110 struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu);
111 int err; 111 int err;
112 112
113 evt->irq = msm_timer_irq; 113 evt->irq = msm_timer_irq;
@@ -135,35 +135,15 @@ static int msm_local_timer_setup(struct clock_event_device *evt)
135 return 0; 135 return 0;
136} 136}
137 137
138static void msm_local_timer_stop(struct clock_event_device *evt) 138static int msm_local_timer_dying_cpu(unsigned int cpu)
139{ 139{
140 struct clock_event_device *evt = per_cpu_ptr(msm_evt, cpu);
141
140 evt->set_state_shutdown(evt); 142 evt->set_state_shutdown(evt);
141 disable_percpu_irq(evt->irq); 143 disable_percpu_irq(evt->irq);
144 return 0;
142} 145}
143 146
144static int msm_timer_cpu_notify(struct notifier_block *self,
145 unsigned long action, void *hcpu)
146{
147 /*
148 * Grab cpu pointer in each case to avoid spurious
149 * preemptible warnings
150 */
151 switch (action & ~CPU_TASKS_FROZEN) {
152 case CPU_STARTING:
153 msm_local_timer_setup(this_cpu_ptr(msm_evt));
154 break;
155 case CPU_DYING:
156 msm_local_timer_stop(this_cpu_ptr(msm_evt));
157 break;
158 }
159
160 return NOTIFY_OK;
161}
162
163static struct notifier_block msm_timer_cpu_nb = {
164 .notifier_call = msm_timer_cpu_notify,
165};
166
167static u64 notrace msm_sched_clock_read(void) 147static u64 notrace msm_sched_clock_read(void)
168{ 148{
169 return msm_clocksource.read(&msm_clocksource); 149 return msm_clocksource.read(&msm_clocksource);
@@ -200,14 +180,15 @@ static int __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
200 if (res) { 180 if (res) {
201 pr_err("request_percpu_irq failed\n"); 181 pr_err("request_percpu_irq failed\n");
202 } else { 182 } else {
203 res = register_cpu_notifier(&msm_timer_cpu_nb); 183 /* Install and invoke hotplug callbacks */
184 res = cpuhp_setup_state(CPUHP_AP_QCOM_TIMER_STARTING,
185 "AP_QCOM_TIMER_STARTING",
186 msm_local_timer_starting_cpu,
187 msm_local_timer_dying_cpu);
204 if (res) { 188 if (res) {
205 free_percpu_irq(irq, msm_evt); 189 free_percpu_irq(irq, msm_evt);
206 goto err; 190 goto err;
207 } 191 }
208
209 /* Immediately configure the timer on the boot CPU */
210 msm_local_timer_setup(raw_cpu_ptr(msm_evt));
211 } 192 }
212 193
213err: 194err: