aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-08-18 08:57:25 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-06 12:30:24 -0400
commit529351fd3c50215a462e5e604d7ceaaf27a8a0e5 (patch)
tree589ccd318d15fa9f1f7982193732f8c6173e5be6
parent29c6d1bbd7a2cd88a197ea7cef171f616e198526 (diff)
cpuidle/pseries: Convert to hotplug state machine
Install the callbacks via the state machine. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: linux-pm@vger.kernel.org Cc: Peter Zijlstra <peterz@infradead.org> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160818125731.27256-11-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--drivers/cpuidle/cpuidle-pseries.c51
-rw-r--r--include/linux/cpuhotplug.h1
2 files changed, 25 insertions, 27 deletions
diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c
index 07135e009d8b..166ccd711ec9 100644
--- a/drivers/cpuidle/cpuidle-pseries.c
+++ b/drivers/cpuidle/cpuidle-pseries.c
@@ -171,40 +171,30 @@ static struct cpuidle_state shared_states[] = {
171 .enter = &shared_cede_loop }, 171 .enter = &shared_cede_loop },
172}; 172};
173 173
174static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, 174static int pseries_cpuidle_cpu_online(unsigned int cpu)
175 unsigned long action, void *hcpu)
176{ 175{
177 int hotcpu = (unsigned long)hcpu; 176 struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
178 struct cpuidle_device *dev =
179 per_cpu(cpuidle_devices, hotcpu);
180 177
181 if (dev && cpuidle_get_driver()) { 178 if (dev && cpuidle_get_driver()) {
182 switch (action) { 179 cpuidle_pause_and_lock();
183 case CPU_ONLINE: 180 cpuidle_enable_device(dev);
184 case CPU_ONLINE_FROZEN: 181 cpuidle_resume_and_unlock();
185 cpuidle_pause_and_lock(); 182 }
186 cpuidle_enable_device(dev); 183 return 0;
187 cpuidle_resume_and_unlock(); 184}
188 break;
189 185
190 case CPU_DEAD: 186static int pseries_cpuidle_cpu_dead(unsigned int cpu)
191 case CPU_DEAD_FROZEN: 187{
192 cpuidle_pause_and_lock(); 188 struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu);
193 cpuidle_disable_device(dev);
194 cpuidle_resume_and_unlock();
195 break;
196 189
197 default: 190 if (dev && cpuidle_get_driver()) {
198 return NOTIFY_DONE; 191 cpuidle_pause_and_lock();
199 } 192 cpuidle_disable_device(dev);
193 cpuidle_resume_and_unlock();
200 } 194 }
201 return NOTIFY_OK; 195 return 0;
202} 196}
203 197
204static struct notifier_block setup_hotplug_notifier = {
205 .notifier_call = pseries_cpuidle_add_cpu_notifier,
206};
207
208/* 198/*
209 * pseries_cpuidle_driver_init() 199 * pseries_cpuidle_driver_init()
210 */ 200 */
@@ -273,7 +263,14 @@ static int __init pseries_processor_idle_init(void)
273 return retval; 263 return retval;
274 } 264 }
275 265
276 register_cpu_notifier(&setup_hotplug_notifier); 266 retval = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
267 "cpuidle/pseries:online",
268 pseries_cpuidle_cpu_online, NULL);
269 WARN_ON(retval < 0);
270 retval = cpuhp_setup_state_nocalls(CPUHP_CPUIDLE_DEAD,
271 "cpuidle/pseries:DEAD", NULL,
272 pseries_cpuidle_cpu_dead);
273 WARN_ON(retval < 0);
277 printk(KERN_DEBUG "pseries_idle_driver registered\n"); 274 printk(KERN_DEBUG "pseries_idle_driver registered\n");
278 return 0; 275 return 0;
279} 276}
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 4066c74bb73c..0fb22b95649f 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -19,6 +19,7 @@ enum cpuhp_state {
19 CPUHP_MM_WRITEBACK_DEAD, 19 CPUHP_MM_WRITEBACK_DEAD,
20 CPUHP_SOFTIRQ_DEAD, 20 CPUHP_SOFTIRQ_DEAD,
21 CPUHP_NET_MVNETA_DEAD, 21 CPUHP_NET_MVNETA_DEAD,
22 CPUHP_CPUIDLE_DEAD,
22 CPUHP_WORKQUEUE_PREP, 23 CPUHP_WORKQUEUE_PREP,
23 CPUHP_POWER_NUMA_PREPARE, 24 CPUHP_POWER_NUMA_PREPARE,
24 CPUHP_HRTIMERS_PREPARE, 25 CPUHP_HRTIMERS_PREPARE,