Skip to content

Commit 6c9bb86

Browse files
Mike Tiptonvireshk
authored andcommitted
cpufreq: scmi: Skip SCMI devices that aren't used by the CPUs
Currently, all SCMI devices with performance domains attempt to register a cpufreq driver, even if their performance domains aren't used to control the CPUs. The cpufreq framework only supports registering a single driver, so only the first device will succeed. And if that device isn't used for the CPUs, then cpufreq will scale the wrong domains. To avoid this, return early from scmi_cpufreq_probe() if the probing SCMI device isn't referenced by the CPU device phandles. This keeps the existing assumption that all CPUs are controlled by a single SCMI device. Signed-off-by: Mike Tipton <quic_mdtipton@quicinc.com> Reviewed-by: Peng Fan <peng.fan@nxp.com> Reviewed-by: Cristian Marussi <cristian.marussi@arm.com> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Tested-by: Cristian Marussi <cristian.marussi@arm.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
1 parent c410aab commit 6c9bb86

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

drivers/cpufreq/scmi-cpufreq.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,40 @@ static struct cpufreq_driver scmi_cpufreq_driver = {
393393
.set_boost = cpufreq_boost_set_sw,
394394
};
395395

396+
static bool scmi_dev_used_by_cpus(struct device *scmi_dev)
397+
{
398+
struct device_node *scmi_np = dev_of_node(scmi_dev);
399+
struct device_node *cpu_np, *np;
400+
struct device *cpu_dev;
401+
int cpu, idx;
402+
403+
if (!scmi_np)
404+
return false;
405+
406+
for_each_possible_cpu(cpu) {
407+
cpu_dev = get_cpu_device(cpu);
408+
if (!cpu_dev)
409+
continue;
410+
411+
cpu_np = dev_of_node(cpu_dev);
412+
413+
np = of_parse_phandle(cpu_np, "clocks", 0);
414+
of_node_put(np);
415+
416+
if (np == scmi_np)
417+
return true;
418+
419+
idx = of_property_match_string(cpu_np, "power-domain-names", "perf");
420+
np = of_parse_phandle(cpu_np, "power-domains", idx);
421+
of_node_put(np);
422+
423+
if (np == scmi_np)
424+
return true;
425+
}
426+
427+
return false;
428+
}
429+
396430
static int scmi_cpufreq_probe(struct scmi_device *sdev)
397431
{
398432
int ret;
@@ -401,7 +435,7 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev)
401435

402436
handle = sdev->handle;
403437

404-
if (!handle)
438+
if (!handle || !scmi_dev_used_by_cpus(dev))
405439
return -ENODEV;
406440

407441
scmi_cpufreq_driver.driver_data = sdev;

0 commit comments

Comments
 (0)