drivers/platform/x86/amd/pmf/core.c
Source file repositories/reference/linux-study-clean/drivers/platform/x86/amd/pmf/core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/platform/x86/amd/pmf/core.c- Extension
.c- Size
- 17932 bytes
- Lines
- 673
- Domain
- Driver Families
- Bucket
- drivers/platform
- 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.
- 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/cleanup.hlinux/debugfs.hlinux/iopoll.hlinux/module.hlinux/mutex.hlinux/pci.hlinux/platform_device.hlinux/power_supply.hlinux/string.hasm/amd/node.hpmf.h
Detected Declarations
function amd_pmf_pwr_src_notify_callfunction current_power_limits_showfunction amd_pmf_dbgfs_unregisterfunction amd_pmf_dbgfs_registerfunction amd_pmf_get_power_sourcefunction amd_pmf_get_metricsfunction amd_pmf_reg_readfunction amd_pmf_reg_writefunction amd_pmf_dump_registersfunction fixp_q88_fromintfunction amd_pmf_send_cmdfunction amd_pmf_set_dram_addrfunction amd_pmf_init_metrics_tablefunction is_npu_metrics_supportedfunction amd_pmf_get_smu_metricsfunction amd_pmf_get_npu_datafunction amd_pmf_reinit_tafunction amd_pmf_restore_handlerfunction amd_pmf_freeze_handlerfunction amd_pmf_suspend_handlerfunction amd_pmf_resume_handlerfunction amd_pmf_init_featuresfunction is_apmf_func_supportedfunction is_apmf_func_supportedfunction amd_pmf_deinit_featuresfunction is_apmf_func_supportedfunction amd_pmf_probefunction amd_pmf_remove
Annotated Snippet
is_apmf_func_supported(pmf, APMF_FUNC_DYN_SLIDER_AC)) {
if ((pmf->amt_enabled || pmf->cnqf_enabled) && is_pprof_balanced(pmf))
return NOTIFY_DONE;
}
if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR))
amd_pmf_set_sps_power_limits(pmf);
if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE))
amd_pmf_power_slider_update_event(pmf);
return NOTIFY_OK;
}
static int current_power_limits_show(struct seq_file *seq, void *unused)
{
struct amd_pmf_dev *dev = seq->private;
struct amd_pmf_static_slider_granular table;
int mode, src = 0;
mode = amd_pmf_get_pprof_modes(dev);
if (mode < 0)
return mode;
src = amd_pmf_get_power_source();
amd_pmf_update_slider(dev, SLIDER_OP_GET, mode, &table);
seq_printf(seq, "spl:%u fppt:%u sppt:%u sppt_apu_only:%u stt_min:%u stt[APU]:%u stt[HS2]: %u\n",
table.prop[src][mode].spl,
table.prop[src][mode].fppt,
table.prop[src][mode].sppt,
table.prop[src][mode].sppt_apu_only,
table.prop[src][mode].stt_min,
table.prop[src][mode].stt_skin_temp[STT_TEMP_APU],
table.prop[src][mode].stt_skin_temp[STT_TEMP_HS2]);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(current_power_limits);
static void amd_pmf_dbgfs_unregister(struct amd_pmf_dev *dev)
{
debugfs_remove_recursive(dev->dbgfs_dir);
}
static void amd_pmf_dbgfs_register(struct amd_pmf_dev *dev)
{
dev->dbgfs_dir = debugfs_create_dir("amd_pmf", NULL);
if (dev->pmf_if_version == PMF_IF_V1)
debugfs_create_file("current_power_limits", 0644, dev->dbgfs_dir, dev,
¤t_power_limits_fops);
}
int amd_pmf_get_power_source(void)
{
if (power_supply_is_system_supplied() > 0)
return POWER_SOURCE_AC;
else
return POWER_SOURCE_DC;
}
static void amd_pmf_get_metrics(struct work_struct *work)
{
struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, work_buffer.work);
ktime_t time_elapsed_ms;
int socket_power;
guard(mutex)(&dev->update_mutex);
/* Transfer table contents */
memset(dev->buf, 0, sizeof(dev->m_table));
amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, SET_CMD, METRICS_TABLE_ID, NULL);
memcpy(&dev->m_table, dev->buf, sizeof(dev->m_table));
time_elapsed_ms = ktime_to_ms(ktime_get()) - dev->start_time;
/* Calculate the avg SoC power consumption */
socket_power = dev->m_table.apu_power + dev->m_table.dgpu_power;
if (dev->amt_enabled) {
/* Apply the Auto Mode transition */
amd_pmf_trans_automode(dev, socket_power, time_elapsed_ms);
}
if (dev->cnqf_enabled) {
/* Apply the CnQF transition */
amd_pmf_trans_cnqf(dev, socket_power, time_elapsed_ms);
}
dev->start_time = ktime_to_ms(ktime_get());
schedule_delayed_work(&dev->work_buffer, msecs_to_jiffies(metrics_table_loop_ms));
}
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/cleanup.h`, `linux/debugfs.h`, `linux/iopoll.h`, `linux/module.h`, `linux/mutex.h`, `linux/pci.h`, `linux/platform_device.h`.
- Detected declarations: `function amd_pmf_pwr_src_notify_call`, `function current_power_limits_show`, `function amd_pmf_dbgfs_unregister`, `function amd_pmf_dbgfs_register`, `function amd_pmf_get_power_source`, `function amd_pmf_get_metrics`, `function amd_pmf_reg_read`, `function amd_pmf_reg_write`, `function amd_pmf_dump_registers`, `function fixp_q88_fromint`.
- Atlas domain: Driver Families / drivers/platform.
- Implementation status: integration 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.