cpufreq: acme: remove race contdition when set/get freq
authorSoohyun Kim <soohyuni.kim@samsung.com>
Mon, 2 Apr 2018 23:58:05 +0000 (08:58 +0900)
committerChungwoo Park <cww.park@samsung.com>
Mon, 21 May 2018 08:33:23 +0000 (17:33 +0900)
Change-Id: I964b18bc4eab0914879c7cf0226ee8bc780dd9de
Signed-off-by: Soohyun Kim <soohyuni.kim@samsung.com>
drivers/soc/samsung/exynos-cpupm.c

index 5eb9f67ce4d3c29eafb7dbd8f56d450f1f808ca9..c72c36f22e42557a1da99b91acb8deb43fb576d3 100644 (file)
@@ -455,6 +455,7 @@ void disable_power_mode(int cpu, int type)
        struct power_mode *mode;
        int pos;
 
+       spin_lock(&cpupm_lock);
        pm = &per_cpu(cpupm, cpu);
 
        for_each_mode(mode, pm->modes, pos) {
@@ -473,10 +474,14 @@ void disable_power_mode(int cpu, int type)
                         * The first mode disable request wakes the cpus to
                         * exit power mode
                         */
-                       if (atomic_inc_return(&mode->disable) == 1)
+                       if (atomic_inc_return(&mode->disable) == 1) {
+                               spin_unlock(&cpupm_lock);
                                awake_cpus(&mode->siblings);
+                               return;
+                       }
                }
        }
+       spin_unlock(&cpupm_lock);
 }
 
 void enable_power_mode(int cpu, int type)
@@ -485,6 +490,7 @@ void enable_power_mode(int cpu, int type)
        struct power_mode *mode;
        int pos;
 
+       spin_lock(&cpupm_lock);
        pm = &per_cpu(cpupm, cpu);
 
        for_each_mode(mode, pm->modes, pos) {
@@ -494,6 +500,7 @@ void enable_power_mode(int cpu, int type)
                if (mode->type == type)
                        atomic_dec(&mode->disable);
        }
+       spin_unlock(&cpupm_lock);
 }
 
 /* get sleep length of given cpu from tickless framework */