soc: cpupm: handle cpu hotplug
authorPark Bumgyu <bumgyu.park@samsung.com>
Tue, 13 Feb 2018 12:05:16 +0000 (21:05 +0900)
committerChungwoo Park <cww.park@samsung.com>
Mon, 21 May 2018 08:30:30 +0000 (17:30 +0900)
Change-Id: I0a2eb08b97bb8d4d07cec790cae13523ed0fadc8
Signed-off-by: Park Bumgyu <bumgyu.park@samsung.com>
drivers/soc/samsung/exynos-cpupm.c

index 3ba345acaa5fcbd5a88356ea14bfa7c6352edbb7..821316c6c9a384e144a9313dff1781b229b06619 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/tick.h>
 #include <linux/psci.h>
+#include <linux/cpuhotplug.h>
 
 #include <soc/samsung/exynos-cpupm.h>
 #include <soc/samsung/cal-if.h>
@@ -355,6 +356,35 @@ void exynos_cpu_pm_exit(int cpu, int cancel)
        spin_unlock(&cpupm_lock);
 }
 
+/******************************************************************************
+ *                               CPU HOTPLUG                                  *
+ ******************************************************************************/
+static int cpuhp_cpupm_online(unsigned int cpu)
+{
+       struct cpumask mask;
+
+       cpumask_and(&mask, cpu_coregroup_mask(cpu), cpu_online_mask);
+       if (cpumask_weight(&mask) == 0)
+               cluster_enable(cpu);
+
+       cpu_enable(cpu);
+
+       return 0;
+}
+
+static int cpuhp_cpupm_offline(unsigned int cpu)
+{
+       struct cpumask mask;
+
+       cpu_disable(cpu);
+
+       cpumask_and(&mask, cpu_coregroup_mask(cpu), cpu_online_mask);
+       if (cpumask_weight(&mask) == 0)
+               cluster_disable(cpu);
+
+       return 0;
+}
+
 /******************************************************************************
  *                                Initialization                              *
  ******************************************************************************/
@@ -424,3 +454,16 @@ static int __init exynos_cpupm_init(void)
        return 0;
 }
 arch_initcall(exynos_cpupm_init);
+
+static int __init exynos_cpupm_early_init(void)
+{
+       cpuhp_setup_state(CPUHP_AP_EXYNOS_CPU_UP_POWER_CONTROL,
+                               "AP_EXYNOS_CPU_UP_POWER_CONTROL",
+                               cpuhp_cpupm_online, NULL);
+       cpuhp_setup_state(CPUHP_AP_EXYNOS_CPU_DOWN_POWER_CONTROL,
+                               "AP_EXYNOS_CPU_DOWN_POWER_CONTROL",
+                               NULL, cpuhp_cpupm_offline);
+
+       return 0;
+}
+early_initcall(exynos_cpupm_early_init);