There are HP servers where the BIOS is capable of managing P-states inherently. On those systems the BIOS does not provide the relevant ACPI data (_PSS,_PCT etc.) to the OS. We don't want to print the following "firmware bug" error messages on those servers: [Firmware Bug]: powernow-k8: No compatible ACPI _PSS objects found. [Firmware Bug]: powernow-k8: Try again with latest BIOS. I think in each of the following cases the call to acpi_processor_register_performance() will fail in the P-state driver: 1) a buggy BIOS (that relinquishes control to the P-state driver, but has an error in the ACPI data) 2) a BIOS that doesn't intentionally expose relevant ACPI info because the HW is buggy 3) a BIOS that manages P-states inherently and doesn't want to provide the cpufreq-related ACPI data There is no simple/clean way to distinguish between these cases. Below is a whitelist that mentions those AMD-based HP x86 servers whose BIOS have the capability of managing P-states. But whitelists are ugly ... Comments? - naga - -------------------- On systems where the BIOS is capable of managing P-states, no relevant ACPI info (_PCT,_PSS etc.) is provided to the driver/OS. Avoid printing the "firmware bug" error messages in those cases. Signed-off-by: Naga Chumbalkar <nagananda.chumbalkar@xxxxxx> --- diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index a9df944..5712478 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -36,6 +36,7 @@ #include <linux/sched.h> /* for current / set_cpus_allowed() */ #include <linux/io.h> #include <linux/delay.h> +#include <linux/dmi.h> #include <asm/msr.h> @@ -1239,12 +1240,88 @@ static void __cpuinit powernowk8_cpu_init_on_cpu(void *_init_on_cpu) init_on_cpu->rc = 0; } +/* + * Some BIOSes may not present P-state related ACPI information + * to the OS/driver. + */ +static int bios_with_pstate_cap; + +static int bios_capability_found(const struct dmi_system_id *d) +{ + bios_with_pstate_cap = 1; + printk(KERN_INFO PFX "driver did not load because %s BIOS" + " has built-in pstate transitioning" + " capability\n", d->ident); + return 0; +} + +static const struct dmi_system_id bios_cap_dmi_table[] = { + { + .callback = bios_capability_found, + .ident = "HP ProLiant", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL365"), + }, + }, + { + .callback = bios_capability_found, + .ident = "HP ProLiant", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL385"), + }, + }, + { + .callback = bios_capability_found, + .ident = "HP ProLiant", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c"), + }, + }, + { + .callback = bios_capability_found, + .ident = "HP ProLiant", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL495c"), + }, + }, + { + .callback = bios_capability_found, + .ident = "HP ProLiant", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585"), + }, + }, + { + .callback = bios_capability_found, + .ident = "HP ProLiant", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c"), + }, + }, + { + .callback = bios_capability_found, + .ident = "HP ProLiant", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL785"), + }, + }, + { } +}; + /* per CPU init entry point to the driver */ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) { static const char ACPI_PSS_BIOS_BUG_MSG[] = KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n" FW_BUG PFX "Try again with latest BIOS.\n"; + static int done; struct powernow_k8_data *data; struct init_on_cpu init_on_cpu; int rc; @@ -1271,7 +1348,12 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) * an UP version, and is deprecated by AMD. */ if (num_online_cpus() != 1) { - printk_once(ACPI_PSS_BIOS_BUG_MSG); + if (!done) { + dmi_check_system(bios_cap_dmi_table); + done++; + } + if (!bios_with_pstate_cap) + printk_once(ACPI_PSS_BIOS_BUG_MSG); goto err_out; } if (pol->cpu != 0) { -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html