From f416fb6f436874f7da7d7c9a200563cc8dbf0bce Mon Sep 17 00:00:00 2001 From: Youngtae Lee Date: Mon, 21 May 2018 14:03:20 +0900 Subject: [PATCH] cpupm: change condition for cpuhp_last_cpu mask. Change-Id: I2a276317d3857db99317f9314e5fe567b7bcc96d Signed-off-by: Youngtae Lee --- drivers/soc/samsung/exynos-cpupm.c | 39 ++++++++++++++++-------------- include/soc/samsung/exynos-cpupm.h | 1 - 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/soc/samsung/exynos-cpupm.c b/drivers/soc/samsung/exynos-cpupm.c index 561e45c0f622..c143f7716aac 100644 --- a/drivers/soc/samsung/exynos-cpupm.c +++ b/drivers/soc/samsung/exynos-cpupm.c @@ -21,6 +21,14 @@ #include #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) { diff --git a/include/soc/samsung/exynos-cpupm.h b/include/soc/samsung/exynos-cpupm.h index 34bb02f3b80a..06292fc19ee1 100644 --- a/include/soc/samsung/exynos-cpupm.h +++ b/include/soc/samsung/exynos-cpupm.h @@ -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); -- 2.20.1