drivers/cpufreq/powernow-k8.c
Source file repositories/reference/linux-study-clean/drivers/cpufreq/powernow-k8.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/cpufreq/powernow-k8.c- Extension
.c- Size
- 31155 bytes
- Lines
- 1220
- Domain
- Driver Families
- Bucket
- drivers/cpufreq
- 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/kernel.hlinux/smp.hlinux/module.hlinux/init.hlinux/cpufreq.hlinux/slab.hlinux/string.hlinux/cpumask.hlinux/io.hlinux/delay.hasm/msr.hasm/cpu_device_id.hasm/cpuid/api.hlinux/acpi.hlinux/mutex.hacpi/processor.hpowernow-k8.h
Detected Declarations
struct powernowk8_target_argstruct init_on_cpufunction find_freq_from_fidfunction find_khz_freq_from_fidfunction convert_fid_to_vco_fidfunction pending_bit_stuckfunction query_current_values_with_pending_waitfunction count_off_irtfunction count_off_vstfunction fidvid_msr_initfunction write_new_fidfunction write_new_vidfunction decrease_vid_code_by_stepfunction transition_fid_vidfunction core_voltage_pre_transitionfunction core_frequency_transitionfunction core_voltage_post_transitionfunction check_supported_cpufunction check_pst_tablefunction invalidate_entryfunction print_basicsfunction fill_powernow_tablefunction find_psb_tablefunction powernow_k8_acpi_pst_valuesfunction powernow_k8_cpu_init_acpifunction fill_powernow_table_fidvidfunction powernow_k8_cpu_exit_acpifunction get_transition_latencyfunction transition_frequency_fidvidfunction powernowk8_target_fnfunction powernowk8_targetfunction powernowk8_cpu_init_on_cpufunction powernowk8_cpu_initfunction powernowk8_cpu_exitfunction query_values_on_cpufunction powernowk8_getfunction __request_acpi_cpufreqfunction powernowk8_initfunction powernowk8_exit
Annotated Snippet
struct powernowk8_target_arg {
struct cpufreq_policy *pol;
unsigned newstate;
};
static long powernowk8_target_fn(void *arg)
{
struct powernowk8_target_arg *pta = arg;
struct cpufreq_policy *pol = pta->pol;
unsigned newstate = pta->newstate;
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
u32 checkfid;
u32 checkvid;
int ret;
if (!data)
return -EINVAL;
checkfid = data->currfid;
checkvid = data->currvid;
if (pending_bit_stuck()) {
pr_err("failing targ, change pending bit set\n");
return -EIO;
}
pr_debug("targ: cpu %d, %d kHz, min %d, max %d\n",
pol->cpu, data->powernow_table[newstate].frequency, pol->min,
pol->max);
if (query_current_values_with_pending_wait(data))
return -EIO;
pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
if ((checkvid != data->currvid) ||
(checkfid != data->currfid)) {
pr_info("error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
checkfid, data->currfid,
checkvid, data->currvid);
}
mutex_lock(&fidvid_mutex);
powernow_k8_acpi_pst_values(data, newstate);
ret = transition_frequency_fidvid(data, newstate, pol);
if (ret) {
pr_err("transition frequency failed\n");
mutex_unlock(&fidvid_mutex);
return 1;
}
mutex_unlock(&fidvid_mutex);
pol->cur = find_khz_freq_from_fid(data->currfid);
return 0;
}
/* Driver entry point to switch to the target frequency */
static int powernowk8_target(struct cpufreq_policy *pol, unsigned index)
{
struct powernowk8_target_arg pta = { .pol = pol, .newstate = index };
return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
}
struct init_on_cpu {
struct powernow_k8_data *data;
int rc;
};
static void powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
{
struct init_on_cpu *init_on_cpu = _init_on_cpu;
if (pending_bit_stuck()) {
pr_err("failing init, change pending bit set\n");
init_on_cpu->rc = -ENODEV;
return;
}
if (query_current_values_with_pending_wait(init_on_cpu->data)) {
init_on_cpu->rc = -ENODEV;
return;
}
fidvid_msr_init();
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/smp.h`, `linux/module.h`, `linux/init.h`, `linux/cpufreq.h`, `linux/slab.h`, `linux/string.h`, `linux/cpumask.h`.
- Detected declarations: `struct powernowk8_target_arg`, `struct init_on_cpu`, `function find_freq_from_fid`, `function find_khz_freq_from_fid`, `function convert_fid_to_vco_fid`, `function pending_bit_stuck`, `function query_current_values_with_pending_wait`, `function count_off_irt`, `function count_off_vst`, `function fidvid_msr_init`.
- Atlas domain: Driver Families / drivers/cpufreq.
- 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.