aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-11-18 10:09:50 -0500
committerGuenter Roeck <linux@roeck-us.net>2016-12-10 00:54:27 -0500
commitdf60d7013c36f86f7653af387915019d7da49613 (patch)
tree45c3240903a0b419b79c797ea77e69ef8574ad36
parent8017c0f2989f077a665bbf7881a1154ecd8334e7 (diff)
hwmon: (via-cputemp) Convert to hotplug state machine
Install the callbacks via the state machine and let the core invoke the callbacks on the already online CPUs. When the hotplug state is unregistered the cleanup function is called for each cpu. So both cpu loops in init() and exit() are not longer required. Cc: Jean Delvare <jdelvare@suse.com> Cc: Guenter Roeck <linux@roeck-us.net> Cc: linux-hwmon@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/via-cputemp.c63
1 files changed, 17 insertions, 46 deletions
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index 5b9866b1b437..d1f209a5feac 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -220,7 +220,7 @@ struct pdev_entry {
220static LIST_HEAD(pdev_list); 220static LIST_HEAD(pdev_list);
221static DEFINE_MUTEX(pdev_list_mutex); 221static DEFINE_MUTEX(pdev_list_mutex);
222 222
223static int via_cputemp_device_add(unsigned int cpu) 223static int via_cputemp_online(unsigned int cpu)
224{ 224{
225 int err; 225 int err;
226 struct platform_device *pdev; 226 struct platform_device *pdev;
@@ -261,7 +261,7 @@ exit:
261 return err; 261 return err;
262} 262}
263 263
264static void via_cputemp_device_remove(unsigned int cpu) 264static int via_cputemp_down_prep(unsigned int cpu)
265{ 265{
266 struct pdev_entry *p; 266 struct pdev_entry *p;
267 267
@@ -272,33 +272,13 @@ static void via_cputemp_device_remove(unsigned int cpu)
272 list_del(&p->list); 272 list_del(&p->list);
273 mutex_unlock(&pdev_list_mutex); 273 mutex_unlock(&pdev_list_mutex);
274 kfree(p); 274 kfree(p);
275 return; 275 return 0;
276 } 276 }
277 } 277 }
278 mutex_unlock(&pdev_list_mutex); 278 mutex_unlock(&pdev_list_mutex);
279 return 0;
279} 280}
280 281
281static int via_cputemp_cpu_callback(struct notifier_block *nfb,
282 unsigned long action, void *hcpu)
283{
284 unsigned int cpu = (unsigned long) hcpu;
285
286 switch (action) {
287 case CPU_ONLINE:
288 case CPU_DOWN_FAILED:
289 via_cputemp_device_add(cpu);
290 break;
291 case CPU_DOWN_PREPARE:
292 via_cputemp_device_remove(cpu);
293 break;
294 }
295 return NOTIFY_OK;
296}
297
298static struct notifier_block via_cputemp_cpu_notifier __refdata = {
299 .notifier_call = via_cputemp_cpu_callback,
300};
301
302static const struct x86_cpu_id __initconst cputemp_ids[] = { 282static const struct x86_cpu_id __initconst cputemp_ids[] = {
303 { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */ 283 { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */
304 { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */ 284 { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */
@@ -307,9 +287,11 @@ static const struct x86_cpu_id __initconst cputemp_ids[] = {
307}; 287};
308MODULE_DEVICE_TABLE(x86cpu, cputemp_ids); 288MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
309 289
290static enum cpuhp_state via_temp_online;
291
310static int __init via_cputemp_init(void) 292static int __init via_cputemp_init(void)
311{ 293{
312 int i, err; 294 int err;
313 295
314 if (!x86_match_cpu(cputemp_ids)) 296 if (!x86_match_cpu(cputemp_ids))
315 return -ENODEV; 297 return -ENODEV;
@@ -318,44 +300,33 @@ static int __init via_cputemp_init(void)
318 if (err) 300 if (err)
319 goto exit; 301 goto exit;
320 302
321 cpu_notifier_register_begin(); 303 err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/via:online",
322 for_each_online_cpu(i) 304 via_cputemp_online, via_cputemp_down_prep);
323 via_cputemp_device_add(i); 305 if (err < 0)
306 goto exit_driver_unreg;
307 via_temp_online = err;
324 308
325#ifndef CONFIG_HOTPLUG_CPU 309#ifndef CONFIG_HOTPLUG_CPU
326 if (list_empty(&pdev_list)) { 310 if (list_empty(&pdev_list)) {
327 cpu_notifier_register_done();
328 err = -ENODEV; 311 err = -ENODEV;
329 goto exit_driver_unreg; 312 goto exit_hp_unreg;
330 } 313 }
331#endif 314#endif
332
333 __register_hotcpu_notifier(&via_cputemp_cpu_notifier);
334 cpu_notifier_register_done();
335 return 0; 315 return 0;
336 316
337#ifndef CONFIG_HOTPLUG_CPU 317#ifndef CONFIG_HOTPLUG_CPU
318exit_hp_unreg:
319 cpuhp_remove_state_nocalls(via_temp_online);
320#endif
338exit_driver_unreg: 321exit_driver_unreg:
339 platform_driver_unregister(&via_cputemp_driver); 322 platform_driver_unregister(&via_cputemp_driver);
340#endif
341exit: 323exit:
342 return err; 324 return err;
343} 325}
344 326
345static void __exit via_cputemp_exit(void) 327static void __exit via_cputemp_exit(void)
346{ 328{
347 struct pdev_entry *p, *n; 329 cpuhp_remove_state(via_temp_online);
348
349 cpu_notifier_register_begin();
350 __unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
351 mutex_lock(&pdev_list_mutex);
352 list_for_each_entry_safe(p, n, &pdev_list, list) {
353 platform_device_unregister(p->pdev);
354 list_del(&p->list);
355 kfree(p);
356 }
357 mutex_unlock(&pdev_list_mutex);
358 cpu_notifier_register_done();
359 platform_driver_unregister(&via_cputemp_driver); 330 platform_driver_unregister(&via_cputemp_driver);
360} 331}
361 332