Commit-ID:  64f3bf2f85c5690228200d6b94eb6847049af70d
Gitweb:     http://git.kernel.org/tip/64f3bf2f85c5690228200d6b94eb6847049af70d
Author:     Sebastian Andrzej Siewior <bige...@linutronix.de>
AuthorDate: Tue, 6 Sep 2016 19:04:47 +0200
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Mon, 19 Sep 2016 21:44:29 +0200

ACPI/processor: Convert to hotplug state machine

Install the callbacks via the state machine.

Signed-off-by: Sebastian Andrzej Siewior <bige...@linutronix.de>
Acked-by: "Rafael J. Wysocki" <r...@rjwysocki.net>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: linux-a...@vger.kernel.org
Cc: r...@linutronix.de
Cc: Len Brown <l...@kernel.org>
Link: http://lkml.kernel.org/r/20160906170457.32393-12-bige...@linutronix.de
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 drivers/acpi/processor_driver.c     | 91 +++++++++++++++++++------------------
 drivers/acpi/processor_throttling.c |  4 +-
 include/acpi/processor.h            |  4 +-
 include/linux/cpuhotplug.h          |  1 +
 4 files changed, 52 insertions(+), 48 deletions(-)

diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 0553aee..13e5ac4 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -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);
 }
 
diff --git a/drivers/acpi/processor_throttling.c 
b/drivers/acpi/processor_throttling.c
index c72e648..d51ca1c 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -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.
                 */
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index bfe6b2e..f3db11c 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -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 */
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index e7146ee..7706987 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -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,

Reply via email to