|
@@ -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;
|
|
|
-
|
|
|
- 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);
|
|
|
+ return 0;
|
|
|
+ /*
|
|
|
+ * 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, 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);
|
|
|
}
|
|
|
|