forked from mirrors/linux
		
	hwmon: (coretemp) Convert to hotplug state machine
Install the callbacks via the state machine. Setup and teardown are handled by the hotplug core. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: linux-hwmon@vger.kernel.org Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Jean Delvare <jdelvare@suse.com> Cc: rt@linuxtronix.de Cc: Guenter Roeck <linux@roeck-us.net> Link: http://lkml.kernel.org/r/20161117183541.8588-5-bigeasy@linutronix.de Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
		
							parent
							
								
									4b138cf73f
								
							
						
					
					
						commit
						e00ca5df37
					
				
					 1 changed files with 29 additions and 57 deletions
				
			
		|  | @ -649,7 +649,7 @@ static void coretemp_device_remove(unsigned int cpu) | ||||||
| 	mutex_unlock(&pdev_list_mutex); | 	mutex_unlock(&pdev_list_mutex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void get_core_online(unsigned int cpu) | static int coretemp_cpu_online(unsigned int cpu) | ||||||
| { | { | ||||||
| 	struct platform_device *pdev = coretemp_get_pdev(cpu); | 	struct platform_device *pdev = coretemp_get_pdev(cpu); | ||||||
| 	struct cpuinfo_x86 *c = &cpu_data(cpu); | 	struct cpuinfo_x86 *c = &cpu_data(cpu); | ||||||
|  | @ -662,12 +662,12 @@ static void get_core_online(unsigned int cpu) | ||||||
| 	 * without thermal sensors will be filtered out. | 	 * without thermal sensors will be filtered out. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (!cpu_has(c, X86_FEATURE_DTHERM)) | 	if (!cpu_has(c, X86_FEATURE_DTHERM)) | ||||||
| 		return; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	if (!pdev) { | 	if (!pdev) { | ||||||
| 		/* Check the microcode version of the CPU */ | 		/* Check the microcode version of the CPU */ | ||||||
| 		if (chk_ucode_version(cpu)) | 		if (chk_ucode_version(cpu)) | ||||||
| 			return; | 			return 0; | ||||||
| 
 | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * Alright, we have DTS support. | 		 * Alright, we have DTS support. | ||||||
|  | @ -677,7 +677,7 @@ static void get_core_online(unsigned int cpu) | ||||||
| 		 */ | 		 */ | ||||||
| 		err = coretemp_device_add(cpu); | 		err = coretemp_device_add(cpu); | ||||||
| 		if (err) | 		if (err) | ||||||
| 			return; | 			return 0; | ||||||
| 
 | 
 | ||||||
| 		pdev = coretemp_get_pdev(cpu); | 		pdev = coretemp_get_pdev(cpu); | ||||||
| 		/*
 | 		/*
 | ||||||
|  | @ -697,9 +697,10 @@ static void get_core_online(unsigned int cpu) | ||||||
| 		coretemp_add_core(pdev, cpu, 0); | 		coretemp_add_core(pdev, cpu, 0); | ||||||
| 
 | 
 | ||||||
| 	cpumask_set_cpu(cpu, &pdata->cpumask); | 	cpumask_set_cpu(cpu, &pdata->cpumask); | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void put_core_offline(unsigned int cpu) | static int coretemp_cpu_offline(unsigned int cpu) | ||||||
| { | { | ||||||
| 	struct platform_device *pdev = coretemp_get_pdev(cpu); | 	struct platform_device *pdev = coretemp_get_pdev(cpu); | ||||||
| 	struct platform_data *pd; | 	struct platform_data *pd; | ||||||
|  | @ -708,12 +709,12 @@ static void put_core_offline(unsigned int cpu) | ||||||
| 
 | 
 | ||||||
| 	/* If the physical CPU device does not exist, just return */ | 	/* If the physical CPU device does not exist, just return */ | ||||||
| 	if (!pdev) | 	if (!pdev) | ||||||
| 		return; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	/* The core id is too big, just return */ | 	/* The core id is too big, just return */ | ||||||
| 	indx = TO_ATTR_NO(cpu); | 	indx = TO_ATTR_NO(cpu); | ||||||
| 	if (indx > MAX_CORE_DATA - 1) | 	if (indx > MAX_CORE_DATA - 1) | ||||||
| 		return; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	pd = platform_get_drvdata(pdev); | 	pd = platform_get_drvdata(pdev); | ||||||
| 	tdata = pd->core_data[indx]; | 	tdata = pd->core_data[indx]; | ||||||
|  | @ -742,7 +743,7 @@ static void put_core_offline(unsigned int cpu) | ||||||
| 	 */ | 	 */ | ||||||
| 	if (cpumask_empty(&pd->cpumask)) { | 	if (cpumask_empty(&pd->cpumask)) { | ||||||
| 		coretemp_device_remove(cpu); | 		coretemp_device_remove(cpu); | ||||||
| 		return; | 		return 0; | ||||||
| 	} | 	} | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Check whether this core is the target for the package | 	 * Check whether this core is the target for the package | ||||||
|  | @ -755,38 +756,19 @@ static void put_core_offline(unsigned int cpu) | ||||||
| 		tdata->cpu = target; | 		tdata->cpu = target; | ||||||
| 		mutex_unlock(&tdata->update_lock); | 		mutex_unlock(&tdata->update_lock); | ||||||
| 	} | 	} | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| static int coretemp_cpu_callback(struct notifier_block *nfb, |  | ||||||
| 				 unsigned long action, void *hcpu) |  | ||||||
| { |  | ||||||
| 	unsigned int cpu = (unsigned long) hcpu; |  | ||||||
| 
 |  | ||||||
| 	switch (action) { |  | ||||||
| 	case CPU_ONLINE: |  | ||||||
| 	case CPU_DOWN_FAILED: |  | ||||||
| 		get_core_online(cpu); |  | ||||||
| 		break; |  | ||||||
| 	case CPU_DOWN_PREPARE: |  | ||||||
| 		put_core_offline(cpu); |  | ||||||
| 		break; |  | ||||||
| 	} |  | ||||||
| 	return NOTIFY_OK; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static struct notifier_block coretemp_cpu_notifier __refdata = { |  | ||||||
| 	.notifier_call = coretemp_cpu_callback, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static const struct x86_cpu_id __initconst coretemp_ids[] = { | static const struct x86_cpu_id __initconst coretemp_ids[] = { | ||||||
| 	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, | 	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, | ||||||
| 	{} | 	{} | ||||||
| }; | }; | ||||||
| MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); | MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); | ||||||
| 
 | 
 | ||||||
|  | static enum cpuhp_state coretemp_hp_online; | ||||||
|  | 
 | ||||||
| static int __init coretemp_init(void) | static int __init coretemp_init(void) | ||||||
| { | { | ||||||
| 	int i, err; | 	int err; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal | 	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal | ||||||
|  | @ -798,52 +780,42 @@ static int __init coretemp_init(void) | ||||||
| 
 | 
 | ||||||
| 	err = platform_driver_register(&coretemp_driver); | 	err = platform_driver_register(&coretemp_driver); | ||||||
| 	if (err) | 	if (err) | ||||||
| 		goto exit; | 		return err; | ||||||
| 
 | 
 | ||||||
| 	cpu_notifier_register_begin(); | 	get_online_cpus(); | ||||||
| 	for_each_online_cpu(i) | 	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online", | ||||||
| 		get_core_online(i); | 				coretemp_cpu_online, coretemp_cpu_offline); | ||||||
|  | 	if (err < 0) | ||||||
|  | 		goto exit_driver_unreg; | ||||||
|  | 	coretemp_hp_online = err; | ||||||
| 
 | 
 | ||||||
| #ifndef CONFIG_HOTPLUG_CPU | #ifndef CONFIG_HOTPLUG_CPU | ||||||
| 	if (list_empty(&pdev_list)) { | 	if (list_empty(&pdev_list)) { | ||||||
| 		cpu_notifier_register_done(); |  | ||||||
| 		err = -ENODEV; | 		err = -ENODEV; | ||||||
| 		goto exit_driver_unreg; | 		goto exit_hp_unreg; | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| 
 | 	put_online_cpus(); | ||||||
| 	__register_hotcpu_notifier(&coretemp_cpu_notifier); |  | ||||||
| 	cpu_notifier_register_done(); |  | ||||||
| 	return 0; | 	return 0; | ||||||
| 
 | 
 | ||||||
| #ifndef CONFIG_HOTPLUG_CPU | #ifndef CONFIG_HOTPLUG_CPU | ||||||
|  | exit_hp_unreg: | ||||||
|  | 	cpuhp_remove_state(coretemp_hp_online); | ||||||
|  | 	put_online_cpus(); | ||||||
|  | #endif | ||||||
| exit_driver_unreg: | exit_driver_unreg: | ||||||
| 	platform_driver_unregister(&coretemp_driver); | 	platform_driver_unregister(&coretemp_driver); | ||||||
| #endif |  | ||||||
| exit: |  | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
|  | module_init(coretemp_init) | ||||||
| 
 | 
 | ||||||
| static void __exit coretemp_exit(void) | static void __exit coretemp_exit(void) | ||||||
| { | { | ||||||
| 	struct pdev_entry *p, *n; | 	cpuhp_remove_state(coretemp_hp_online); | ||||||
| 
 |  | ||||||
| 	cpu_notifier_register_begin(); |  | ||||||
| 	__unregister_hotcpu_notifier(&coretemp_cpu_notifier); |  | ||||||
| 	mutex_lock(&pdev_list_mutex); |  | ||||||
| 	list_for_each_entry_safe(p, n, &pdev_list, list) { |  | ||||||
| 		platform_device_unregister(p->pdev); |  | ||||||
| 		list_del(&p->list); |  | ||||||
| 		kfree(p); |  | ||||||
| 	} |  | ||||||
| 	mutex_unlock(&pdev_list_mutex); |  | ||||||
| 	cpu_notifier_register_done(); |  | ||||||
| 	platform_driver_unregister(&coretemp_driver); | 	platform_driver_unregister(&coretemp_driver); | ||||||
| } | } | ||||||
|  | module_exit(coretemp_exit) | ||||||
| 
 | 
 | ||||||
| MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); | MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); | ||||||
| MODULE_DESCRIPTION("Intel Core temperature monitor"); | MODULE_DESCRIPTION("Intel Core temperature monitor"); | ||||||
| MODULE_LICENSE("GPL"); | MODULE_LICENSE("GPL"); | ||||||
| 
 |  | ||||||
| module_init(coretemp_init) |  | ||||||
| module_exit(coretemp_exit) |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Thomas Gleixner
						Thomas Gleixner