Re: [PATCH 4/5] cpufreq: loongson3: Use global physical CPU ID in get/target callbacks
Zhongqiu Han <[email protected]>
| Newsgroups | org.kernel.vger.linux-pm,dev.linux.lists.loongarch,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
On 8/18/2026 8:39 PM, Huacai Chen wrote: > 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: [email protected] > Signed-off-by: Hongliang Wang <[email protected]> > Signed-off-by: Huacai Chen <[email protected]> > --- > drivers/cpufreq/loongson3_cpufreq.c | 20 +++++++++++--------- > 1 file changed, 11 insertions(+), 9 deletions(-) > > diff --git a/drivers/cpufreq/loongson3_cpufreq.c b/drivers/cpufreq/loongson3_cpufreq.c > index e3cd78a5ab18..c75c0e30e881 100644 > --- a/drivers/cpufreq/loongson3_cpufreq.c > +++ b/drivers/cpufreq/loongson3_cpufreq.c > @@ -219,38 +219,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); As patch 5/5 changelog: "However, IOCSR read/write can only perform on the current node, while sometimes we want to perform on other nodes" However, patch 4/5 starts passing the global CPU number without updating do_service_request(), which is only changed in patch 5/5. Doesn't that mean patch 4/5 is broken on its own? > > return ret * KILO; > } > A separate issue, do_service_request() can return errno such as -EPERM, it will cause .get() func return a large unsigned integer value. > 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 +265,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; -- Thx and BRs, Zhongqiu Han