drivers/thermal/devfreq_cooling.c
Source file repositories/reference/linux-study-clean/drivers/thermal/devfreq_cooling.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/thermal/devfreq_cooling.c- Extension
.c- Size
- 15024 bytes
- Lines
- 577
- Domain
- Driver Families
- Bucket
- drivers/thermal
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/devfreq.hlinux/devfreq_cooling.hlinux/energy_model.hlinux/export.hlinux/slab.hlinux/pm_opp.hlinux/pm_qos.hlinux/thermal.hlinux/units.hthermal_trace.h
Detected Declarations
struct devfreq_cooling_devicefunction devfreq_cooling_get_max_statefunction devfreq_cooling_get_cur_statefunction devfreq_cooling_set_cur_statefunction get_perf_idxfunction get_voltagefunction _normalize_loadfunction devfreq_cooling_get_requested_powerfunction devfreq_cooling_state2powerfunction devfreq_cooling_power2statefunction devfreq_cooling_gen_tablesfunction of_devfreq_cooling_register_powerfunction of_devfreq_cooling_registerfunction devfreq_cooling_registerfunction devfreq_cooling_em_registerfunction devfreq_cooling_unregisterexport of_devfreq_cooling_register_powerexport of_devfreq_cooling_registerexport devfreq_cooling_registerexport devfreq_cooling_em_registerexport devfreq_cooling_unregister
Annotated Snippet
struct devfreq_cooling_device {
struct thermal_cooling_device *cdev;
struct thermal_cooling_device_ops cooling_ops;
struct devfreq *devfreq;
unsigned long cooling_state;
u32 *freq_table;
size_t max_state;
struct devfreq_cooling_power *power_ops;
u32 res_util;
int capped_state;
struct dev_pm_qos_request req_max_freq;
struct em_perf_domain *em_pd;
};
static int devfreq_cooling_get_max_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct devfreq_cooling_device *dfc = cdev->devdata;
*state = dfc->max_state;
return 0;
}
static int devfreq_cooling_get_cur_state(struct thermal_cooling_device *cdev,
unsigned long *state)
{
struct devfreq_cooling_device *dfc = cdev->devdata;
*state = dfc->cooling_state;
return 0;
}
static int devfreq_cooling_set_cur_state(struct thermal_cooling_device *cdev,
unsigned long state)
{
struct devfreq_cooling_device *dfc = cdev->devdata;
struct devfreq *df = dfc->devfreq;
struct device *dev = df->dev.parent;
struct em_perf_state *table;
unsigned long freq;
int perf_idx;
if (state == dfc->cooling_state)
return 0;
dev_dbg(dev, "Setting cooling state %lu\n", state);
if (state > dfc->max_state)
return -EINVAL;
if (dfc->em_pd) {
perf_idx = dfc->max_state - state;
rcu_read_lock();
table = em_perf_state_from_pd(dfc->em_pd);
freq = table[perf_idx].frequency * 1000;
rcu_read_unlock();
} else {
freq = dfc->freq_table[state];
}
dev_pm_qos_update_request(&dfc->req_max_freq,
DIV_ROUND_UP(freq, HZ_PER_KHZ));
dfc->cooling_state = state;
return 0;
}
/**
* get_perf_idx() - get the performance index corresponding to a frequency
* @em_pd: Pointer to device's Energy Model
* @freq: frequency in kHz
*
* Return: the performance index associated with the @freq, or
* -EINVAL if it wasn't found.
*/
static int get_perf_idx(struct em_perf_domain *em_pd, unsigned long freq)
{
struct em_perf_state *table;
int i, idx = -EINVAL;
rcu_read_lock();
table = em_perf_state_from_pd(em_pd);
for (i = 0; i < em_pd->nr_perf_states; i++) {
if (table[i].frequency != freq)
continue;
Annotation
- Immediate include surface: `linux/devfreq.h`, `linux/devfreq_cooling.h`, `linux/energy_model.h`, `linux/export.h`, `linux/slab.h`, `linux/pm_opp.h`, `linux/pm_qos.h`, `linux/thermal.h`.
- Detected declarations: `struct devfreq_cooling_device`, `function devfreq_cooling_get_max_state`, `function devfreq_cooling_get_cur_state`, `function devfreq_cooling_set_cur_state`, `function get_perf_idx`, `function get_voltage`, `function _normalize_load`, `function devfreq_cooling_get_requested_power`, `function devfreq_cooling_state2power`, `function devfreq_cooling_power2state`.
- Atlas domain: Driver Families / drivers/thermal.
- Implementation status: integration 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.