diff mbox series

cpufreq: Init cpufreq only for present CPUs

Message ID 20250310071640.3140435-1-ping.bai@nxp.com (mailing list archive)
State New
Headers show
Series cpufreq: Init cpufreq only for present CPUs | expand

Commit Message

Jacky Bai March 10, 2025, 7:16 a.m. UTC
for_each_possible_cpu() is currently used to initialize cpufreq
in below cpufreq drivers:
  drivers/cpufreq/cpufreq-dt.c
  drivers/cpufreq/mediatek-cpufreq-hw.c
  drivers/cpufreq/mediatek-cpufreq.c
  drivers/cpufreq/qcom-cpufreq-nvmem.c
  drivers/cpufreq/sun50i-cpufreq-nvmem.c

However, in cpu_dev_register_generic(), for_each_present_cpu()
is used to register CPU devices which means the CPU devices are
only registered for present CPUs and not all possible CPUs.

With nosmp or maxcpus=0, only the boot CPU is present, lead
to the cpufreq probe failure or defer probe due to no cpu device
available for not present CPUs.

Change for_each_possible_cpu() to for_each_present_cpu() in the
above cpufreq drivers to ensure it only registers cpufreq for
CPUs that are actually present.

Fixes: b0c69e1214bc ("drivers: base: Use present CPUs in GENERIC_CPU_DEVICES")
Signed-off-by: Jacky Bai <ping.bai@nxp.com>
---
 drivers/cpufreq/cpufreq-dt.c           | 2 +-
 drivers/cpufreq/mediatek-cpufreq-hw.c  | 2 +-
 drivers/cpufreq/mediatek-cpufreq.c     | 2 +-
 drivers/cpufreq/qcom-cpufreq-nvmem.c   | 8 ++++----
 drivers/cpufreq/sun50i-cpufreq-nvmem.c | 6 +++---
 5 files changed, 10 insertions(+), 10 deletions(-)

Comments

Sudeep Holla March 10, 2025, 10:19 a.m. UTC | #1
On Mon, Mar 10, 2025 at 03:16:40PM +0800, Jacky Bai wrote:
> for_each_possible_cpu() is currently used to initialize cpufreq
> in below cpufreq drivers:
>   drivers/cpufreq/cpufreq-dt.c
>   drivers/cpufreq/mediatek-cpufreq-hw.c
>   drivers/cpufreq/mediatek-cpufreq.c
>   drivers/cpufreq/qcom-cpufreq-nvmem.c
>   drivers/cpufreq/sun50i-cpufreq-nvmem.c
>

Again how did you just narrow down to the list above ? Is that just a
random pick ? As I suggested with corresponding cpuidle changes, please
look into the details in side the for_each_possible_cpu() loop and then
decide if it applies or not.

For me, it applied to the below files as well at the least.

drivers/cpufreq/mvebu-cpufreq.c
drivers/cpufreq/qcom-cpufreq-hw.c
drivers/cpufreq/scmi-cpufreq.c
drivers/cpufreq/scpi-cpufreq.c
drivers/cpufreq/virtual-cpufreq.c

Please check everything thoroughly as I just looked at these briefly.

--
Regards,
Sudeep
Jacky Bai March 10, 2025, 10:56 a.m. UTC | #2
Hi Sudeep,

> Subject: Re: [PATCH] cpufreq: Init cpufreq only for present CPUs
> 
> On Mon, Mar 10, 2025 at 03:16:40PM +0800, Jacky Bai wrote:
> > for_each_possible_cpu() is currently used to initialize cpufreq in
> > below cpufreq drivers:
> >   drivers/cpufreq/cpufreq-dt.c
> >   drivers/cpufreq/mediatek-cpufreq-hw.c
> >   drivers/cpufreq/mediatek-cpufreq.c
> >   drivers/cpufreq/qcom-cpufreq-nvmem.c
> >   drivers/cpufreq/sun50i-cpufreq-nvmem.c
> >
> 
> Again how did you just narrow down to the list above ? Is that just a random
> pick ? As I suggested with corresponding cpuidle changes, please look into the
> details in side the for_each_possible_cpu() loop and then decide if it applies
> or not.
> 
> For me, it applied to the below files as well at the least.
> 
> drivers/cpufreq/mvebu-cpufreq.c
> drivers/cpufreq/qcom-cpufreq-hw.c
> drivers/cpufreq/scmi-cpufreq.c
> drivers/cpufreq/scpi-cpufreq.c
> drivers/cpufreq/virtual-cpufreq.c
> 

I checked these drivers before, these drivers has logic to check
if the cpu device is available, then skip the not present cpu.
From my understanding, using 'for_each_possible_cpu' will not
cause the cpufreq driver failed to register for nosmp case, so I skipped.
For those I just changed in the patch, the cpufreq will be failed to register totally.
I can changes all of them together as you suggested if no other guys object.

Thank you for your comments. :)

BR
Jacky Bai
> Please check everything thoroughly as I just looked at these briefly.
> 
> --
> Regards,
> Sudeep
diff mbox series

Patch

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index 778916f89a51..e80dd982a3e2 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -283,7 +283,7 @@  static int dt_cpufreq_probe(struct platform_device *pdev)
 	int ret, cpu;
 
 	/* Request resources early so we can return in case of -EPROBE_DEFER */
-	for_each_possible_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		ret = dt_cpufreq_early_init(&pdev->dev, cpu);
 		if (ret)
 			goto err;
diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c
index aa209f5527dc..74f1b4c796e4 100644
--- a/drivers/cpufreq/mediatek-cpufreq-hw.c
+++ b/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -303,7 +303,7 @@  static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
 	struct regulator *cpu_reg;
 
 	/* Make sure that all CPU supplies are available before proceeding. */
-	for_each_possible_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		cpu_dev = get_cpu_device(cpu);
 		if (!cpu_dev)
 			return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
index 2656b88db378..f3f02c4b6888 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -631,7 +631,7 @@  static int mtk_cpufreq_probe(struct platform_device *pdev)
 		return dev_err_probe(&pdev->dev, -ENODEV,
 				     "failed to get mtk cpufreq platform data\n");
 
-	for_each_possible_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		info = mtk_cpu_dvfs_info_lookup(cpu);
 		if (info)
 			continue;
diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
index 3a8ed723a23e..54f8117103c8 100644
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
@@ -489,7 +489,7 @@  static int qcom_cpufreq_probe(struct platform_device *pdev)
 		nvmem_cell_put(speedbin_nvmem);
 	}
 
-	for_each_possible_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		struct dev_pm_opp_config config = {
 			.supported_hw = NULL,
 		};
@@ -543,7 +543,7 @@  static int qcom_cpufreq_probe(struct platform_device *pdev)
 	dev_err(cpu_dev, "Failed to register platform device\n");
 
 free_opp:
-	for_each_possible_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		dev_pm_domain_detach_list(drv->cpus[cpu].pd_list);
 		dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
 	}
@@ -557,7 +557,7 @@  static void qcom_cpufreq_remove(struct platform_device *pdev)
 
 	platform_device_unregister(cpufreq_dt_pdev);
 
-	for_each_possible_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		dev_pm_domain_detach_list(drv->cpus[cpu].pd_list);
 		dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
 	}
@@ -568,7 +568,7 @@  static int qcom_cpufreq_suspend(struct device *dev)
 	struct qcom_cpufreq_drv *drv = dev_get_drvdata(dev);
 	unsigned int cpu;
 
-	for_each_possible_cpu(cpu)
+	for_each_present_cpu(cpu)
 		qcom_cpufreq_suspend_pd_devs(drv, cpu);
 
 	return 0;
diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
index 17d6a149f580..47d6840b3489 100644
--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
@@ -262,7 +262,7 @@  static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 	snprintf(name, sizeof(name), "speed%d", speed);
 	config.prop_name = name;
 
-	for_each_possible_cpu(cpu) {
+	for_each_present_cpu(cpu) {
 		struct device *cpu_dev = get_cpu_device(cpu);
 
 		if (!cpu_dev) {
@@ -288,7 +288,7 @@  static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
 	pr_err("Failed to register platform device\n");
 
 free_opp:
-	for_each_possible_cpu(cpu)
+	for_each_present_cpu(cpu)
 		dev_pm_opp_clear_config(opp_tokens[cpu]);
 	kfree(opp_tokens);
 
@@ -302,7 +302,7 @@  static void sun50i_cpufreq_nvmem_remove(struct platform_device *pdev)
 
 	platform_device_unregister(cpufreq_dt_pdev);
 
-	for_each_possible_cpu(cpu)
+	for_each_present_cpu(cpu)
 		dev_pm_opp_clear_config(opp_tokens[cpu]);
 
 	kfree(opp_tokens);