drivers/cpufreq/scmi-cpufreq.c
Source file repositories/reference/linux-study-clean/drivers/cpufreq/scmi-cpufreq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/cpufreq/scmi-cpufreq.c- Extension
.c- Size
- 12904 bytes
- Lines
- 498
- Domain
- Driver Families
- Bucket
- drivers/cpufreq
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk-provider.hlinux/cpu.hlinux/cpufreq.hlinux/cpumask.hlinux/energy_model.hlinux/export.hlinux/module.hlinux/of.hlinux/pm_opp.hlinux/pm_qos.hlinux/slab.hlinux/scmi_protocol.hlinux/types.hlinux/units.h
Detected Declarations
struct scmi_datafunction scmi_cpufreq_get_ratefunction scmi_cpufreq_set_targetfunction scmi_cpufreq_fast_switchfunction scmi_cpu_domain_idfunction scmi_get_sharing_cpusfunction for_each_present_cpufunction scmi_get_cpu_powerfunction scmi_get_rate_limitfunction scmi_limit_notify_cbfunction scmi_cpufreq_initfunction scmi_cpufreq_exitfunction scmi_cpufreq_register_emfunction scmi_dev_used_by_cpusfunction for_each_possible_cpufunction scmi_cpufreq_probefunction scmi_cpufreq_remove
Annotated Snippet
struct scmi_data {
int domain_id;
int nr_opp;
struct device *cpu_dev;
cpumask_var_t opp_shared_cpus;
struct notifier_block limit_notify_nb;
struct freq_qos_request limits_freq_req;
};
static struct scmi_protocol_handle *ph;
static const struct scmi_perf_proto_ops *perf_ops;
static struct cpufreq_driver scmi_cpufreq_driver;
static unsigned int scmi_cpufreq_get_rate(unsigned int cpu)
{
struct cpufreq_policy *policy;
struct scmi_data *priv;
unsigned long rate;
int ret;
policy = cpufreq_cpu_get_raw(cpu);
if (unlikely(!policy))
return 0;
priv = policy->driver_data;
ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false);
if (ret)
return 0;
return rate / 1000;
}
/*
* perf_ops->freq_set is not a synchronous, the actual OPP change will
* happen asynchronously and can get notified if the events are
* subscribed for by the SCMI firmware
*/
static int
scmi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
{
struct scmi_data *priv = policy->driver_data;
u64 freq = policy->freq_table[index].frequency;
return perf_ops->freq_set(ph, priv->domain_id, freq * 1000, false);
}
static unsigned int scmi_cpufreq_fast_switch(struct cpufreq_policy *policy,
unsigned int target_freq)
{
struct scmi_data *priv = policy->driver_data;
unsigned long freq = target_freq;
if (!perf_ops->freq_set(ph, priv->domain_id, freq * 1000, true))
return target_freq;
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;
}
of_node_put(domain_id.np);
return domain_id.args[0];
}
static int
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) {
Annotation
- Immediate include surface: `linux/clk-provider.h`, `linux/cpu.h`, `linux/cpufreq.h`, `linux/cpumask.h`, `linux/energy_model.h`, `linux/export.h`, `linux/module.h`, `linux/of.h`.
- Detected declarations: `struct scmi_data`, `function scmi_cpufreq_get_rate`, `function scmi_cpufreq_set_target`, `function scmi_cpufreq_fast_switch`, `function scmi_cpu_domain_id`, `function scmi_get_sharing_cpus`, `function for_each_present_cpu`, `function scmi_get_cpu_power`, `function scmi_get_rate_limit`, `function scmi_limit_notify_cb`.
- Atlas domain: Driver Families / drivers/cpufreq.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.