drivers/cpufreq/mediatek-cpufreq-hw.c
Source file repositories/reference/linux-study-clean/drivers/cpufreq/mediatek-cpufreq-hw.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/cpufreq/mediatek-cpufreq-hw.c- Extension
.c- Size
- 11229 bytes
- Lines
- 443
- 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/bitfield.hlinux/cpufreq.hlinux/energy_model.hlinux/init.hlinux/iopoll.hlinux/kernel.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hlinux/regulator/consumer.hlinux/slab.h
Detected Declarations
struct mtk_cpufreq_privstruct mtk_cpufreq_domainstruct mtk_cpufreq_variantfunction mtk_cpufreq_hw_mt8196_initfunction mtk_cpufreq_get_cpu_powerfunction mtk_cpufreq_hw_fdvfs_switchfunction mtk_cpufreq_hw_target_indexfunction mtk_cpufreq_hw_getfunction mtk_cpufreq_hw_fast_switchfunction mtk_cpu_create_freq_tablefunction mtk_cpu_resources_initfunction mtk_cpufreq_hw_cpu_initfunction mtk_cpufreq_hw_cpu_exitfunction mtk_cpufreq_register_emfunction mtk_cpufreq_hw_driver_probefunction mtk_cpufreq_hw_driver_remove
Annotated Snippet
struct mtk_cpufreq_priv {
struct device *dev;
const struct mtk_cpufreq_variant *variant;
void __iomem *fdvfs;
};
struct mtk_cpufreq_domain {
struct mtk_cpufreq_priv *parent;
struct cpufreq_frequency_table *table;
void __iomem *reg_bases[REG_ARRAY_SIZE];
struct resource *res;
void __iomem *base;
int nr_opp;
};
struct mtk_cpufreq_variant {
int (*init)(struct mtk_cpufreq_priv *priv);
const u16 reg_offsets[REG_ARRAY_SIZE];
const bool is_hybrid_dvfs;
};
static const struct mtk_cpufreq_variant cpufreq_mtk_base_variant = {
.reg_offsets = {
[REG_FREQ_LUT_TABLE] = 0x0,
[REG_FREQ_ENABLE] = 0x84,
[REG_FREQ_PERF_STATE] = 0x88,
[REG_FREQ_HW_STATE] = 0x8c,
[REG_EM_POWER_TBL] = 0x90,
[REG_FREQ_LATENCY] = 0x110,
},
};
static int mtk_cpufreq_hw_mt8196_init(struct mtk_cpufreq_priv *priv)
{
priv->fdvfs = devm_of_iomap(priv->dev, priv->dev->of_node, 0, NULL);
if (IS_ERR(priv->fdvfs))
return dev_err_probe(priv->dev, PTR_ERR(priv->fdvfs),
"failed to get fdvfs iomem\n");
return 0;
}
static const struct mtk_cpufreq_variant cpufreq_mtk_mt8196_variant = {
.init = mtk_cpufreq_hw_mt8196_init,
.reg_offsets = {
[REG_FREQ_LUT_TABLE] = 0x0,
[REG_FREQ_ENABLE] = 0x84,
[REG_FREQ_PERF_STATE] = 0x88,
[REG_FREQ_HW_STATE] = 0x8c,
[REG_EM_POWER_TBL] = 0x90,
[REG_FREQ_LATENCY] = 0x114,
},
.is_hybrid_dvfs = true,
};
static int __maybe_unused
mtk_cpufreq_get_cpu_power(struct device *cpu_dev, unsigned long *uW,
unsigned long *KHz)
{
struct mtk_cpufreq_domain *data;
struct cpufreq_policy *policy;
int i;
policy = cpufreq_cpu_get_raw(cpu_dev->id);
if (!policy)
return -EINVAL;
data = policy->driver_data;
for (i = 0; i < data->nr_opp; i++) {
if (data->table[i].frequency < *KHz)
break;
}
i--;
*KHz = data->table[i].frequency;
/* Provide micro-Watts value to the Energy Model */
*uW = readl_relaxed(data->reg_bases[REG_EM_POWER_TBL] +
i * LUT_ROW_SIZE);
return 0;
}
static void mtk_cpufreq_hw_fdvfs_switch(unsigned int target_freq,
struct cpufreq_policy *policy)
{
struct mtk_cpufreq_domain *data = policy->driver_data;
struct mtk_cpufreq_priv *priv = data->parent;
unsigned int cpu;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/cpufreq.h`, `linux/energy_model.h`, `linux/init.h`, `linux/iopoll.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`.
- Detected declarations: `struct mtk_cpufreq_priv`, `struct mtk_cpufreq_domain`, `struct mtk_cpufreq_variant`, `function mtk_cpufreq_hw_mt8196_init`, `function mtk_cpufreq_get_cpu_power`, `function mtk_cpufreq_hw_fdvfs_switch`, `function mtk_cpufreq_hw_target_index`, `function mtk_cpufreq_hw_get`, `function mtk_cpufreq_hw_fast_switch`, `function mtk_cpu_create_freq_table`.
- 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.