diff options
Diffstat (limited to 'drivers/acpi/processor_perflib.c')
| -rw-r--r-- | drivers/acpi/processor_perflib.c | 474 |
1 files changed, 211 insertions, 263 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 1e9732d809bf..8972446b7162 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * processor_perflib.c - ACPI Processor P-States Library ($Revision: 71 $) * @@ -6,48 +7,23 @@ * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> * - Added processor hotplug support - * - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * */ +#define pr_fmt(fmt) "ACPI: " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/cpufreq.h> #include <linux/slab.h> - +#include <linux/acpi.h> +#include <acpi/processor.h> #ifdef CONFIG_X86 #include <asm/cpufeature.h> +#include <asm/msr.h> #endif -#include <acpi/acpi_bus.h> -#include <acpi/acpi_drivers.h> -#include <acpi/processor.h> - -#define PREFIX "ACPI: " - -#define ACPI_PROCESSOR_CLASS "processor" #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" -#define _COMPONENT ACPI_PROCESSOR_COMPONENT -ACPI_MODULE_NAME("processor_perflib"); - -static DEFINE_MUTEX(performance_mutex); /* * _PPC support is implemented as a CPUfreq policy notifier: @@ -70,59 +46,15 @@ module_param(ignore_ppc, int, 0644); MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ "limited by BIOS, this should help"); -#define PPC_REGISTERED 1 -#define PPC_IN_USE 2 - -static int acpi_processor_ppc_status; - -static int acpi_processor_ppc_notifier(struct notifier_block *nb, - unsigned long event, void *data) -{ - struct cpufreq_policy *policy = data; - struct acpi_processor *pr; - unsigned int ppc = 0; - - if (event == CPUFREQ_START && ignore_ppc <= 0) { - ignore_ppc = 0; - return 0; - } - - if (ignore_ppc) - return 0; - - if (event != CPUFREQ_INCOMPATIBLE) - return 0; - - mutex_lock(&performance_mutex); - - pr = per_cpu(processors, policy->cpu); - if (!pr || !pr->performance) - goto out; - - ppc = (unsigned int)pr->performance_platform_limit; - - if (ppc >= pr->performance->state_count) - goto out; - - cpufreq_verify_within_limits(policy, 0, - pr->performance->states[ppc]. - core_frequency * 1000); - - out: - mutex_unlock(&performance_mutex); - - return 0; -} - -static struct notifier_block acpi_ppc_notifier_block = { - .notifier_call = acpi_processor_ppc_notifier, -}; +static bool acpi_processor_ppc_in_use; static int acpi_processor_get_platform_limit(struct acpi_processor *pr) { acpi_status status = 0; unsigned long long ppc = 0; - + s32 qos_value; + int index; + int ret; if (!pr) return -EINVAL; @@ -132,19 +64,43 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) * (e.g. 0 = states 0..n; 1 = states 1..n; etc. */ status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc); + if (status != AE_NOT_FOUND) { + acpi_processor_ppc_in_use = true; - if (status != AE_NOT_FOUND) - acpi_processor_ppc_status |= PPC_IN_USE; - - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PPC")); - return -ENODEV; + 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, - (int)ppc, ppc ? "" : "not"); + index, index ? "is" : "is not"); - pr->performance_platform_limit = (int)ppc; + 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; } @@ -154,41 +110,28 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) * 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 specificed. + * 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) { - union acpi_object params[2] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - }; - struct acpi_object_list arg_list = {2, params}; - acpi_handle temp; - - params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; - params[1].integer.value = status; - - /* when there is no _OST , skip it */ - if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp))) - return; - - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); - return; + if (acpi_has_method(handle, "_OST")) + acpi_evaluate_ost(handle, ACPI_PROCESSOR_NOTIFY_PERFORMANCE, + status, NULL); } -int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) +void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) { int ret; - if (ignore_ppc) { + 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 0; + return; } ret = acpi_processor_get_platform_limit(pr); @@ -202,10 +145,8 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) else acpi_processor_ppc_ost(pr->handle, 0); } - if (ret < 0) - return (ret); - else - return cpufreq_update_policy(pr->id); + if (ret >= 0) + cpufreq_update_limits(pr->id); } int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) @@ -215,53 +156,73 @@ int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) pr = per_cpu(processors, cpu); if (!pr || !pr->performance || !pr->performance->state_count) return -ENODEV; + *limit = pr->performance->states[pr->performance_platform_limit]. core_frequency * 1000; return 0; } EXPORT_SYMBOL(acpi_processor_get_bios_limit); -void acpi_processor_ppc_init(void) +void acpi_processor_ignore_ppc_init(void) { - if (!cpufreq_register_notifier - (&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER)) - acpi_processor_ppc_status |= PPC_REGISTERED; - else - printk(KERN_DEBUG - "Warning: Processor Platform Limit not supported.\n"); + if (ignore_ppc < 0) + ignore_ppc = 0; } -void acpi_processor_ppc_exit(void) +void acpi_processor_ppc_init(struct cpufreq_policy *policy) { - if (acpi_processor_ppc_status & PPC_REGISTERED) - cpufreq_unregister_notifier(&acpi_ppc_notifier_block, - CPUFREQ_POLICY_NOTIFIER); + unsigned int cpu; + + if (ignore_ppc == 1) + return; + + for_each_cpu(cpu, policy->related_cpus) { + struct acpi_processor *pr = per_cpu(processors, cpu); + int ret; + + if (!pr) + continue; + + /* + * Reset performance_platform_limit in case there is a stale + * value in it, so as to make it match the "no limit" QoS value + * below. + */ + pr->performance_platform_limit = 0; + + ret = freq_qos_add_request(&policy->constraints, + &pr->perflib_req, FREQ_QOS_MAX, + FREQ_QOS_MAX_DEFAULT_VALUE); + if (ret < 0) + pr_err("Failed to add freq constraint for CPU%d (%d)\n", + cpu, ret); + + if (!pr->performance) + continue; - acpi_processor_ppc_status &= ~PPC_REGISTERED; + ret = acpi_processor_get_platform_limit(pr); + if (ret) + pr_err("Failed to update freq constraint for CPU%d (%d)\n", + cpu, ret); + } } -/* - * Do a quick check if the systems looks like it should use ACPI - * cpufreq. We look at a _PCT method being available, but don't - * do a whole lot of sanity checks. - */ -void acpi_processor_load_module(struct acpi_processor *pr) +void acpi_processor_ppc_exit(struct cpufreq_policy *policy) { - static int requested; - acpi_status status = 0; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + unsigned int cpu; - if (!arch_has_acpi_pdc() || requested) - return; - status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); - if (!ACPI_FAILURE(status)) { - printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n"); - request_module_nowait("acpi_cpufreq"); - requested = 1; + for_each_cpu(cpu, policy->related_cpus) { + struct acpi_processor *pr = per_cpu(processors, cpu); + + if (pr) + freq_qos_remove_request(&pr->perflib_req); } - kfree(buffer.pointer); } +#ifdef CONFIG_X86 + +static DEFINE_MUTEX(performance_mutex); + static int acpi_processor_get_performance_control(struct acpi_processor *pr) { int result = 0; @@ -270,17 +231,15 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr) union acpi_object *pct = NULL; union acpi_object obj = { 0 }; - status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PCT")); + acpi_evaluation_failure_warn(pr->handle, "_PCT", status); return -ENODEV; } pct = (union acpi_object *)buffer.pointer; - if (!pct || (pct->type != ACPI_TYPE_PACKAGE) - || (pct->package.count != 2)) { - printk(KERN_ERR PREFIX "Invalid _PCT data\n"); + if (!pct || pct->type != ACPI_TYPE_PACKAGE || pct->package.count != 2) { + pr_err("Invalid _PCT data\n"); result = -EFAULT; goto end; } @@ -291,10 +250,9 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr) obj = pct->package.elements[0]; - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_pct_register)) - || (obj.buffer.pointer == NULL)) { - printk(KERN_ERR PREFIX "Invalid _PCT data (control_register)\n"); + if (!obj.buffer.pointer || obj.type != ACPI_TYPE_BUFFER || + obj.buffer.length < sizeof(struct acpi_pct_register)) { + pr_err("Invalid _PCT data (control_register)\n"); result = -EFAULT; goto end; } @@ -307,10 +265,9 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr) obj = pct->package.elements[1]; - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_pct_register)) - || (obj.buffer.pointer == NULL)) { - printk(KERN_ERR PREFIX "Invalid _PCT data (status_register)\n"); + if (!obj.buffer.pointer || obj.type != ACPI_TYPE_BUFFER || + obj.buffer.length < sizeof(struct acpi_pct_register)) { + pr_err("Invalid _PCT data (status_register)\n"); result = -EFAULT; goto end; } @@ -318,13 +275,12 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr) memcpy(&pr->performance->status_register, obj.buffer.pointer, sizeof(struct acpi_pct_register)); - end: +end: kfree(buffer.pointer); return result; } -#ifdef CONFIG_X86 /* * Some AMDs have 50MHz frequency multiples, but only provide 100MHz rounding * in their ACPI data. Calculate the real values and fix up the _PSS data. @@ -337,8 +293,8 @@ static void amd_fixup_frequency(struct acpi_processor_px *px, int i) if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) return; - if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) - || boot_cpu_data.x86 == 0x11) { + if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) || + boot_cpu_data.x86 == 0x11) { rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi); /* * MSR C001_0064+: @@ -355,9 +311,6 @@ static void amd_fixup_frequency(struct acpi_processor_px *px, int i) px->core_frequency = (100 * (fid + 8)) >> did; } } -#else -static void amd_fixup_frequency(struct acpi_processor_px *px, int i) {}; -#endif static int acpi_processor_get_performance_states(struct acpi_processor *pr) { @@ -370,27 +323,27 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) int i; int last_invalid = -1; - status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PSS")); + acpi_evaluation_failure_warn(pr->handle, "_PSS", status); return -ENODEV; } pss = buffer.pointer; - if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { - printk(KERN_ERR PREFIX "Invalid _PSS data\n"); + if (!pss || pss->type != ACPI_TYPE_PACKAGE) { + pr_err("Invalid _PSS data\n"); result = -EFAULT; goto end; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n", - pss->package.count)); + acpi_handle_debug(pr->handle, "Found %d performance states\n", + pss->package.count); pr->performance->state_count = pss->package.count; pr->performance->states = - kmalloc(sizeof(struct acpi_processor_px) * pss->package.count, - GFP_KERNEL); + kmalloc_array(pss->package.count, + sizeof(struct acpi_processor_px), + GFP_KERNEL); if (!pr->performance->states) { result = -ENOMEM; goto end; @@ -403,12 +356,13 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) state.length = sizeof(struct acpi_processor_px); state.pointer = px; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i)); + acpi_handle_debug(pr->handle, "Extracting state %d\n", i); status = acpi_extract_package(&(pss->package.elements[i]), &format, &state); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Invalid _PSS data")); + acpi_handle_warn(pr->handle, "Invalid _PSS data: %s\n", + acpi_format_exception(status)); result = -EFAULT; kfree(pr->performance->states); goto end; @@ -416,22 +370,21 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) amd_fixup_frequency(px, i); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, + acpi_handle_debug(pr->handle, "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", i, (u32) px->core_frequency, (u32) px->power, (u32) px->transition_latency, (u32) px->bus_master_latency, - (u32) px->control, (u32) px->status)); + (u32) px->control, (u32) px->status); /* - * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq + * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq */ if (!px->core_frequency || - ((u32)(px->core_frequency * 1000) != - (px->core_frequency * 1000))) { - printk(KERN_ERR FW_BUG PREFIX + (u32)(px->core_frequency * 1000) != px->core_frequency * 1000) { + pr_err(FW_BUG "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n", pr->id, px->core_frequency); if (last_invalid == -1) @@ -449,8 +402,8 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) } if (last_invalid == 0) { - printk(KERN_ERR FW_BUG PREFIX - "No valid BIOS _PSS frequency found for processor %d\n", pr->id); + pr_err(FW_BUG + "No valid BIOS _PSS frequency found for processor %d\n", pr->id); result = -EFAULT; kfree(pr->performance->states); pr->performance->states = NULL; @@ -459,7 +412,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) if (last_invalid > 0) pr->performance->state_count = last_invalid; - end: +end: kfree(buffer.pointer); return result; @@ -468,16 +421,13 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) int acpi_processor_get_performance_info(struct acpi_processor *pr) { int result = 0; - acpi_status status = AE_OK; - acpi_handle handle = NULL; if (!pr || !pr->performance || !pr->handle) return -EINVAL; - status = acpi_get_handle(pr->handle, "_PCT", &handle); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "ACPI-based processor performance control unavailable\n")); + if (!acpi_has_method(pr->handle, "_PCT")) { + acpi_handle_debug(pr->handle, + "ACPI-based processor performance control unavailable\n"); return -ENODEV; } @@ -500,78 +450,85 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr) * the BIOS is older than the CPU and does not know its frequencies */ update_bios: -#ifdef CONFIG_X86 - if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){ + if (acpi_has_method(pr->handle, "_PPC")) { if(boot_cpu_has(X86_FEATURE_EST)) - printk(KERN_WARNING FW_BUG "BIOS needs update for CPU " + pr_warn(FW_BUG "BIOS needs update for CPU " "frequency support\n"); } -#endif return result; } EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info); -int acpi_processor_notify_smm(struct module *calling_module) + +int acpi_processor_pstate_control(void) { acpi_status status; - static int is_done = 0; + if (!acpi_gbl_FADT.smi_command || !acpi_gbl_FADT.pstate_control) + return 0; + + pr_debug("Writing pstate_control [0x%x] to smi_command [0x%x]\n", + acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command); - if (!(acpi_processor_ppc_status & PPC_REGISTERED)) + status = acpi_os_write_port(acpi_gbl_FADT.smi_command, + (u32)acpi_gbl_FADT.pstate_control, 8); + if (ACPI_SUCCESS(status)) + return 1; + + pr_warn("Failed to write pstate_control [0x%x] to smi_command [0x%x]: %s\n", + acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command, + acpi_format_exception(status)); + return -EIO; +} + +int acpi_processor_notify_smm(struct module *calling_module) +{ + static int is_done; + int result = 0; + + if (!acpi_processor_cpufreq_init) return -EBUSY; if (!try_module_get(calling_module)) return -EINVAL; - /* is_done is set to negative if an error occurred, - * and to postitive if _no_ error occurred, but SMM - * was already notified. This avoids double notification - * which might lead to unexpected results... + /* + * is_done is set to negative if an error occurs and to 1 if no error + * occurrs, but SMM has been notified already. This avoids repeated + * notification which might lead to unexpected results. */ - if (is_done > 0) { - module_put(calling_module); - return 0; - } else if (is_done < 0) { - module_put(calling_module); - return is_done; - } - - is_done = -EIO; + if (is_done != 0) { + if (is_done < 0) + result = is_done; - /* Can't write pstate_control to smi_command if either value is zero */ - if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n")); - module_put(calling_module); - return 0; + goto out_put; } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Writing pstate_control [0x%x] to smi_command [0x%x]\n", - acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command)); - - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, - (u32) acpi_gbl_FADT.pstate_control, 8); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Failed to write pstate_control [0x%x] to " - "smi_command [0x%x]", acpi_gbl_FADT.pstate_control, - acpi_gbl_FADT.smi_command)); - module_put(calling_module); - return status; + result = acpi_processor_pstate_control(); + if (result <= 0) { + if (result) { + is_done = result; + } else { + pr_debug("No SMI port or pstate_control\n"); + is_done = 1; + } + goto out_put; } - /* Success. If there's no _PPC, we need to fear nothing, so - * we can allow the cpufreq driver to be rmmod'ed. */ is_done = 1; + /* + * Success. If there _PPC, unloading the cpufreq driver would be risky, + * so disallow it in that case. + */ + if (acpi_processor_ppc_in_use) + return 0; - if (!(acpi_processor_ppc_status & PPC_IN_USE)) - module_put(calling_module); - - return 0; +out_put: + module_put(calling_module); + return result; } - EXPORT_SYMBOL(acpi_processor_notify_smm); -static int acpi_processor_get_psd(struct acpi_processor *pr) +int acpi_processor_get_psd(acpi_handle handle, struct acpi_psd_package *pdomain) { int result = 0; acpi_status status = AE_OK; @@ -579,47 +536,43 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"}; struct acpi_buffer state = {0, NULL}; union acpi_object *psd = NULL; - struct acpi_psd_package *pdomain; - status = acpi_evaluate_object(pr->handle, "_PSD", NULL, &buffer); + status = acpi_evaluate_object(handle, "_PSD", NULL, &buffer); if (ACPI_FAILURE(status)) { return -ENODEV; } psd = buffer.pointer; - if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { - printk(KERN_ERR PREFIX "Invalid _PSD data\n"); + if (!psd || psd->type != ACPI_TYPE_PACKAGE) { + pr_err("Invalid _PSD data\n"); result = -EFAULT; goto end; } if (psd->package.count != 1) { - printk(KERN_ERR PREFIX "Invalid _PSD data\n"); + pr_err("Invalid _PSD data\n"); result = -EFAULT; goto end; } - pdomain = &(pr->performance->domain_info); - state.length = sizeof(struct acpi_psd_package); state.pointer = pdomain; - status = acpi_extract_package(&(psd->package.elements[0]), - &format, &state); + status = acpi_extract_package(&(psd->package.elements[0]), &format, &state); if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Invalid _PSD data\n"); + pr_err("Invalid _PSD data\n"); result = -EFAULT; goto end; } if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) { - printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n"); + pr_err("Unknown _PSD:num_entries\n"); result = -EFAULT; goto end; } if (pdomain->revision != ACPI_PSD_REV0_REVISION) { - printk(KERN_ERR PREFIX "Unknown _PSD:revision\n"); + pr_err("Unknown _PSD:revision\n"); result = -EFAULT; goto end; } @@ -627,7 +580,7 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL && pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY && pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) { - printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n"); + pr_err("Invalid _PSD:coord_type\n"); result = -EFAULT; goto end; } @@ -635,6 +588,7 @@ end: kfree(buffer.pointer); return result; } +EXPORT_SYMBOL(acpi_processor_get_psd); int acpi_processor_preregister_performance( struct acpi_processor_performance __percpu *performance) @@ -682,8 +636,8 @@ int acpi_processor_preregister_performance( continue; pr->performance = per_cpu_ptr(performance, i); - cpumask_set_cpu(i, pr->performance->shared_cpu_map); - if (acpi_processor_get_psd(pr)) { + pdomain = &(pr->performance->domain_info); + if (acpi_processor_get_psd(pr->handle, pdomain)) { retval = -EINVAL; continue; } @@ -692,7 +646,7 @@ int acpi_processor_preregister_performance( goto err_ret; /* - * Now that we have _PSD data from all CPUs, lets setup P-state + * Now that we have _PSD data from all CPUs, lets setup P-state * domain info. */ for_each_possible_cpu(i) { @@ -758,7 +712,7 @@ int acpi_processor_preregister_performance( if (match_pdomain->domain != pdomain->domain) continue; - match_pr->performance->shared_type = + match_pr->performance->shared_type = pr->performance->shared_type; cpumask_copy(match_pr->performance->shared_cpu_map, pr->performance->shared_cpu_map); @@ -775,7 +729,7 @@ err_ret: if (retval) { cpumask_clear(pr->performance->shared_cpu_map); cpumask_set_cpu(i, pr->performance->shared_cpu_map); - pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL; + pr->performance->shared_type = CPUFREQ_SHARED_TYPE_NONE; } pr->performance = NULL; /* Will be set for real in register */ } @@ -787,13 +741,12 @@ err_out: } EXPORT_SYMBOL(acpi_processor_preregister_performance); -int -acpi_processor_register_performance(struct acpi_processor_performance - *performance, unsigned int cpu) +int acpi_processor_register_performance(struct acpi_processor_performance + *performance, unsigned int cpu) { struct acpi_processor *pr; - if (!(acpi_processor_ppc_status & PPC_REGISTERED)) + if (!acpi_processor_cpufreq_init) return -EINVAL; mutex_lock(&performance_mutex); @@ -822,30 +775,25 @@ acpi_processor_register_performance(struct acpi_processor_performance mutex_unlock(&performance_mutex); return 0; } - EXPORT_SYMBOL(acpi_processor_register_performance); -void -acpi_processor_unregister_performance(struct acpi_processor_performance - *performance, unsigned int cpu) +void acpi_processor_unregister_performance(unsigned int cpu) { struct acpi_processor *pr; mutex_lock(&performance_mutex); pr = per_cpu(processors, cpu); - if (!pr) { - mutex_unlock(&performance_mutex); - return; - } + if (!pr) + goto unlock; if (pr->performance) kfree(pr->performance->states); + pr->performance = NULL; +unlock: mutex_unlock(&performance_mutex); - - return; } - EXPORT_SYMBOL(acpi_processor_unregister_performance); +#endif |
