drivers/thermal/cpufreq_cooling.c

Source file repositories/reference/linux-study-clean/drivers/thermal/cpufreq_cooling.c

File Facts

System
Linux kernel
Corpus path
drivers/thermal/cpufreq_cooling.c
Extension
.c
Size
19605 bytes
Lines
696
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct time_in_idle {
	u64 time;
	u64 timestamp;
};

/**
 * struct cpufreq_cooling_device - data for cooling device with cpufreq
 * @last_load: load measured by the latest call to cpufreq_get_requested_power()
 * @cpufreq_state: integer value representing the current state of cpufreq
 *	cooling	devices.
 * @max_level: maximum cooling level. One less than total number of valid
 *	cpufreq frequencies.
 * @em: Reference on the Energy Model of the device
 * @policy: cpufreq policy.
 * @cooling_ops: cpufreq callbacks to thermal cooling device ops
 * @idle_time: idle time stats
 * @qos_req: PM QoS contraint to apply
 *
 * This structure is required for keeping information of each registered
 * cpufreq_cooling_device.
 */
struct cpufreq_cooling_device {
	u32 last_load;
	unsigned int cpufreq_state;
	unsigned int max_level;
	struct em_perf_domain *em;
	struct cpufreq_policy *policy;
	struct thermal_cooling_device_ops cooling_ops;
#ifndef CONFIG_SMP
	struct time_in_idle *idle_time;
#endif
	struct freq_qos_request qos_req;
};

#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
/**
 * get_level: Find the level for a particular frequency
 * @cpufreq_cdev: cpufreq_cdev for which the property is required
 * @freq: Frequency
 *
 * Return: level corresponding to the frequency.
 */
static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_cdev,
			       unsigned int freq)
{
	struct em_perf_state *table;
	int i;

	rcu_read_lock();
	table = em_perf_state_from_pd(cpufreq_cdev->em);
	for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
		if (freq > table[i].frequency)
			break;
	}
	rcu_read_unlock();

	return cpufreq_cdev->max_level - i - 1;
}

static u32 cpu_freq_to_power(struct cpufreq_cooling_device *cpufreq_cdev,
			     u32 freq)
{
	struct em_perf_state *table;
	unsigned long power_mw;
	int i;

	rcu_read_lock();
	table = em_perf_state_from_pd(cpufreq_cdev->em);
	for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
		if (freq > table[i].frequency)
			break;
	}

	power_mw = table[i + 1].power;
	power_mw /= MICROWATT_PER_MILLIWATT;
	rcu_read_unlock();

	return power_mw;
}

static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_cdev,
			     u32 power)
{
	struct em_perf_state *table;
	unsigned long em_power_mw;
	u32 freq;
	int i;

	rcu_read_lock();
	table = em_perf_state_from_pd(cpufreq_cdev->em);

Annotation

Implementation Notes