drivers/devfreq/mtk-cci-devfreq.c
Source file repositories/reference/linux-study-clean/drivers/devfreq/mtk-cci-devfreq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/devfreq/mtk-cci-devfreq.c- Extension
.c- Size
- 11461 bytes
- Lines
- 445
- Domain
- Driver Families
- Bucket
- drivers/devfreq
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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.hlinux/devfreq.hlinux/minmax.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/pm_opp.hlinux/regulator/consumer.h
Detected Declarations
struct mtk_ccifreq_platform_datastruct mtk_ccifreq_drvfunction mtk_ccifreq_set_voltagefunction mtk_ccifreq_targetfunction mtk_ccifreq_opp_notifierfunction mtk_ccifreq_probefunction mtk_ccifreq_remove
Annotated Snippet
struct mtk_ccifreq_platform_data {
int min_volt_shift;
int max_volt_shift;
int proc_max_volt;
int sram_min_volt;
int sram_max_volt;
};
struct mtk_ccifreq_drv {
struct device *dev;
struct devfreq *devfreq;
struct regulator *proc_reg;
struct regulator *sram_reg;
struct clk *cci_clk;
struct clk *inter_clk;
int inter_voltage;
unsigned long pre_freq;
/* Avoid race condition for regulators between notify and policy */
struct mutex reg_lock;
struct notifier_block opp_nb;
const struct mtk_ccifreq_platform_data *soc_data;
int vtrack_max;
};
static int mtk_ccifreq_set_voltage(struct mtk_ccifreq_drv *drv, int new_voltage)
{
const struct mtk_ccifreq_platform_data *soc_data = drv->soc_data;
struct device *dev = drv->dev;
int pre_voltage, pre_vsram, new_vsram, vsram, voltage, ret;
int retry_max = drv->vtrack_max;
if (!drv->sram_reg) {
ret = regulator_set_voltage(drv->proc_reg, new_voltage,
drv->soc_data->proc_max_volt);
return ret;
}
pre_voltage = regulator_get_voltage(drv->proc_reg);
if (pre_voltage < 0) {
dev_err(dev, "invalid vproc value: %d\n", pre_voltage);
return pre_voltage;
}
pre_vsram = regulator_get_voltage(drv->sram_reg);
if (pre_vsram < 0) {
dev_err(dev, "invalid vsram value: %d\n", pre_vsram);
return pre_vsram;
}
new_vsram = clamp(new_voltage + soc_data->min_volt_shift,
soc_data->sram_min_volt, soc_data->sram_max_volt);
do {
if (pre_voltage <= new_voltage) {
vsram = clamp(pre_voltage + soc_data->max_volt_shift,
soc_data->sram_min_volt, new_vsram);
ret = regulator_set_voltage(drv->sram_reg, vsram,
soc_data->sram_max_volt);
if (ret)
return ret;
if (vsram == soc_data->sram_max_volt ||
new_vsram == soc_data->sram_min_volt)
voltage = new_voltage;
else
voltage = vsram - soc_data->min_volt_shift;
ret = regulator_set_voltage(drv->proc_reg, voltage,
soc_data->proc_max_volt);
if (ret) {
regulator_set_voltage(drv->sram_reg, pre_vsram,
soc_data->sram_max_volt);
return ret;
}
} else {
voltage = max(new_voltage,
pre_vsram - soc_data->max_volt_shift);
ret = regulator_set_voltage(drv->proc_reg, voltage,
soc_data->proc_max_volt);
if (ret)
return ret;
if (voltage == new_voltage)
vsram = new_vsram;
else
vsram = max(new_vsram,
voltage + soc_data->min_volt_shift);
ret = regulator_set_voltage(drv->sram_reg, vsram,
soc_data->sram_max_volt);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/devfreq.h`, `linux/minmax.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/pm_opp.h`, `linux/regulator/consumer.h`.
- Detected declarations: `struct mtk_ccifreq_platform_data`, `struct mtk_ccifreq_drv`, `function mtk_ccifreq_set_voltage`, `function mtk_ccifreq_target`, `function mtk_ccifreq_opp_notifier`, `function mtk_ccifreq_probe`, `function mtk_ccifreq_remove`.
- Atlas domain: Driver Families / drivers/devfreq.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.