[PATCH v5 2/3] cpufreq: cppc: Refactor autonomous perf bounds into helper
Xueqin Luo <[email protected]>
| Newsgroups | dev.linux.lists.driver-core,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm |
|---|---|
| Message-ID | <[email protected]> |
Extract the autonomous selection performance bounds programming from store_auto_select() into a reusable cppc_cpufreq_set_autonomous_perf() helper. The helper saves and restores MIN/MAX performance on failure, keeping the rollback logic co-located with the programming sequence. Reuse the helper in cppc_cpufreq_update_limits() so that when Highest Performance changes at runtime, the autonomous MIN/MAX envelope is re-programmed against the updated capability. Add a pr_debug message on failure for diagnostics. Signed-off-by: Xueqin Luo <[email protected]> --- drivers/cpufreq/cppc_cpufreq.c | 57 ++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 089f734f851b..09d7745a609f 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -868,6 +868,37 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state) * policy->max) rather than by hiding the hardware max in cpuinfo. * boost_freq_req itself is only created at policy init, not here. */ + +/** + * cppc_cpufreq_set_autonomous_perf - Configure performance bounds for + * autonomous mode + * @policy: cpufreq policy structure + * + * When autonomous selection is enabled, program MIN_PERF and MAX_PERF + * from current policy limits so that the platform uses the correct + * performance bounds immediately. + * + * Return: 0 on success, negative error code on failure. + */ +static int cppc_cpufreq_set_autonomous_perf(struct cpufreq_policy *policy) +{ + struct cppc_cpudata *cpu_data = policy->driver_data; + u32 old_min_perf = cpu_data->perf_ctrls.min_perf; + u32 old_max_perf = cpu_data->perf_ctrls.max_perf; + int ret; + + cppc_cpufreq_update_perf_limits(cpu_data, policy); + + ret = cppc_set_perf(policy->cpu, &cpu_data->perf_ctrls); + if (ret) { + cpu_data->perf_ctrls.min_perf = old_min_perf; + cpu_data->perf_ctrls.max_perf = old_max_perf; + return ret; + } + + return 0; +} + static void cppc_cpufreq_sync_boost_limits(struct cpufreq_policy *policy, bool boost_supported) { @@ -948,6 +979,18 @@ static void cppc_cpufreq_update_limits(struct cpufreq_policy *policy) refresh_frequency_limits(policy); + /* + * Autonomous selection mode uses MIN/MAX performance as runtime + * hardware control bounds. Re-program them when highest_perf + * changes so that the platform uses the updated bounds. + */ + if (cpu_data->perf_ctrls.auto_sel) { + ret = cppc_cpufreq_set_autonomous_perf(policy); + if (ret) + pr_debug("CPU%d: failed to update autonomous perf: %d\n", + policy->cpu, ret); + } + pr_debug("CPU%d: highest_perf updated %llu -> %llu\n", policy->cpu, prev_highest_perf, highest_perf); } @@ -994,20 +1037,8 @@ static ssize_t store_auto_select(struct cpufreq_policy *policy, cpu_data->perf_ctrls.auto_sel = val; if (val) { - u32 old_min_perf = cpu_data->perf_ctrls.min_perf; - u32 old_max_perf = cpu_data->perf_ctrls.max_perf; - - /* - * When enabling autonomous selection, program MIN_PERF and - * MAX_PERF from current policy limits so that the platform - * uses the correct performance bounds immediately. - */ - cppc_cpufreq_update_perf_limits(cpu_data, policy); - - ret = cppc_set_perf(policy->cpu, &cpu_data->perf_ctrls); + ret = cppc_cpufreq_set_autonomous_perf(policy); if (ret) { - cpu_data->perf_ctrls.min_perf = old_min_perf; - cpu_data->perf_ctrls.max_perf = old_max_perf; cppc_set_auto_sel(policy->cpu, false); cpu_data->perf_ctrls.auto_sel = false; return ret; -- 2.43.0