Skip to content

Commit 6ba21d0

Browse files
committed
Merge branch 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Merge ARM cpufreq fixes for 6.7-rc4 from Viresh Kumar. These fix issues related to power domains in the qcom cpufreq driver and an OPP-related issue in the imx6q cpufreq driver. * 'cpufreq/arm/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: pmdomain: qcom: rpmpd: Set GENPD_FLAG_ACTIVE_WAKEUP cpufreq: qcom-nvmem: Preserve PM domain votes in system suspend cpufreq: qcom-nvmem: Enable virtual power domain devices cpufreq: imx6q: Don't disable 792 Mhz OPP unnecessarily
2 parents 2cc14f5 + 8f96e29 commit 6ba21d0

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

drivers/cpufreq/imx6q-cpufreq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ static int imx6ul_opp_check_speed_grading(struct device *dev)
327327
imx6x_disable_freq_in_opp(dev, 696000000);
328328

329329
if (of_machine_is_compatible("fsl,imx6ull")) {
330-
if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ)
330+
if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ)
331331
imx6x_disable_freq_in_opp(dev, 792000000);
332332

333333
if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)

drivers/cpufreq/qcom-cpufreq-nvmem.c

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
#include <linux/nvmem-consumer.h>
2424
#include <linux/of.h>
2525
#include <linux/platform_device.h>
26+
#include <linux/pm.h>
2627
#include <linux/pm_domain.h>
2728
#include <linux/pm_opp.h>
29+
#include <linux/pm_runtime.h>
2830
#include <linux/slab.h>
2931
#include <linux/soc/qcom/smem.h>
3032

@@ -55,6 +57,7 @@ struct qcom_cpufreq_match_data {
5557

5658
struct qcom_cpufreq_drv_cpu {
5759
int opp_token;
60+
struct device **virt_devs;
5861
};
5962

6063
struct qcom_cpufreq_drv {
@@ -424,6 +427,30 @@ static const struct qcom_cpufreq_match_data match_data_ipq8074 = {
424427
.get_version = qcom_cpufreq_ipq8074_name_version,
425428
};
426429

430+
static void qcom_cpufreq_suspend_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu)
431+
{
432+
const char * const *name = drv->data->genpd_names;
433+
int i;
434+
435+
if (!drv->cpus[cpu].virt_devs)
436+
return;
437+
438+
for (i = 0; *name; i++, name++)
439+
device_set_awake_path(drv->cpus[cpu].virt_devs[i]);
440+
}
441+
442+
static void qcom_cpufreq_put_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu)
443+
{
444+
const char * const *name = drv->data->genpd_names;
445+
int i;
446+
447+
if (!drv->cpus[cpu].virt_devs)
448+
return;
449+
450+
for (i = 0; *name; i++, name++)
451+
pm_runtime_put(drv->cpus[cpu].virt_devs[i]);
452+
}
453+
427454
static int qcom_cpufreq_probe(struct platform_device *pdev)
428455
{
429456
struct qcom_cpufreq_drv *drv;
@@ -478,6 +505,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
478505
of_node_put(np);
479506

480507
for_each_possible_cpu(cpu) {
508+
struct device **virt_devs = NULL;
481509
struct dev_pm_opp_config config = {
482510
.supported_hw = NULL,
483511
};
@@ -498,7 +526,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
498526

499527
if (drv->data->genpd_names) {
500528
config.genpd_names = drv->data->genpd_names;
501-
config.virt_devs = NULL;
529+
config.virt_devs = &virt_devs;
502530
}
503531

504532
if (config.supported_hw || config.genpd_names) {
@@ -509,6 +537,27 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
509537
goto free_opp;
510538
}
511539
}
540+
541+
if (virt_devs) {
542+
const char * const *name = config.genpd_names;
543+
int i, j;
544+
545+
for (i = 0; *name; i++, name++) {
546+
ret = pm_runtime_resume_and_get(virt_devs[i]);
547+
if (ret) {
548+
dev_err(cpu_dev, "failed to resume %s: %d\n",
549+
*name, ret);
550+
551+
/* Rollback previous PM runtime calls */
552+
name = config.genpd_names;
553+
for (j = 0; *name && j < i; j++, name++)
554+
pm_runtime_put(virt_devs[j]);
555+
556+
goto free_opp;
557+
}
558+
}
559+
drv->cpus[cpu].virt_devs = virt_devs;
560+
}
512561
}
513562

514563
cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
@@ -522,8 +571,10 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
522571
dev_err(cpu_dev, "Failed to register platform device\n");
523572

524573
free_opp:
525-
for_each_possible_cpu(cpu)
574+
for_each_possible_cpu(cpu) {
575+
qcom_cpufreq_put_virt_devs(drv, cpu);
526576
dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
577+
}
527578
return ret;
528579
}
529580

@@ -534,15 +585,31 @@ static void qcom_cpufreq_remove(struct platform_device *pdev)
534585

535586
platform_device_unregister(cpufreq_dt_pdev);
536587

537-
for_each_possible_cpu(cpu)
588+
for_each_possible_cpu(cpu) {
589+
qcom_cpufreq_put_virt_devs(drv, cpu);
538590
dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
591+
}
539592
}
540593

594+
static int qcom_cpufreq_suspend(struct device *dev)
595+
{
596+
struct qcom_cpufreq_drv *drv = dev_get_drvdata(dev);
597+
unsigned int cpu;
598+
599+
for_each_possible_cpu(cpu)
600+
qcom_cpufreq_suspend_virt_devs(drv, cpu);
601+
602+
return 0;
603+
}
604+
605+
static DEFINE_SIMPLE_DEV_PM_OPS(qcom_cpufreq_pm_ops, qcom_cpufreq_suspend, NULL);
606+
541607
static struct platform_driver qcom_cpufreq_driver = {
542608
.probe = qcom_cpufreq_probe,
543609
.remove_new = qcom_cpufreq_remove,
544610
.driver = {
545611
.name = "qcom-cpufreq-nvmem",
612+
.pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops),
546613
},
547614
};
548615

drivers/pmdomain/qcom/rpmpd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ static int rpmpd_probe(struct platform_device *pdev)
10441044
rpmpds[i]->pd.power_off = rpmpd_power_off;
10451045
rpmpds[i]->pd.power_on = rpmpd_power_on;
10461046
rpmpds[i]->pd.set_performance_state = rpmpd_set_performance;
1047+
rpmpds[i]->pd.flags = GENPD_FLAG_ACTIVE_WAKEUP;
10471048
pm_genpd_init(&rpmpds[i]->pd, NULL, true);
10481049

10491050
data->domains[i] = &rpmpds[i]->pd;

0 commit comments

Comments
 (0)