drivers/acpi/processor_perflib.c

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

File Facts

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

Dependency Surface

Detected Declarations

Annotated Snippet

if (ACPI_FAILURE(status)) {
			acpi_evaluation_failure_warn(pr->handle, "_PPC", status);
			return -ENODEV;
		}
	}

	index = ppc;

	if (pr->performance_platform_limit == index ||
	    ppc >= pr->performance->state_count)
		return 0;

	pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
		 index, index ? "is" : "is not");

	pr->performance_platform_limit = index;

	if (unlikely(!freq_qos_request_active(&pr->perflib_req)))
		return 0;

	/*
	 * If _PPC returns 0, it means that all of the available states can be
	 * used ("no limit").
	 */
	if (index == 0)
		qos_value = FREQ_QOS_MAX_DEFAULT_VALUE;
	else
		qos_value = pr->performance->states[index].core_frequency * 1000;

	ret = freq_qos_update_request(&pr->perflib_req, qos_value);
	if (ret < 0) {
		pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n",
			pr->id, ret);
	}

	return 0;
}

#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE	0x80
/*
 * acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status
 * @handle: ACPI processor handle
 * @status: the status code of _PPC evaluation
 *	0: success. OSPM is now using the performance state specified.
 *	1: failure. OSPM has not changed the number of P-states in use
 */
static void acpi_processor_ppc_ost(acpi_handle handle, int status)
{
	if (acpi_has_method(handle, "_OST"))
		acpi_evaluate_ost(handle, ACPI_PROCESSOR_NOTIFY_PERFORMANCE,
				  status, NULL);
}

void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
{
	int ret;

	if (ignore_ppc || !pr->performance) {
		/*
		 * Only when it is notification event, the _OST object
		 * will be evaluated. Otherwise it is skipped.
		 */
		if (event_flag)
			acpi_processor_ppc_ost(pr->handle, 1);
		return;
	}

	ret = acpi_processor_get_platform_limit(pr);
	/*
	 * Only when it is notification event, the _OST object
	 * will be evaluated. Otherwise it is skipped.
	 */
	if (event_flag) {
		if (ret < 0)
			acpi_processor_ppc_ost(pr->handle, 1);
		else
			acpi_processor_ppc_ost(pr->handle, 0);
	}
	if (ret >= 0)
		cpufreq_update_limits(pr->id);
}

int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
{
	struct acpi_processor *pr;

	pr = per_cpu(processors, cpu);
	if (!pr || !pr->performance || !pr->performance->state_count)
		return -ENODEV;

Annotation

Implementation Notes