drivers/acpi/processor_driver.c

Source file repositories/reference/linux-study-clean/drivers/acpi/processor_driver.c

File Facts

System
Linux kernel
Corpus path
drivers/acpi/processor_driver.c
Extension
.c
Size
7558 bytes
Lines
312
Domain
Driver Families
Bucket
drivers/acpi
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static struct device_driver acpi_processor_driver = {
	.name = "processor",
	.bus = &cpu_subsys,
	.acpi_match_table = processor_device_ids,
	.remove = acpi_processor_stop,
};

static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
{
	struct acpi_device *device = data;
	struct acpi_processor *pr;
	int saved, ev_data = 0;

	if (device->handle != handle)
		return;

	pr = acpi_driver_data(device);
	if (!pr)
		return;

	switch (event) {
	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
		saved = pr->performance_platform_limit;
		acpi_processor_ppc_has_changed(pr, 1);
		ev_data = pr->performance_platform_limit;
		if (saved == ev_data)
			return;

		break;
	case ACPI_PROCESSOR_NOTIFY_POWER:
		acpi_processor_power_state_has_changed(pr);
		break;
	case ACPI_PROCESSOR_NOTIFY_THROTTLING:
		acpi_processor_tstate_has_changed(pr);
		break;
	case ACPI_PROCESSOR_NOTIFY_HIGEST_PERF_CHANGED:
		cpufreq_update_limits(pr->id);
		break;
	default:
		acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event);
		return;
	}

	acpi_bus_generate_netlink_event("processor", dev_name(&device->dev),
					event, ev_data);
}

static int __acpi_processor_start(struct acpi_device *device);

static int acpi_soft_cpu_online(unsigned int cpu)
{
	struct acpi_processor *pr = per_cpu(processors, cpu);
	struct acpi_device *device;

	if (!pr)
		return 0;

	device = acpi_fetch_acpi_dev(pr->handle);
	if (!device)
		return 0;

	/*
	 * CPU got physically hotplugged and onlined for the first time:
	 * Initialize missing things.
	 */
	if (!pr->flags.previously_online) {
		int ret;

		ret = __acpi_processor_start(device);
		WARN(ret, "Failed to start CPU: %d\n", pr->id);
	} else {
		/* Normal CPU soft online event. */
		acpi_processor_ppc_has_changed(pr, 0);
		acpi_processor_hotplug(pr);
		acpi_processor_reevaluate_tstate(pr, false);
		acpi_processor_tstate_has_changed(pr);
	}
	return 0;
}

static int acpi_soft_cpu_dead(unsigned int cpu)
{
	struct acpi_processor *pr = per_cpu(processors, cpu);

	if (!pr || !acpi_fetch_acpi_dev(pr->handle))
		return 0;

	acpi_processor_reevaluate_tstate(pr, true);
	return 0;
}

Annotation

Implementation Notes