aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/intel_pstate.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-03-26 07:15:13 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-04-01 17:43:05 -0400
commit5a25e3f7cc538fb49e11267c1e41c54ccf83835e (patch)
treee964c1948f3065cc885e0c36fe1b061c3d5ffd45 /drivers/cpufreq/intel_pstate.c
parent79a3aaa7b82e3106be97842dedfd8429248896e6 (diff)
cpufreq: intel_pstate: Driver-specific handling of _PPC updates
In some cases, the platform firmware disables or enables turbo frequencies for all CPUs globally before triggering a _PPC change notification for one of them. Obviously, that global change affects all CPUs, not just the notified one, and it needs to be acted upon by cpufreq. The intel_pstate driver is able to detect such global changes of the settings, but it also needs to update policy limits for all CPUs if that happens, in particular if turbo frequencies are enabled globally - to allow them to be used. For this reason, introduce a new cpufreq driver callback to be invoked on _PPC notifications, if present, instead of simply calling cpufreq_update_policy() for the notified CPU and make intel_pstate use it to trigger policy updates for all CPUs in the system if global settings change. Link: https://bugzilla.kernel.org/show_bug.cgi?id=200759 Reported-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r--drivers/cpufreq/intel_pstate.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index b599c7318aab..e2191a570ade 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -179,6 +179,7 @@ struct vid_data {
179 * based on the MSR_IA32_MISC_ENABLE value and whether or 179 * based on the MSR_IA32_MISC_ENABLE value and whether or
180 * not the maximum reported turbo P-state is different from 180 * not the maximum reported turbo P-state is different from
181 * the maximum reported non-turbo one. 181 * the maximum reported non-turbo one.
182 * @turbo_disabled_s: Saved @turbo_disabled value.
182 * @min_perf_pct: Minimum capacity limit in percent of the maximum turbo 183 * @min_perf_pct: Minimum capacity limit in percent of the maximum turbo
183 * P-state capacity. 184 * P-state capacity.
184 * @max_perf_pct: Maximum capacity limit in percent of the maximum turbo 185 * @max_perf_pct: Maximum capacity limit in percent of the maximum turbo
@@ -187,6 +188,7 @@ struct vid_data {
187struct global_params { 188struct global_params {
188 bool no_turbo; 189 bool no_turbo;
189 bool turbo_disabled; 190 bool turbo_disabled;
191 bool turbo_disabled_s;
190 int max_perf_pct; 192 int max_perf_pct;
191 int min_perf_pct; 193 int min_perf_pct;
192}; 194};
@@ -897,6 +899,25 @@ static void intel_pstate_update_policies(void)
897 cpufreq_update_policy(cpu); 899 cpufreq_update_policy(cpu);
898} 900}
899 901
902static void intel_pstate_update_limits(unsigned int cpu)
903{
904 mutex_lock(&intel_pstate_driver_lock);
905
906 update_turbo_state();
907 /*
908 * If turbo has been turned on or off globally, policy limits for
909 * all CPUs need to be updated to reflect that.
910 */
911 if (global.turbo_disabled_s != global.turbo_disabled) {
912 global.turbo_disabled_s = global.turbo_disabled;
913 intel_pstate_update_policies();
914 } else {
915 cpufreq_update_policy(cpu);
916 }
917
918 mutex_unlock(&intel_pstate_driver_lock);
919}
920
900/************************** sysfs begin ************************/ 921/************************** sysfs begin ************************/
901#define show_one(file_name, object) \ 922#define show_one(file_name, object) \
902 static ssize_t show_##file_name \ 923 static ssize_t show_##file_name \
@@ -2138,6 +2159,7 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
2138 /* cpuinfo and default policy values */ 2159 /* cpuinfo and default policy values */
2139 policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling; 2160 policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling;
2140 update_turbo_state(); 2161 update_turbo_state();
2162 global.turbo_disabled_s = global.turbo_disabled;
2141 policy->cpuinfo.max_freq = global.turbo_disabled ? 2163 policy->cpuinfo.max_freq = global.turbo_disabled ?
2142 cpu->pstate.max_pstate : cpu->pstate.turbo_pstate; 2164 cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
2143 policy->cpuinfo.max_freq *= cpu->pstate.scaling; 2165 policy->cpuinfo.max_freq *= cpu->pstate.scaling;
@@ -2182,6 +2204,7 @@ static struct cpufreq_driver intel_pstate = {
2182 .init = intel_pstate_cpu_init, 2204 .init = intel_pstate_cpu_init,
2183 .exit = intel_pstate_cpu_exit, 2205 .exit = intel_pstate_cpu_exit,
2184 .stop_cpu = intel_pstate_stop_cpu, 2206 .stop_cpu = intel_pstate_stop_cpu,
2207 .update_limits = intel_pstate_update_limits,
2185 .name = "intel_pstate", 2208 .name = "intel_pstate",
2186}; 2209};
2187 2210
@@ -2316,6 +2339,7 @@ static struct cpufreq_driver intel_cpufreq = {
2316 .init = intel_cpufreq_cpu_init, 2339 .init = intel_cpufreq_cpu_init,
2317 .exit = intel_pstate_cpu_exit, 2340 .exit = intel_pstate_cpu_exit,
2318 .stop_cpu = intel_cpufreq_stop_cpu, 2341 .stop_cpu = intel_cpufreq_stop_cpu,
2342 .update_limits = intel_pstate_update_limits,
2319 .name = "intel_cpufreq", 2343 .name = "intel_cpufreq",
2320}; 2344};
2321 2345