drivers/cpufreq/freq_table.c

Source file repositories/reference/linux-study-clean/drivers/cpufreq/freq_table.c

File Facts

System
Linux kernel
Corpus path
drivers/cpufreq/freq_table.c
Extension
.c
Size
8997 bytes
Lines
371
Domain
Driver Families
Bucket
drivers/cpufreq
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

if ((freq >= policy->min) && (freq <= policy->max)) {
			found = true;
			break;
		}

		if ((prev_smaller < freq) && (freq <= policy->max))
			prev_smaller = freq;
	}

	if (!found) {
		policy->max = prev_smaller;
		cpufreq_verify_within_cpu_limits(policy);
	}

	pr_debug("verification lead to (%u - %u kHz) for cpu %u\n",
				policy->min, policy->max, policy->cpu);

	return 0;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);

/*
 * Generic routine to verify policy & frequency table, requires driver to set
 * policy->freq_table prior to it.
 */
int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy)
{
	if (!policy->freq_table)
		return -ENODEV;

	return cpufreq_frequency_table_verify(policy);
}
EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify);

int cpufreq_table_index_unsorted(struct cpufreq_policy *policy,
				 unsigned int target_freq, unsigned int min,
				 unsigned int max, unsigned int relation)
{
	struct cpufreq_frequency_table optimal = {
		.driver_data = ~0,
		.frequency = 0,
	};
	struct cpufreq_frequency_table suboptimal = {
		.driver_data = ~0,
		.frequency = 0,
	};
	struct cpufreq_frequency_table *pos;
	struct cpufreq_frequency_table *table = policy->freq_table;
	unsigned int freq, diff, i;
	int index;

	pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
					target_freq, relation, policy->cpu);

	switch (relation) {
	case CPUFREQ_RELATION_H:
		suboptimal.frequency = ~0;
		break;
	case CPUFREQ_RELATION_L:
	case CPUFREQ_RELATION_C:
		optimal.frequency = ~0;
		break;
	}

	cpufreq_for_each_valid_entry_idx(pos, table, i) {
		freq = pos->frequency;

		if (freq < min || freq > max)
			continue;
		if (freq == target_freq) {
			optimal.driver_data = i;
			break;
		}
		switch (relation) {
		case CPUFREQ_RELATION_H:
			if (freq < target_freq) {
				if (freq >= optimal.frequency) {
					optimal.frequency = freq;
					optimal.driver_data = i;
				}
			} else {
				if (freq <= suboptimal.frequency) {
					suboptimal.frequency = freq;
					suboptimal.driver_data = i;
				}
			}
			break;
		case CPUFREQ_RELATION_L:
			if (freq > target_freq) {
				if (freq <= optimal.frequency) {

Annotation

Implementation Notes