forked from Minki/linux
ACPI/processor: Convert to hotplug state machine
Install the callbacks via the state machine. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Acked-by: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: Peter Zijlstra <peterz@infradead.org> Cc: linux-acpi@vger.kernel.org Cc: rt@linutronix.de Cc: Len Brown <lenb@kernel.org> Link: http://lkml.kernel.org/r/20160906170457.32393-12-bigeasy@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
8904f5a5af
commit
64f3bf2f85
@ -110,55 +110,46 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
|
||||
|
||||
static int __acpi_processor_start(struct acpi_device *device);
|
||||
|
||||
static int acpi_cpu_soft_notify(struct notifier_block *nfb,
|
||||
unsigned long action, void *hcpu)
|
||||
static int acpi_soft_cpu_online(unsigned int cpu)
|
||||
{
|
||||
unsigned int cpu = (unsigned long)hcpu;
|
||||
struct acpi_processor *pr = per_cpu(processors, cpu);
|
||||
struct acpi_device *device;
|
||||
action &= ~CPU_TASKS_FROZEN;
|
||||
|
||||
switch (action) {
|
||||
case CPU_ONLINE:
|
||||
case CPU_DEAD:
|
||||
break;
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
if (!pr || acpi_bus_get_device(pr->handle, &device))
|
||||
return NOTIFY_DONE;
|
||||
return 0;
|
||||
/*
|
||||
* CPU got physically hotplugged and onlined for the first time:
|
||||
* Initialize missing things.
|
||||
*/
|
||||
if (pr->flags.need_hotplug_init) {
|
||||
int ret;
|
||||
|
||||
if (action == CPU_ONLINE) {
|
||||
/*
|
||||
* CPU got physically hotplugged and onlined for the first time:
|
||||
* Initialize missing things.
|
||||
*/
|
||||
if (pr->flags.need_hotplug_init) {
|
||||
int ret;
|
||||
|
||||
pr_info("Will online and init hotplugged CPU: %d\n",
|
||||
pr->id);
|
||||
pr->flags.need_hotplug_init = 0;
|
||||
ret = __acpi_processor_start(device);
|
||||
WARN(ret, "Failed to start CPU: %d\n", pr->id);
|
||||
} else {
|
||||
/* Normal CPU soft online event. */
|
||||
acpi_processor_ppc_has_changed(pr, 0);
|
||||
acpi_processor_hotplug(pr);
|
||||
acpi_processor_reevaluate_tstate(pr, action);
|
||||
acpi_processor_tstate_has_changed(pr);
|
||||
}
|
||||
} else if (action == CPU_DEAD) {
|
||||
/* Invalidate flag.throttling after the CPU is offline. */
|
||||
acpi_processor_reevaluate_tstate(pr, action);
|
||||
pr_info("Will online and init hotplugged CPU: %d\n",
|
||||
pr->id);
|
||||
pr->flags.need_hotplug_init = 0;
|
||||
ret = __acpi_processor_start(device);
|
||||
WARN(ret, "Failed to start CPU: %d\n", pr->id);
|
||||
} else {
|
||||
/* Normal CPU soft online event. */
|
||||
acpi_processor_ppc_has_changed(pr, 0);
|
||||
acpi_processor_hotplug(pr);
|
||||
acpi_processor_reevaluate_tstate(pr, false);
|
||||
acpi_processor_tstate_has_changed(pr);
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block acpi_cpu_notifier = {
|
||||
.notifier_call = acpi_cpu_soft_notify,
|
||||
};
|
||||
static int acpi_soft_cpu_dead(unsigned int cpu)
|
||||
{
|
||||
struct acpi_processor *pr = per_cpu(processors, cpu);
|
||||
struct acpi_device *device;
|
||||
|
||||
if (!pr || acpi_bus_get_device(pr->handle, &device))
|
||||
return 0;
|
||||
|
||||
acpi_processor_reevaluate_tstate(pr, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_CPU_FREQ_PSS
|
||||
static int acpi_pss_perf_init(struct acpi_processor *pr,
|
||||
@ -303,7 +294,7 @@ static int acpi_processor_stop(struct device *dev)
|
||||
* This is needed for the powernow-k8 driver, that works even without
|
||||
* ACPI, but needs symbols from this driver
|
||||
*/
|
||||
|
||||
static enum cpuhp_state hp_online;
|
||||
static int __init acpi_processor_driver_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
@ -315,11 +306,22 @@ static int __init acpi_processor_driver_init(void)
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
register_hotcpu_notifier(&acpi_cpu_notifier);
|
||||
result = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
|
||||
"acpi/cpu-drv:online",
|
||||
acpi_soft_cpu_online, NULL);
|
||||
if (result < 0)
|
||||
goto err;
|
||||
hp_online = result;
|
||||
cpuhp_setup_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD, "acpi/cpu-drv:dead",
|
||||
NULL, acpi_soft_cpu_dead);
|
||||
|
||||
acpi_thermal_cpufreq_init();
|
||||
acpi_processor_ppc_init();
|
||||
acpi_processor_throttling_init();
|
||||
return 0;
|
||||
err:
|
||||
driver_unregister(&acpi_processor_driver);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __exit acpi_processor_driver_exit(void)
|
||||
@ -329,7 +331,8 @@ static void __exit acpi_processor_driver_exit(void)
|
||||
|
||||
acpi_processor_ppc_exit();
|
||||
acpi_thermal_cpufreq_exit();
|
||||
unregister_hotcpu_notifier(&acpi_cpu_notifier);
|
||||
cpuhp_remove_state_nocalls(hp_online);
|
||||
cpuhp_remove_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD);
|
||||
driver_unregister(&acpi_processor_driver);
|
||||
}
|
||||
|
||||
|
@ -375,11 +375,11 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
|
||||
* 3. TSD domain
|
||||
*/
|
||||
void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
|
||||
unsigned long action)
|
||||
bool is_dead)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (action == CPU_DEAD) {
|
||||
if (is_dead) {
|
||||
/* When one CPU is offline, the T-state throttling
|
||||
* will be invalidated.
|
||||
*/
|
||||
|
@ -359,7 +359,7 @@ extern int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||
* onlined/offlined. In such case the flags.throttling will be updated.
|
||||
*/
|
||||
extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
|
||||
unsigned long action);
|
||||
bool is_dead);
|
||||
extern const struct file_operations acpi_processor_throttling_fops;
|
||||
extern void acpi_processor_throttling_init(void);
|
||||
#else
|
||||
@ -380,7 +380,7 @@ static inline int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||
}
|
||||
|
||||
static inline void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
|
||||
unsigned long action) {}
|
||||
bool is_dead) {}
|
||||
|
||||
static inline void acpi_processor_throttling_init(void) {}
|
||||
#endif /* CONFIG_ACPI_CPU_FREQ_PSS */
|
||||
|
@ -25,6 +25,7 @@ enum cpuhp_state {
|
||||
CPUHP_IRQ_POLL_DEAD,
|
||||
CPUHP_BLOCK_SOFTIRQ_DEAD,
|
||||
CPUHP_VIRT_SCSI_DEAD,
|
||||
CPUHP_ACPI_CPUDRV_DEAD,
|
||||
CPUHP_WORKQUEUE_PREP,
|
||||
CPUHP_POWER_NUMA_PREPARE,
|
||||
CPUHP_HRTIMERS_PREPARE,
|
||||
|
Loading…
Reference in New Issue
Block a user