cpufreq: loongson3: Use global physical CPU ID in get/target callbacks

Our server productions (e.g. Loongson-3D6000/3E6000) can have discrete
global physical CPU IDs while the core ID inside the packages are always
continuous. In these cases we should use global physical CPU IDs to get
and set frequencies.

Cc: stable@vger.kernel.org
Fixes: ccf5145414 ("cpufreq: Add Loongson-3 CPUFreq driver support")
Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
This commit is contained in:
Huacai Chen 2026-08-28 11:12:00 +08:00 committed by Viresh Kumar
parent 5d7802ada3
commit e38360d7c6

View File

@ -16,6 +16,7 @@
#include <asm/idle.h>
#include <asm/loongarch.h>
#include <asm/loongson.h>
#include <asm/smp.h>
/* Message */
union smc_message {
@ -219,38 +220,40 @@ static inline int do_service_request(u32 id, u32 info, u32 cmd, u32 val, u32 ext
static unsigned int loongson3_cpufreq_get(unsigned int cpu)
{
int ret;
int ret, core = cpu_logical_map(cpu);
ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_INFO, 0, 0);
ret = do_service_request(core, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_INFO, 0, 0);
return ret * KILO;
return (ret < 0) ? 0 : ret * KILO;
}
static int loongson3_cpufreq_target(struct cpufreq_policy *policy, unsigned int index)
{
int ret;
int ret, core = cpu_logical_map(policy->cpu);
ret = do_service_request(cpu_data[policy->cpu].core,
FREQ_INFO_TYPE_LEVEL, CMD_SET_FREQ_INFO, index, 0);
ret = do_service_request(core, FREQ_INFO_TYPE_LEVEL, CMD_SET_FREQ_INFO,
index, 0);
return (ret >= 0) ? 0 : ret;
}
static int configure_freq_table(int cpu)
{
int i, ret, boost_level, max_level, freq_level;
int i, ret, core, boost_level, max_level, freq_level;
struct platform_device *pdev = cpufreq_get_driver_data();
struct loongson3_freq_data *data;
if (per_cpu(freq_data, cpu))
return 0;
ret = do_service_request(cpu, 0, CMD_GET_FREQ_LEVEL_NUM, 0, 0);
core = cpu_logical_map(cpu);
ret = do_service_request(core, 0, CMD_GET_FREQ_LEVEL_NUM, 0, 0);
if (ret < 0)
return ret;
max_level = ret;
ret = do_service_request(cpu, 0, CMD_GET_FREQ_BOOST_LEVEL, 0, 0);
ret = do_service_request(core, 0, CMD_GET_FREQ_BOOST_LEVEL, 0, 0);
if (ret < 0)
return ret;
boost_level = ret;
@ -263,7 +266,7 @@ static int configure_freq_table(int cpu)
data->def_freq_level = boost_level - 1;
for (i = 0; i < freq_level; i++) {
ret = do_service_request(cpu, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_LEVEL_INFO, i, 0);
ret = do_service_request(core, FREQ_INFO_TYPE_FREQ, CMD_GET_FREQ_LEVEL_INFO, i, 0);
if (ret < 0) {
devm_kfree(&pdev->dev, data);
return ret;