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];
}
staticint
scmi_get_sharing_cpus(struct device *cpu_dev, int domain, struct cpumask *cpumask)
{ int cpu, tdomain; struct device *tcpu_dev;
for_each_present_cpu(cpu) { if (cpu == cpu_dev->id) continue;
tcpu_dev = get_cpu_device(cpu); if (!tcpu_dev) continue;
tdomain = scmi_cpu_domain_id(tcpu_dev); if (tdomain == domain)
cpumask_set_cpu(cpu, cpumask);
}
/* *ApreviousCPUmayhavemarkedOPPsassharedforafewCPUs,basedon *whatOPPcoreprovided.IfthecurrentCPUispartofthosefew,then *thereisnoneedtoaddOPPsagain.
*/
nr_opp = dev_pm_opp_get_opp_count(cpu_dev); if (nr_opp <= 0) {
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;
}
nr_opp = dev_pm_opp_get_opp_count(cpu_dev); if (nr_opp <= 0) {
dev_err(cpu_dev, "%s: No OPPs for this device: %d\n",
__func__, nr_opp);
ret = -ENODEV; goto out_free_opp;
}
ret = dev_pm_opp_set_sharing_cpus(cpu_dev, priv->opp_shared_cpus); if (ret) {
dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
__func__, ret);
goto out_free_opp;
}
priv->nr_opp = nr_opp;
}
ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); if (ret) {
dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); goto out_free_opp;
}
ret = freq_qos_add_request(&policy->constraints, &priv->limits_freq_req, FREQ_QOS_MAX,
FREQ_QOS_MAX_DEFAULT_VALUE); if (ret < 0) {
dev_err(cpu_dev, "failed to add qos limits request: %d\n", ret); goto out_free_table;
}
priv->limit_notify_nb.notifier_call = scmi_limit_notify_cb;
ret = sdev->handle->notify_ops->event_notifier_register(sdev->handle, SCMI_PROTOCOL_PERF,
SCMI_EVENT_PERFORMANCE_LIMITS_CHANGED,
&priv->domain_id,
&priv->limit_notify_nb); if (ret)
dev_warn(&sdev->dev, "failed to register for limits change notifier for domain %d\n",
priv->domain_id);
if (!handle || !scmi_dev_used_by_cpus(dev)) return -ENODEV;
scmi_cpufreq_driver.driver_data = sdev;
perf_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PERF, &ph); if (IS_ERR(perf_ops)) return PTR_ERR(perf_ops);
#ifdef CONFIG_COMMON_CLK /* dummy clock provider as needed by OPP if clocks property is used */ if (of_property_present(dev->of_node, "#clock-cells")) {
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); if (ret) return dev_err_probe(dev, ret, "%s: registering clock provider failed\n", __func__);
} #endif
ret = cpufreq_register_driver(&scmi_cpufreq_driver); if (ret) {
dev_err(dev, "%s: registering cpufreq failed, err: %d\n",
__func__, ret);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.