Power management fix for 4.17-rc4

This fixes a regression from the 4.14 cycle in the CPPC cpufreq
 driver causing it to use an incorrect transition delay value
 which leads to a very high rate of frequency change requests when
 the schedutil governor is in use (Prashanth Prakash).
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABCAAGBQJa7CgAAAoJEILEb/54YlRxOuAP/1aKd0w41BMpwlS2knk5nBhw
 nfVJJAIvrqd8eLGd7D0m4mSQGRLDB7MXCgqNbTpvQQniAM1dQmUrsJmcahiKxxBr
 BAYabnxezMTNc8H3r/YI7YIsxYQ5/vYhhydDSM4MDVP39m7xCUa2gsjOS7tngM32
 ppy78Ob0GBA4JCZo98wByNcXpautS/z/b/NdSMDcrgUZVe4WYht6V6q2lGaD3q2m
 4DdenTOQU7o0R8ModMpw7bFemQAWQcthiGq9y7u3A4k4zgQ+t77gN7f75gUUf+lz
 IfLKBF2S1GmqJ+T3y47Wb/ok+dJozIWx0sPTl6QP3Cn4KcqvmusqHoz/cOW7G0lr
 dt5tzGzk8Q2IYKtmg02d+KwF7yCZa2dSuWHCGnS9C4p2VVvm2Cv2rbSuDesFYu4D
 TPLXZgLPmfptNpUJ3gHbJCnin6laybkVW9b1O7c0YD5HbgVKLBwbvTGooiNbyn0L
 LQlggat4DET/Ul+k4FW40zhsDO07u9sAjPAGkvGHvLqnWQ7SABIwHSayYTv+r8Ta
 0zDvSHC0I3Iwg1lgS7JEQi2CZwGBhHW/5xHzYFFJc7UQoVwbTdPcqsUJlAViafe9
 UlT789KRdSFPmFXy/EG+u+2yq1YiRcV52Tyi7VMmJ0IOrXLHhj9ZoJQQ1VlOvMCd
 bLL44TeGfDgbM7861Ynp
 =dt55
 -----END PGP SIGNATURE-----

Merge tag 'pm-4.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fix from Rafael Wysocki:
 "This fixes a regression from the 4.14 cycle in the CPPC cpufreq driver
  causing it to use an incorrect transition delay value which leads to a
  very high rate of frequency change requests when the schedutil
  governor is in use (Prashanth Prakash)"

* tag 'pm-4.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq / CPPC: Set platform specific transition_delay_us
This commit is contained in:
Linus Torvalds 2018-05-04 05:44:50 -10:00
commit 54c6fd566b
1 changed files with 44 additions and 2 deletions

View File

@ -126,6 +126,49 @@ static void cppc_cpufreq_stop_cpu(struct cpufreq_policy *policy)
cpu->perf_caps.lowest_perf, cpu_num, ret);
}
/*
* The PCC subspace describes the rate at which platform can accept commands
* on the shared PCC channel (including READs which do not count towards freq
* trasition requests), so ideally we need to use the PCC values as a fallback
* if we don't have a platform specific transition_delay_us
*/
#ifdef CONFIG_ARM64
#include <asm/cputype.h>
static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
{
unsigned long implementor = read_cpuid_implementor();
unsigned long part_num = read_cpuid_part_number();
unsigned int delay_us = 0;
switch (implementor) {
case ARM_CPU_IMP_QCOM:
switch (part_num) {
case QCOM_CPU_PART_FALKOR_V1:
case QCOM_CPU_PART_FALKOR:
delay_us = 10000;
break;
default:
delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
break;
}
break;
default:
delay_us = cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
break;
}
return delay_us;
}
#else
static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
{
return cppc_get_transition_latency(cpu) / NSEC_PER_USEC;
}
#endif
static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
struct cppc_cpudata *cpu;
@ -162,8 +205,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpu->perf_caps.highest_perf;
policy->cpuinfo.max_freq = cppc_dmi_max_khz;
policy->transition_delay_us = cppc_get_transition_latency(cpu_num) /
NSEC_PER_USEC;
policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num);
policy->shared_type = cpu->shared_type;
if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {