Skip to content

Commit d93df29

Browse files
xiangwei-Lirafaeljw
authored andcommitted
cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception
When the nominal_freq recorded by the kernel is equal to the lowest_freq, and the frequency adjustment operation is triggered externally, there is a logic error in cppc_perf_to_khz()/cppc_khz_to_perf(), resulting in perf and khz conversion errors. Fix this by adding a branch processing logic when nominal_freq is equal to lowest_freq. Fixes: ec1c7ad ("cpufreq: CPPC: Fix performance/frequency conversion") Signed-off-by: liwei <[email protected]> Acked-by: Viresh Kumar <[email protected]> Link: https://patch.msgid.link/[email protected] [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 29dcbea commit d93df29

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

drivers/acpi/cppc_acpi.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,9 +1916,15 @@ unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf)
19161916
u64 mul, div;
19171917

19181918
if (caps->lowest_freq && caps->nominal_freq) {
1919-
mul = caps->nominal_freq - caps->lowest_freq;
1919+
/* Avoid special case when nominal_freq is equal to lowest_freq */
1920+
if (caps->lowest_freq == caps->nominal_freq) {
1921+
mul = caps->nominal_freq;
1922+
div = caps->nominal_perf;
1923+
} else {
1924+
mul = caps->nominal_freq - caps->lowest_freq;
1925+
div = caps->nominal_perf - caps->lowest_perf;
1926+
}
19201927
mul *= KHZ_PER_MHZ;
1921-
div = caps->nominal_perf - caps->lowest_perf;
19221928
offset = caps->nominal_freq * KHZ_PER_MHZ -
19231929
div64_u64(caps->nominal_perf * mul, div);
19241930
} else {
@@ -1939,11 +1945,17 @@ unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq)
19391945
{
19401946
s64 retval, offset = 0;
19411947
static u64 max_khz;
1942-
u64 mul, div;
1948+
u64 mul, div;
19431949

19441950
if (caps->lowest_freq && caps->nominal_freq) {
1945-
mul = caps->nominal_perf - caps->lowest_perf;
1946-
div = caps->nominal_freq - caps->lowest_freq;
1951+
/* Avoid special case when nominal_freq is equal to lowest_freq */
1952+
if (caps->lowest_freq == caps->nominal_freq) {
1953+
mul = caps->nominal_perf;
1954+
div = caps->nominal_freq;
1955+
} else {
1956+
mul = caps->nominal_perf - caps->lowest_perf;
1957+
div = caps->nominal_freq - caps->lowest_freq;
1958+
}
19471959
/*
19481960
* We don't need to convert to kHz for computing offset and can
19491961
* directly use nominal_freq and lowest_freq as the div64_u64

0 commit comments

Comments
 (0)