summaryrefslogtreecommitdiff
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-11-01 14:46:51 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2023-11-01 14:46:51 -1000
commit385903a7ec75bb400f4bf0f07d8d5ad61390270d (patch)
treef6510ea86effc389da264871b6ecb6af6c77d679 /drivers/cpufreq
parentc035f0268b87fc21f517f638b3bad26c81babc85 (diff)
parentdfae947836d867e127e2b64f981ebb299c28f0dc (diff)
Merge tag 'soc-drivers-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull SoC driver updates from Arnd Bergmann: "The highlights for the driver support this time are - Qualcomm platforms gain support for the Qualcomm Secure Execution Environment firmware interface to access EFI variables on certain devices, and new features for multiple platform and firmware drivers. - Arm FF-A firmware support gains support for v1.1 specification features, in particular notification and memory transaction descriptor changes. - SCMI firmware support now support v3.2 features for clock and DVFS configuration and a new transport for Qualcomm platforms. - Minor cleanups and bugfixes are added to pretty much all the active platforms: qualcomm, broadcom, dove, ti-k3, rockchip, sifive, amlogic, atmel, tegra, aspeed, vexpress, mediatek, samsung and more. In particular, this contains portions of the treewide conversion to use __counted_by annotations and the device_get_match_data helper" * tag 'soc-drivers-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (156 commits) soc: qcom: pmic_glink_altmode: Print return value on error firmware: qcom: scm: remove unneeded 'extern' specifiers firmware: qcom: scm: add a missing forward declaration for struct device firmware: qcom: move Qualcomm code into its own directory soc: samsung: exynos-chipid: Convert to platform remove callback returning void soc: qcom: apr: Add __counted_by for struct apr_rx_buf and use struct_size() soc: qcom: pmic_glink: fix connector type to be DisplayPort soc: ti: k3-socinfo: Avoid overriding return value soc: ti: k3-socinfo: Fix typo in bitfield documentation soc: ti: knav_qmss_queue: Use device_get_match_data() firmware: ti_sci: Use device_get_match_data() firmware: qcom: qseecom: add missing include guards soc/pxa: ssp: Convert to platform remove callback returning void soc/mediatek: mtk-mmsys: Convert to platform remove callback returning void soc/mediatek: mtk-devapc: Convert to platform remove callback returning void soc/loongson: loongson2_guts: Convert to platform remove callback returning void soc/litex: litex_soc_ctrl: Convert to platform remove callback returning void soc/ixp4xx: ixp4xx-qmgr: Convert to platform remove callback returning void soc/ixp4xx: ixp4xx-npe: Convert to platform remove callback returning void soc/hisilicon: kunpeng_hccs: Convert to platform remove callback returning void ...
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/scmi-cpufreq.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index f34e6382a4c5..c8a7ccc42c16 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -70,16 +70,36 @@ static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
return 0;
}
+static int scmi_cpu_domain_id(struct device *cpu_dev)
+{
+ struct device_node *np = cpu_dev->of_node;
+ struct of_phandle_args domain_id;
+ int index;
+
+ if (of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
+ &domain_id)) {
+ /* Find the corresponding index for power-domain "perf". */
+ index = of_property_match_string(np, "power-domain-names",
+ "perf");
+ if (index < 0)
+ return -EINVAL;
+
+ if (of_parse_phandle_with_args(np, "power-domains",
+ "#power-domain-cells", index,
+ &domain_id))
+ return -EINVAL;
+ }
+
+ return domain_id.args[0];
+}
+
static int
-scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
+scmi_get_sharing_cpus(struct device *cpu_dev, int domain,
+ struct cpumask *cpumask)
{
- int cpu, domain, tdomain;
+ int cpu, tdomain;
struct device *tcpu_dev;
- domain = perf_ops->device_domain_id(cpu_dev);
- if (domain < 0)
- return domain;
-
for_each_possible_cpu(cpu) {
if (cpu == cpu_dev->id)
continue;
@@ -88,7 +108,7 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
if (!tcpu_dev)
continue;
- tdomain = perf_ops->device_domain_id(tcpu_dev);
+ tdomain = scmi_cpu_domain_id(tcpu_dev);
if (tdomain == domain)
cpumask_set_cpu(cpu, cpumask);
}
@@ -104,7 +124,7 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
unsigned long Hz;
int ret, domain;
- domain = perf_ops->device_domain_id(cpu_dev);
+ domain = scmi_cpu_domain_id(cpu_dev);
if (domain < 0)
return domain;
@@ -126,7 +146,7 @@ scmi_get_cpu_power(struct device *cpu_dev, unsigned long *power,
static int scmi_cpufreq_init(struct cpufreq_policy *policy)
{
- int ret, nr_opp;
+ int ret, nr_opp, domain;
unsigned int latency;
struct device *cpu_dev;
struct scmi_data *priv;
@@ -138,6 +158,10 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
return -ENODEV;
}
+ domain = scmi_cpu_domain_id(cpu_dev);
+ if (domain < 0)
+ return domain;
+
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -148,7 +172,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
}
/* Obtain CPUs that share SCMI performance controls */
- ret = scmi_get_sharing_cpus(cpu_dev, policy->cpus);
+ ret = scmi_get_sharing_cpus(cpu_dev, domain, policy->cpus);
if (ret) {
dev_warn(cpu_dev, "failed to get sharing cpumask\n");
goto out_free_cpumask;
@@ -176,7 +200,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
*/
nr_opp = dev_pm_opp_get_opp_count(cpu_dev);
if (nr_opp <= 0) {
- ret = perf_ops->device_opps_add(ph, cpu_dev);
+ ret = perf_ops->device_opps_add(ph, cpu_dev, domain);
if (ret) {
dev_warn(cpu_dev, "failed to add opps to the device\n");
goto out_free_cpumask;
@@ -209,7 +233,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
}
priv->cpu_dev = cpu_dev;
- priv->domain_id = perf_ops->device_domain_id(cpu_dev);
+ priv->domain_id = domain;
policy->driver_data = priv;
policy->freq_table = freq_table;
@@ -217,14 +241,14 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
/* SCMI allows DVFS request for any domain from any CPU */
policy->dvfs_possible_from_any_cpu = true;
- latency = perf_ops->transition_latency_get(ph, cpu_dev);
+ latency = perf_ops->transition_latency_get(ph, domain);
if (!latency)
latency = CPUFREQ_ETERNAL;
policy->cpuinfo.transition_latency = latency;
policy->fast_switch_possible =
- perf_ops->fast_switch_possible(ph, cpu_dev);
+ perf_ops->fast_switch_possible(ph, domain);
return 0;