Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * processor_perflib.c - ACPI Processor P-States Library ($Revision: 71 $)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  			- Added processor hotplug support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/cpufreq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <acpi/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/cpufeature.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define PREFIX "ACPI: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define ACPI_PROCESSOR_CLASS		"processor"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define ACPI_PROCESSOR_FILE_PERFORMANCE	"performance"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) ACPI_MODULE_NAME("processor_perflib");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static DEFINE_MUTEX(performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * _PPC support is implemented as a CPUfreq policy notifier:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * This means each time a CPUfreq driver registered also with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * the ACPI core is asked to change the speed policy, the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * value is adjusted so that it is within the platform limit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * Also, when a new platform limit value is detected, the CPUfreq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * policy is adjusted accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /* ignore_ppc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * -1 -> cpufreq low level drivers not initialized -> _PSS, etc. not called yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *       ignore _PPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  *  0 -> cpufreq low level drivers initialized -> consider _PPC values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  *  1 -> ignore _PPC totally -> forced by user through boot param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static int ignore_ppc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) module_param(ignore_ppc, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		 "limited by BIOS, this should help");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static bool acpi_processor_ppc_in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	acpi_status status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	unsigned long long ppc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (!pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	 * _PPC indicates the maximum state currently supported by the platform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	 * (e.g. 0 = states 0..n; 1 = states 1..n; etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	if (status != AE_NOT_FOUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		acpi_processor_ppc_in_use = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PPC"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		       (int)ppc, ppc ? "" : "not");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	pr->performance_platform_limit = (int)ppc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (ppc >= pr->performance->state_count ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	    unlikely(!freq_qos_request_active(&pr->perflib_req)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	ret = freq_qos_update_request(&pr->perflib_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			pr->performance->states[ppc].core_frequency * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			pr->id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * @handle: ACPI processor handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * @status: the status code of _PPC evaluation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  *	0: success. OSPM is now using the performance state specificed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *	1: failure. OSPM has not changed the number of P-states in use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void acpi_processor_ppc_ost(acpi_handle handle, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (acpi_has_method(handle, "_OST"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		acpi_evaluate_ost(handle, ACPI_PROCESSOR_NOTIFY_PERFORMANCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 				  status, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (ignore_ppc || !pr->performance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		 * Only when it is notification event, the _OST object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		 * will be evaluated. Otherwise it is skipped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		if (event_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			acpi_processor_ppc_ost(pr->handle, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	ret = acpi_processor_get_platform_limit(pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	 * Only when it is notification event, the _OST object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * will be evaluated. Otherwise it is skipped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	if (event_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			acpi_processor_ppc_ost(pr->handle, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 			acpi_processor_ppc_ost(pr->handle, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		cpufreq_update_limits(pr->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct acpi_processor *pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	pr = per_cpu(processors, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (!pr || !pr->performance || !pr->performance->state_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	*limit = pr->performance->states[pr->performance_platform_limit].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		core_frequency * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) EXPORT_SYMBOL(acpi_processor_get_bios_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) void acpi_processor_ignore_ppc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (ignore_ppc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		ignore_ppc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) void acpi_processor_ppc_init(struct cpufreq_policy *policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	unsigned int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	for_each_cpu(cpu, policy->related_cpus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		struct acpi_processor *pr = per_cpu(processors, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		if (!pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		ret = freq_qos_add_request(&policy->constraints,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 					   &pr->perflib_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 					   FREQ_QOS_MAX, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			pr_err("Failed to add freq constraint for CPU%d (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			       cpu, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) void acpi_processor_ppc_exit(struct cpufreq_policy *policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	unsigned int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	for_each_cpu(cpu, policy->related_cpus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		struct acpi_processor *pr = per_cpu(processors, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		if (pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			freq_qos_remove_request(&pr->perflib_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int acpi_processor_get_performance_control(struct acpi_processor *pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	acpi_status status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	union acpi_object *pct = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	union acpi_object obj = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PCT"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	pct = (union acpi_object *)buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (!pct || (pct->type != ACPI_TYPE_PACKAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	    || (pct->package.count != 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		printk(KERN_ERR PREFIX "Invalid _PCT data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	 * control_register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	obj = pct->package.elements[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if ((obj.type != ACPI_TYPE_BUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	    || (obj.buffer.length < sizeof(struct acpi_pct_register))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	    || (obj.buffer.pointer == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		printk(KERN_ERR PREFIX "Invalid _PCT data (control_register)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	memcpy(&pr->performance->control_register, obj.buffer.pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	       sizeof(struct acpi_pct_register));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	 * status_register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	obj = pct->package.elements[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	if ((obj.type != ACPI_TYPE_BUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	    || (obj.buffer.length < sizeof(struct acpi_pct_register))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	    || (obj.buffer.pointer == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		printk(KERN_ERR PREFIX "Invalid _PCT data (status_register)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	memcpy(&pr->performance->status_register, obj.buffer.pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	       sizeof(struct acpi_pct_register));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)       end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	kfree(buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  * Some AMDs have 50MHz frequency multiples, but only provide 100MHz rounding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  * in their ACPI data. Calculate the real values and fix up the _PSS data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	u32 hi, lo, fid, did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	int index = px->control & 0x00000007;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	    || boot_cpu_data.x86 == 0x11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		 * MSR C001_0064+:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		 * Bit 63: PstateEn. Read-write. If set, the P-state is valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		if (!(hi & BIT(31)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		fid = lo & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		did = (lo >> 6) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		if (boot_cpu_data.x86 == 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			px->core_frequency = (100 * (fid + 0x10)) >> did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			px->core_frequency = (100 * (fid + 8)) >> did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static void amd_fixup_frequency(struct acpi_processor_px *px, int i) {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int acpi_processor_get_performance_states(struct acpi_processor *pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	struct acpi_buffer format = { sizeof("NNNNNN"), "NNNNNN" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	struct acpi_buffer state = { 0, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	union acpi_object *pss = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	int last_invalid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PSS"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	pss = buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		printk(KERN_ERR PREFIX "Invalid _PSS data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			  pss->package.count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	pr->performance->state_count = pss->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	pr->performance->states =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	    kmalloc_array(pss->package.count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			  sizeof(struct acpi_processor_px),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	if (!pr->performance->states) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		result = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	for (i = 0; i < pr->performance->state_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		struct acpi_processor_px *px = &(pr->performance->states[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		state.length = sizeof(struct acpi_processor_px);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		state.pointer = px;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		status = acpi_extract_package(&(pss->package.elements[i]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 					      &format, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			ACPI_EXCEPTION((AE_INFO, status, "Invalid _PSS data"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			kfree(pr->performance->states);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		amd_fixup_frequency(px, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 				  "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 				  i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				  (u32) px->core_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				  (u32) px->power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				  (u32) px->transition_latency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				  (u32) px->bus_master_latency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 				  (u32) px->control, (u32) px->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		 * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		if (!px->core_frequency ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		    ((u32)(px->core_frequency * 1000) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		     (px->core_frequency * 1000))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 			printk(KERN_ERR FW_BUG PREFIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			       "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			       pr->id, px->core_frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			if (last_invalid == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				last_invalid = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			if (last_invalid != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 				 * Copy this valid entry over last_invalid entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 				memcpy(&(pr->performance->states[last_invalid]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 				       px, sizeof(struct acpi_processor_px));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 				++last_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	if (last_invalid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		printk(KERN_ERR FW_BUG PREFIX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		       "No valid BIOS _PSS frequency found for processor %d\n", pr->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		kfree(pr->performance->states);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		pr->performance->states = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (last_invalid > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		pr->performance->state_count = last_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)       end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	kfree(buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int acpi_processor_get_performance_info(struct acpi_processor *pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (!pr || !pr->performance || !pr->handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (!acpi_has_method(pr->handle, "_PCT")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 				  "ACPI-based processor performance control unavailable\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	result = acpi_processor_get_performance_control(pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		goto update_bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	result = acpi_processor_get_performance_states(pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		goto update_bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	/* We need to call _PPC once when cpufreq starts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if (ignore_ppc != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		result = acpi_processor_get_platform_limit(pr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	 * the BIOS is older than the CPU and does not know its frequencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  update_bios:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) #ifdef CONFIG_X86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (acpi_has_method(pr->handle, "_PPC")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if(boot_cpu_has(X86_FEATURE_EST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			       "frequency support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int acpi_processor_pstate_control(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	if (!acpi_gbl_FADT.smi_command || !acpi_gbl_FADT.pstate_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			  "Writing pstate_control [0x%x] to smi_command [0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			  acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 				    (u32)acpi_gbl_FADT.pstate_control, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	ACPI_EXCEPTION((AE_INFO, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			"Failed to write pstate_control [0x%x] to smi_command [0x%x]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int acpi_processor_notify_smm(struct module *calling_module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	static int is_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (!acpi_processor_cpufreq_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (!try_module_get(calling_module))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	/* is_done is set to negative if an error occurred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	 * and to postitive if _no_ error occurred, but SMM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	 * was already notified. This avoids double notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	 * which might lead to unexpected results...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	if (is_done > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		module_put(calling_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	} else if (is_done < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		module_put(calling_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		return is_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	is_done = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	result = acpi_processor_pstate_control();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	if (!result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		module_put(calling_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		module_put(calling_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	/* Success. If there's no _PPC, we need to fear nothing, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	 * we can allow the cpufreq driver to be rmmod'ed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	is_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	if (!acpi_processor_ppc_in_use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		module_put(calling_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) EXPORT_SYMBOL(acpi_processor_notify_smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	struct acpi_buffer state = {0, NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	union acpi_object  *psd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	status = acpi_evaluate_object(handle, "_PSD", NULL, &buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	psd = buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		printk(KERN_ERR PREFIX "Invalid _PSD data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	if (psd->package.count != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		printk(KERN_ERR PREFIX "Invalid _PSD data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	state.length = sizeof(struct acpi_psd_package);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	state.pointer = pdomain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	status = acpi_extract_package(&(psd->package.elements[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		&format, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		printk(KERN_ERR PREFIX "Invalid _PSD data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		printk(KERN_ERR PREFIX "Unknown _PSD:revision\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		result = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	kfree(buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) EXPORT_SYMBOL(acpi_processor_get_psd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int acpi_processor_preregister_performance(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		struct acpi_processor_performance __percpu *performance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	int count_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	cpumask_var_t covered_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	struct acpi_processor *pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	struct acpi_psd_package *pdomain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	struct acpi_processor *match_pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	struct acpi_psd_package *match_pdomain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	mutex_lock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	 * Check if another driver has already registered, and abort before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	 * changing pr->performance if it has. Check input data as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		pr = per_cpu(processors, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		if (!pr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 			/* Look only at processors in ACPI namespace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		if (pr->performance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			retval = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		if (!performance || !per_cpu_ptr(performance, i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 			retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 			goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	/* Call _PSD for all CPUs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		pr = per_cpu(processors, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		if (!pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		pr->performance = per_cpu_ptr(performance, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		cpumask_set_cpu(i, pr->performance->shared_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		pdomain = &(pr->performance->domain_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		if (acpi_processor_get_psd(pr->handle, pdomain)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 		goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	 * Now that we have _PSD data from all CPUs, lets setup P-state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	 * domain info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		pr = per_cpu(processors, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		if (!pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		if (cpumask_test_cpu(i, covered_cpus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		pdomain = &(pr->performance->domain_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		cpumask_set_cpu(i, pr->performance->shared_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		cpumask_set_cpu(i, covered_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		if (pdomain->num_processors <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		/* Validate the Domain info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		count_target = pdomain->num_processors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 			pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 			pr->performance->shared_type = CPUFREQ_SHARED_TYPE_HW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ANY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		for_each_possible_cpu(j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 			if (i == j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			match_pr = per_cpu(processors, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			if (!match_pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			match_pdomain = &(match_pr->performance->domain_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			if (match_pdomain->domain != pdomain->domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			/* Here i and j are in the same domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			if (match_pdomain->num_processors != count_target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 				retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 				goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 			if (pdomain->coord_type != match_pdomain->coord_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 				retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 				goto err_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 			cpumask_set_cpu(j, covered_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 			cpumask_set_cpu(j, pr->performance->shared_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		for_each_possible_cpu(j) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 			if (i == j)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 			match_pr = per_cpu(processors, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 			if (!match_pr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 			match_pdomain = &(match_pr->performance->domain_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 			if (match_pdomain->domain != pdomain->domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 			match_pr->performance->shared_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 					pr->performance->shared_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 			cpumask_copy(match_pr->performance->shared_cpu_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 				     pr->performance->shared_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) err_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	for_each_possible_cpu(i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		pr = per_cpu(processors, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		if (!pr || !pr->performance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		/* Assume no coordination on any error parsing domain info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 			cpumask_clear(pr->performance->shared_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 			cpumask_set_cpu(i, pr->performance->shared_cpu_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 			pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		pr->performance = NULL; /* Will be set for real in register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	mutex_unlock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	free_cpumask_var(covered_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) EXPORT_SYMBOL(acpi_processor_preregister_performance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) acpi_processor_register_performance(struct acpi_processor_performance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 				    *performance, unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	struct acpi_processor *pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	if (!acpi_processor_cpufreq_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	mutex_lock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	pr = per_cpu(processors, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (!pr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		mutex_unlock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	if (pr->performance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		mutex_unlock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	WARN_ON(!performance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	pr->performance = performance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	if (acpi_processor_get_performance_info(pr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		pr->performance = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		mutex_unlock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	mutex_unlock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) EXPORT_SYMBOL(acpi_processor_register_performance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) void acpi_processor_unregister_performance(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	struct acpi_processor *pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	mutex_lock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	pr = per_cpu(processors, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	if (!pr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		mutex_unlock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	if (pr->performance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		kfree(pr->performance->states);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	pr->performance = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	mutex_unlock(&performance_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) EXPORT_SYMBOL(acpi_processor_unregister_performance);