drivers/soc/samsung/exynos-asv.c
Source file repositories/reference/linux-study-clean/drivers/soc/samsung/exynos-asv.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/soc/samsung/exynos-asv.c- Extension
.c- Size
- 3808 bytes
- Lines
- 170
- Domain
- Driver Families
- Bucket
- drivers/soc
- 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/array_size.hlinux/cpu.hlinux/device.hlinux/energy_model.hlinux/errno.hlinux/of.hlinux/pm_opp.hlinux/regmap.hlinux/soc/samsung/exynos-chipid.hexynos-asv.hexynos5422-asv.h
Detected Declarations
function Copyrightfunction exynos_asv_update_oppsfunction for_each_possible_cpufunction exynos_asv_init
Annotated Snippet
if (IS_ERR(opp)) {
dev_info(asv->dev, "cpu%d opp%d, freq: %u missing\n",
cpu->id, i, opp_freq);
continue;
}
volt = dev_pm_opp_get_voltage(opp);
new_volt = asv->opp_get_voltage(subsys, i, volt);
dev_pm_opp_put(opp);
if (new_volt == volt)
continue;
ret = dev_pm_opp_adjust_voltage(cpu, opp_freq * MHZ,
new_volt, new_volt, new_volt);
if (ret < 0)
dev_err(asv->dev,
"Failed to adjust OPP %u Hz/%u uV for cpu%d\n",
opp_freq, new_volt, cpu->id);
else
dev_dbg(asv->dev,
"Adjusted OPP %u Hz/%u -> %u uV, cpu%d\n",
opp_freq, volt, new_volt, cpu->id);
}
return 0;
}
static int exynos_asv_update_opps(struct exynos_asv *asv)
{
struct opp_table *last_opp_table = NULL;
struct device *cpu;
int ret, cpuid;
for_each_possible_cpu(cpuid) {
struct opp_table *opp_table;
cpu = get_cpu_device(cpuid);
if (!cpu)
continue;
opp_table = dev_pm_opp_get_opp_table(cpu);
if (IS_ERR(opp_table))
continue;
if (!last_opp_table || opp_table != last_opp_table) {
last_opp_table = opp_table;
ret = exynos_asv_update_cpu_opps(asv, cpu);
if (!ret) {
/*
* Update EM power values since OPP
* voltage values may have changed.
*/
em_dev_update_chip_binning(cpu);
} else {
dev_err(asv->dev, "Couldn't udate OPPs for cpu%d\n",
cpuid);
}
}
dev_pm_opp_put_opp_table(opp_table);
}
return 0;
}
int exynos_asv_init(struct device *dev, struct regmap *regmap)
{
int (*probe_func)(struct exynos_asv *asv);
struct exynos_asv *asv;
struct device *cpu_dev;
u32 product_id = 0;
int ret, i;
asv = devm_kzalloc(dev, sizeof(*asv), GFP_KERNEL);
if (!asv)
return -ENOMEM;
asv->chipid_regmap = regmap;
asv->dev = dev;
ret = regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID,
&product_id);
if (ret < 0) {
dev_err(dev, "Cannot read revision from ChipID: %d\n", ret);
return -ENODEV;
}
switch (product_id & EXYNOS_MASK) {
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/cpu.h`, `linux/device.h`, `linux/energy_model.h`, `linux/errno.h`, `linux/of.h`, `linux/pm_opp.h`, `linux/regmap.h`.
- Detected declarations: `function Copyright`, `function exynos_asv_update_opps`, `function for_each_possible_cpu`, `function exynos_asv_init`.
- Atlas domain: Driver Families / drivers/soc.
- 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.