drivers/acpi/processor_idle.c
Source file repositories/reference/linux-study-clean/drivers/acpi/processor_idle.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/acpi/processor_idle.c- Extension
.c- Size
- 37586 bytes
- Lines
- 1471
- Domain
- Driver Families
- Bucket
- drivers/acpi
- 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/module.hlinux/acpi.hlinux/dmi.hlinux/sched.hlinux/tick.hlinux/cpuidle.hlinux/cpu.hlinux/minmax.hlinux/perf_event.hacpi/processor.hlinux/context_tracking.hinternal.hasm/apic.hasm/cpu.h
Detected Declarations
struct acpi_lpi_states_arrayfunction acpi_idle_rescan_dead_smt_siblingsfunction disabled_by_idle_boot_paramfunction set_max_cstatefunction acpi_safe_haltfunction lapic_timer_check_statefunction __lapic_timer_propagate_broadcastfunction lapic_timer_propagate_broadcastfunction lapic_timer_needs_broadcastfunction lapic_timer_check_statefunction tsc_check_statefunction tsc_check_statefunction acpi_processor_get_power_info_fadtfunction acpi_processor_get_power_info_defaultfunction acpi_processor_get_power_info_cstfunction acpi_processor_power_verify_c3function acpi_cst_latency_sortfunction acpi_processor_power_verifyfunction acpi_processor_get_cstate_infofunction acpi_idle_bm_checkfunction io_idlefunction acpi_idle_do_entryfunction acpi_idle_play_deadfunction acpi_idle_fallback_to_c1function acpi_idle_enter_bmfunction acpi_idle_enterfunction acpi_idle_enter_s2idlefunction acpi_processor_setup_cpuidle_cxfunction acpi_processor_setup_cstatesfunction acpi_processor_update_max_cstatefunction disabled_by_idle_boot_paramfunction acpi_processor_update_max_cstatefunction acpi_processor_setup_cpuidle_cxfunction acpi_processor_setup_cstatesfunction obj_get_integerfunction acpi_processor_evaluate_lpifunction combine_lpi_statesfunction stash_composite_statefunction flatten_lpi_statesfunction acpi_processor_ffh_lpi_probefunction acpi_processor_get_lpi_infofunction acpi_processor_ffh_lpi_enterfunction acpi_idle_lpi_enterfunction acpi_processor_setup_lpi_statesfunction acpi_processor_setup_cpuidle_statesfunction acpi_processor_setup_cpuidle_devfunction acpi_processor_get_power_infofunction acpi_processor_hotplug
Annotated Snippet
struct acpi_lpi_states_array {
unsigned int size;
unsigned int composite_states_size;
struct acpi_lpi_state *entries;
struct acpi_lpi_state *composite_states[ACPI_PROCESSOR_MAX_POWER];
};
static int obj_get_integer(union acpi_object *obj, u32 *value)
{
if (obj->type != ACPI_TYPE_INTEGER)
return -EINVAL;
*value = obj->integer.value;
return 0;
}
static int acpi_processor_evaluate_lpi(acpi_handle handle,
struct acpi_lpi_states_array *info)
{
acpi_status status;
int ret = 0;
int pkg_count, state_idx = 1, loop;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *lpi_data;
struct acpi_lpi_state *lpi_state;
status = acpi_evaluate_object(handle, "_LPI", NULL, &buffer);
if (ACPI_FAILURE(status)) {
acpi_handle_debug(handle, "No _LPI, giving up\n");
return -ENODEV;
}
lpi_data = buffer.pointer;
/* There must be at least 4 elements = 3 elements + 1 package */
if (!lpi_data || lpi_data->type != ACPI_TYPE_PACKAGE ||
lpi_data->package.count < 4) {
pr_debug("not enough elements in _LPI\n");
ret = -ENODATA;
goto end;
}
pkg_count = lpi_data->package.elements[2].integer.value;
/* Validate number of power states. */
if (pkg_count < 1 || pkg_count != lpi_data->package.count - 3) {
pr_debug("count given by _LPI is not valid\n");
ret = -ENODATA;
goto end;
}
lpi_state = kzalloc_objs(*lpi_state, pkg_count);
if (!lpi_state) {
ret = -ENOMEM;
goto end;
}
info->size = pkg_count;
info->entries = lpi_state;
/* LPI States start at index 3 */
for (loop = 3; state_idx <= pkg_count; loop++, state_idx++, lpi_state++) {
union acpi_object *element, *pkg_elem, *obj;
element = &lpi_data->package.elements[loop];
if (element->type != ACPI_TYPE_PACKAGE || element->package.count < 7)
continue;
pkg_elem = element->package.elements;
obj = pkg_elem + 6;
if (obj->type == ACPI_TYPE_BUFFER) {
struct acpi_power_register *reg;
reg = (struct acpi_power_register *)obj->buffer.pointer;
if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO &&
reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)
continue;
lpi_state->address = reg->address;
lpi_state->entry_method =
reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE ?
ACPI_CSTATE_FFH : ACPI_CSTATE_SYSTEMIO;
} else if (obj->type == ACPI_TYPE_INTEGER) {
lpi_state->entry_method = ACPI_CSTATE_INTEGER;
lpi_state->address = obj->integer.value;
} else {
pr_debug("Entry method of state-%d is invalid, disable it.\n",
state_idx);
continue;
Annotation
- Immediate include surface: `linux/module.h`, `linux/acpi.h`, `linux/dmi.h`, `linux/sched.h`, `linux/tick.h`, `linux/cpuidle.h`, `linux/cpu.h`, `linux/minmax.h`.
- Detected declarations: `struct acpi_lpi_states_array`, `function acpi_idle_rescan_dead_smt_siblings`, `function disabled_by_idle_boot_param`, `function set_max_cstate`, `function acpi_safe_halt`, `function lapic_timer_check_state`, `function __lapic_timer_propagate_broadcast`, `function lapic_timer_propagate_broadcast`, `function lapic_timer_needs_broadcast`, `function lapic_timer_check_state`.
- Atlas domain: Driver Families / drivers/acpi.
- 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.