aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/qcom-timer.c
diff options
context:
space:
mode:
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: