From: Park Bumgyu Date: Mon, 19 Feb 2018 04:50:19 +0000 (+0900) Subject: soc: cpupm: support system idle X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c2f7bd92a6be53f732e2e0b886b279269d2942c6;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git soc: cpupm: support system idle Change-Id: Id861005931eff43e61c9cd7b98aed8d00adc61b1 Signed-off-by: Park Bumgyu --- diff --git a/drivers/soc/samsung/exynos-cpupm.c b/drivers/soc/samsung/exynos-cpupm.c index 821316c6c9a3..a69d0023f913 100644 --- a/drivers/soc/samsung/exynos-cpupm.c +++ b/drivers/soc/samsung/exynos-cpupm.c @@ -15,6 +15,7 @@ #include #include +#include #include /****************************************************************************** @@ -106,6 +107,12 @@ struct power_mode { /* disable count */ atomic_t disable; + + /* + * Some power modes can determine whether to enter power mode + * depending on system idle state + */ + bool system_idle; }; /* Maximum number of power modes manageable per cpu */ @@ -231,6 +238,11 @@ static int cpus_busy(int target_residency, const struct cpumask *cpus) return 0; } +static int system_busy(void) +{ + return 0; +} + /* * In order to enter the power mode, the following conditions must be met: * 1. power mode should not be disabled @@ -250,6 +262,9 @@ static int can_enter_power_mode(int cpu, struct power_mode *mode) if (cpus_busy(mode->target_residency, &mode->siblings)) return 0; + if (mode->system_idle && system_busy()) + return 0; + return 1; } @@ -272,6 +287,10 @@ static int try_to_enter_power_mode(int cpu, struct power_mode *mode) case POWERMODE_TYPE_CLUSTER: cluster_disable(cpu_topology[cpu].cluster_id); break; + case POWERMODE_TYPE_SYSTEM: + if (unlikely(exynos_system_idle_enter())) + return 0; + break; } exynos_ss_cpuidle(mode->name, 0, 0, ESS_FLAG_IN); @@ -280,7 +299,7 @@ static int try_to_enter_power_mode(int cpu, struct power_mode *mode) return 1; } -static void exit_mode(int cpu, struct power_mode *mode) +static void exit_mode(int cpu, struct power_mode *mode, int cancel) { /* * Configure settings to exit power mode. This is executed by the @@ -293,6 +312,9 @@ static void exit_mode(int cpu, struct power_mode *mode) case POWERMODE_TYPE_CLUSTER: cluster_enable(cpu_topology[cpu].cluster_id); break; + case POWERMODE_TYPE_SYSTEM: + exynos_system_idle_exit(cancel); + break; } } @@ -344,7 +366,7 @@ void exynos_cpu_pm_exit(int cpu, int cancel) break; if (check_state_powerdown(mode)) - exit_mode(cpu, mode); + exit_mode(cpu, mode, cancel); } /* Set cpu state to RUN */ @@ -429,6 +451,9 @@ static int __init cpu_power_mode_init(void) of_property_read_u32(dn, "psci-index", &mode->psci_index); of_property_read_u32(dn, "type", &mode->type); + if (of_property_read_bool(dn, "system-idle")) + mode->system_idle = true; + if (!of_property_read_string(dn, "siblings", &buf)) cpulist_parse(buf, &mode->siblings); diff --git a/include/soc/samsung/exynos-cpupm.h b/include/soc/samsung/exynos-cpupm.h index 12b0a3ca40c1..765b6404c027 100644 --- a/include/soc/samsung/exynos-cpupm.h +++ b/include/soc/samsung/exynos-cpupm.h @@ -14,6 +14,7 @@ extern void exynos_cpu_pm_exit(int cpu, int cancel); enum { POWERMODE_TYPE_CLUSTER = 0, + POWERMODE_TYPE_SYSTEM, }; extern void disable_mode(int cpu, int type);