drivers/firmware/psci/psci.c
Source file repositories/reference/linux-study-clean/drivers/firmware/psci/psci.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/firmware/psci/psci.c- Extension
.c- Size
- 20191 bytes
- Lines
- 851
- Domain
- Driver Families
- Bucket
- drivers/firmware
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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 an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/arm-smccc.hlinux/cpuidle.hlinux/debugfs.hlinux/errno.hlinux/linkage.hlinux/of.hlinux/pm.hlinux/printk.hlinux/psci.hlinux/reboot.hlinux/slab.hlinux/suspend.huapi/linux/psci.hasm/cpuidle.hasm/cputype.hasm/hypervisor.hasm/system_misc.hasm/smp_plat.hasm/suspend.h
Detected Declarations
function psci_tos_resident_onfunction get_psci_0_1_function_idsfunction psci_has_ext_power_statefunction psci_has_osi_supportfunction psci_power_state_loses_contextfunction psci_power_state_is_validfunction __invoke_psci_fn_hvcfunction __invoke_psci_fn_smcfunction psci_to_linux_errnofunction psci_0_1_get_versionfunction psci_0_2_get_versionfunction psci_set_osi_modefunction __psci_cpu_suspendfunction psci_0_1_cpu_suspendfunction psci_0_2_cpu_suspendfunction __psci_cpu_offfunction psci_0_1_cpu_offfunction psci_0_2_cpu_offfunction __psci_cpu_onfunction psci_0_1_cpu_onfunction psci_0_2_cpu_onfunction __psci_migratefunction psci_0_1_migratefunction psci_0_2_migratefunction psci_affinity_infofunction psci_migrate_info_typefunction psci_migrate_info_up_cpufunction set_conduitfunction get_set_conduit_methodfunction psci_sys_resetfunction psci_sys_powerofffunction psci_sys_hibernatefunction psci_hibernate_initfunction psci_featuresfunction psci_debugfs_readfunction psci_debugfs_openfunction psci_debugfs_initfunction psci_suspend_finisherfunction psci_cpu_suspend_enterfunction psci_system_suspendfunction psci_system_suspend_enterfunction psci_system_suspend_beginfunction psci_init_system_reset2function psci_init_system_off2function psci_init_system_suspendfunction psci_init_cpu_suspendfunction DENIEDfunction psci_init_smccc
Annotated Snippet
static const struct file_operations psci_debugfs_ops = {
.owner = THIS_MODULE,
.open = psci_debugfs_open,
.release = single_release,
.read = seq_read,
.llseek = seq_lseek
};
static int __init psci_debugfs_init(void)
{
if (!invoke_psci_fn || !psci_ops.get_version)
return 0;
return PTR_ERR_OR_ZERO(debugfs_create_file("psci", 0444, NULL, NULL,
&psci_debugfs_ops));
}
late_initcall(psci_debugfs_init)
#endif
#ifdef CONFIG_CPU_IDLE
static noinstr int psci_suspend_finisher(unsigned long state)
{
u32 power_state = state;
phys_addr_t pa_cpu_resume;
pa_cpu_resume = __pa_symbol_nodebug((unsigned long)cpu_resume);
return psci_ops.cpu_suspend(power_state, pa_cpu_resume);
}
int psci_cpu_suspend_enter(u32 state)
{
int ret;
if (!psci_power_state_loses_context(state)) {
struct arm_cpuidle_irq_context context;
ct_cpuidle_enter();
arm_cpuidle_save_irq_context(&context);
ret = psci_ops.cpu_suspend(state, 0);
arm_cpuidle_restore_irq_context(&context);
ct_cpuidle_exit();
} else {
/*
* ARM64 cpu_suspend() wants to do ct_cpuidle_*() itself.
*/
if (!IS_ENABLED(CONFIG_ARM64))
ct_cpuidle_enter();
ret = cpu_suspend(state, psci_suspend_finisher);
if (!IS_ENABLED(CONFIG_ARM64))
ct_cpuidle_exit();
}
return ret;
}
#endif
static int psci_system_suspend(unsigned long unused)
{
int err;
phys_addr_t pa_cpu_resume = __pa_symbol(cpu_resume);
err = invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
pa_cpu_resume, 0, 0);
return psci_to_linux_errno(err);
}
static int psci_system_suspend_enter(suspend_state_t state)
{
pm_set_resume_via_firmware();
return cpu_suspend(0, psci_system_suspend);
}
static int psci_system_suspend_begin(suspend_state_t state)
{
pm_set_suspend_via_firmware();
return 0;
}
static const struct platform_suspend_ops psci_suspend_ops = {
.valid = suspend_valid_only_mem,
.enter = psci_system_suspend_enter,
.begin = psci_system_suspend_begin,
};
static void __init psci_init_system_reset2(void)
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/arm-smccc.h`, `linux/cpuidle.h`, `linux/debugfs.h`, `linux/errno.h`, `linux/linkage.h`, `linux/of.h`, `linux/pm.h`.
- Detected declarations: `function psci_tos_resident_on`, `function get_psci_0_1_function_ids`, `function psci_has_ext_power_state`, `function psci_has_osi_support`, `function psci_power_state_loses_context`, `function psci_power_state_is_valid`, `function __invoke_psci_fn_hvc`, `function __invoke_psci_fn_smc`, `function psci_to_linux_errno`, `function psci_0_1_get_version`.
- Atlas domain: Driver Families / drivers/firmware.
- Implementation status: pattern 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.