cpupm: change condition for cpuhp_last_cpu mask.
authorYoungtae Lee <yt0729.lee@samsung.com>
Mon, 21 May 2018 05:03:20 +0000 (14:03 +0900)
committerlakkyung.jung <lakkyung.jung@samsung.com>
Mon, 23 Jul 2018 05:59:20 +0000 (14:59 +0900)
Change-Id: I2a276317d3857db99317f9314e5fe567b7bcc96d
Signed-off-by: Youngtae Lee <yt0729.lee@samsung.com>
drivers/soc/samsung/exynos-cpupm.c
include/soc/samsung/exynos-cpupm.h

index 561e45c0f622f032ffd7b3e8e7ca03c15fd38790..c143f7716aac814ee4b9dc298b4dd3b24efdf020 100644 (file)
 #include <soc/samsung/exynos-pmu.h>
 
 #ifdef CONFIG_CPU_IDLE
+/*
+ * State of each cpu is managed by a structure declared by percpu, so there
+ * is no need for protection for synchronization. However, when entering
+ * the power mode, it is necessary to set the critical section to check the
+ * state of cpus in the power domain, cpupm_lock is used for it.
+ */
+static spinlock_t cpupm_lock;
+
 /******************************************************************************
  *                                  IDLE_IP                                   *
  ******************************************************************************/
@@ -299,11 +307,11 @@ static void cluster_disable(unsigned int cpu_id)
  *                               CPU HOTPLUG                                  *
  ******************************************************************************/
 /* cpumask for indecating last cpu of a cluster */
-struct cpumask cpuhp_last_cpu;
+struct cpumask cpuhp_last_mask;
 
 bool exynos_cpuhp_last_cpu(unsigned int cpu)
 {
-       return cpumask_test_cpu(cpu, &cpuhp_last_cpu);
+       return cpumask_test_cpu(cpu, &cpuhp_last_mask);
 }
 
 static int cpuhp_cpupm_online(unsigned int cpu)
@@ -313,9 +321,9 @@ static int cpuhp_cpupm_online(unsigned int cpu)
        cpumask_and(&mask, cpu_cluster_mask(cpu), cpu_online_mask);
        if (cpumask_weight(&mask) == 0) {
                cluster_enable(cpu);
-               /* clear cpus of this cluster from cpuhp_last_cpu */
-               cpumask_andnot(&cpuhp_last_cpu,
-                       &cpuhp_last_cpu, cpu_coregroup_mask(cpu));
+               /* clear cpus of this cluster from cpuhp_last_mask */
+               cpumask_andnot(&cpuhp_last_mask,
+                       &cpuhp_last_mask, cpu_cluster_mask(cpu));
        }
 
        cpu_enable(cpu);
@@ -325,16 +333,19 @@ static int cpuhp_cpupm_online(unsigned int cpu)
 
 static int cpuhp_cpupm_offline(unsigned int cpu)
 {
-       struct cpumask mask;
+       struct cpumask online_mask, last_mask;
 
        cpu_disable(cpu);
 
-       cpumask_and(&mask, cpu_cluster_mask(cpu), cpu_online_mask);
-       if ((cpumask_weight(&mask) == 0) && cpuhp_last_fastcpu(cpu)) {
-               /* set cpu cpuhp_last_cpu */
-               cpumask_set_cpu(cpu, &cpuhp_last_cpu);
+       spin_lock(&cpupm_lock);
+       cpumask_and(&online_mask, cpu_cluster_mask(cpu), cpu_online_mask);
+       cpumask_and(&last_mask, cpu_cluster_mask(cpu), &cpuhp_last_mask);
+       if ((cpumask_weight(&online_mask) == 0) && cpumask_empty(&last_mask)) {
+               /* set cpu cpuhp_last_mask */
+               cpumask_set_cpu(cpu, &cpuhp_last_mask);
                cluster_disable(cpu);
        }
+       spin_unlock(&cpupm_lock);
 
        return 0;
 }
@@ -451,14 +462,6 @@ struct exynos_cpupm {
 
 static DEFINE_PER_CPU(struct exynos_cpupm, cpupm);
 
-/*
- * State of each cpu is managed by a structure declared by percpu, so there
- * is no need for protection for synchronization. However, when entering
- * the power mode, it is necessary to set the critical section to check the
- * state of cpus in the power domain, cpupm_lock is used for it.
- */
-static spinlock_t cpupm_lock;
-
 /* Nop function to awake cpus */
 static void do_nothing(void *unused)
 {
index 34bb02f3b80a046924a6776643b665226ce620dc..06292fc19ee19029f0082f8c8c9211a11d2ee0b8 100644 (file)
@@ -20,7 +20,6 @@ enum {
 extern void disable_power_mode(int cpu, int type);
 extern void enable_power_mode(int cpu, int type);
 extern bool exynos_cpuhp_last_cpu(unsigned int cpu);
-extern bool cpuhp_last_fastcpu(unsigned int cpu);
 
 #ifdef CONFIG_CPU_IDLE
 void exynos_update_ip_idle_status(int index, int idle);