drivers/platform/x86/amd/pmc/pmc.c
Source file repositories/reference/linux-study-clean/drivers/platform/x86/amd/pmc/pmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/platform/x86/amd/pmc/pmc.c- Extension
.c- Size
- 21509 bytes
- Lines
- 848
- Domain
- Driver Families
- Bucket
- drivers/platform
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/array_size.hlinux/bitfield.hlinux/bits.hlinux/debugfs.hlinux/delay.hlinux/io.hlinux/iopoll.hlinux/limits.hlinux/module.hlinux/pci.hlinux/platform_device.hlinux/rtc.hlinux/serio.hlinux/suspend.hlinux/seq_file.hlinux/uaccess.hasm/amd/node.hpmc.h
Detected Declarations
function amd_pmc_reg_readfunction amd_pmc_reg_writefunction amd_pmc_get_ip_infofunction amd_pmc_setup_smu_loggingfunction get_metrics_tablefunction amd_pmc_validate_deepestfunction amd_pmc_get_smu_versionfunction smu_fw_version_showfunction smu_program_showfunction pmc_attr_is_visiblefunction smu_fw_info_showfunction s0ix_stats_showfunction amd_pmc_idlemask_readfunction amd_pmc_idlemask_showfunction amd_pmc_dbgfs_unregisterfunction amd_pmc_dbgfs_registerfunction amd_pmc_dump_registersfunction amd_pmc_send_cmdfunction amd_pmc_get_os_hintfunction amd_pmc_wa_irq1function amd_pmc_verify_czn_rtcfunction amd_pmc_s2idle_preparefunction amd_pmc_s2idle_checkfunction amd_pmc_dump_datafunction amd_pmc_s2idle_restorefunction amd_pmc_suspend_handlerfunction i8042_pm_suspendfunction amd_pmc_probefunction amd_pmc_remove
Annotated Snippet
if (boot_cpu_data.x86_model == 0x70) {
dev->num_ips = ARRAY_SIZE(soc15_ip_blk_v2);
dev->ips_ptr = soc15_ip_blk_v2;
} else {
dev->num_ips = ARRAY_SIZE(soc15_ip_blk);
dev->ips_ptr = soc15_ip_blk;
}
dev->smu_msg = 0x938;
break;
}
}
static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
{
if (dev->cpu_id == AMD_CPU_ID_PCO) {
dev_warn_once(dev->dev, "SMU debugging info not supported on this platform\n");
return -EINVAL;
}
/* Get Active devices list from SMU */
if (!dev->active_ips)
amd_pmc_send_cmd(dev, 0, &dev->active_ips, SMU_MSG_GET_SUP_CONSTRAINTS, true);
/* Get dram address */
if (!dev->smu_virt_addr) {
u32 phys_addr_low, phys_addr_hi;
u64 smu_phys_addr;
amd_pmc_send_cmd(dev, 0, &phys_addr_low, SMU_MSG_LOG_GETDRAM_ADDR_LO, true);
amd_pmc_send_cmd(dev, 0, &phys_addr_hi, SMU_MSG_LOG_GETDRAM_ADDR_HI, true);
smu_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
dev->smu_virt_addr = devm_ioremap(dev->dev, smu_phys_addr,
sizeof(struct smu_metrics));
if (!dev->smu_virt_addr)
return -ENOMEM;
}
memset_io(dev->smu_virt_addr, 0, sizeof(struct smu_metrics));
/* Start the logging */
amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_RESET, false);
amd_pmc_send_cmd(dev, 0, NULL, SMU_MSG_LOG_START, false);
return 0;
}
static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table)
{
int rc;
if (!pdev->smu_virt_addr) {
rc = amd_pmc_setup_smu_logging(pdev);
if (rc)
return rc;
}
if (pdev->cpu_id == AMD_CPU_ID_PCO)
return -ENODEV;
memcpy_fromio(table, pdev->smu_virt_addr, sizeof(struct smu_metrics));
return 0;
}
static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
{
struct smu_metrics table;
if (get_metrics_table(pdev, &table))
return;
if (!table.s0i3_last_entry_status)
dev_warn(pdev->dev, "Last suspend didn't reach deepest state\n");
pm_report_hw_sleep_time(table.s0i3_last_entry_status ?
table.timein_s0i3_lastcapture : 0);
}
static int amd_pmc_get_smu_version(struct amd_pmc_dev *dev)
{
int rc;
u32 val;
if (dev->cpu_id == AMD_CPU_ID_PCO)
return -ENODEV;
rc = amd_pmc_send_cmd(dev, 0, &val, SMU_MSG_GETSMUVERSION, true);
if (rc)
return rc;
dev->smu_program = (val >> 24) & GENMASK(7, 0);
dev->major = (val >> 16) & GENMASK(7, 0);
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/array_size.h`, `linux/bitfield.h`, `linux/bits.h`, `linux/debugfs.h`, `linux/delay.h`, `linux/io.h`, `linux/iopoll.h`.
- Detected declarations: `function amd_pmc_reg_read`, `function amd_pmc_reg_write`, `function amd_pmc_get_ip_info`, `function amd_pmc_setup_smu_logging`, `function get_metrics_table`, `function amd_pmc_validate_deepest`, `function amd_pmc_get_smu_version`, `function smu_fw_version_show`, `function smu_program_show`, `function pmc_attr_is_visible`.
- Atlas domain: Driver Families / drivers/platform.
- Implementation status: source 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.