#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/dmi.h>
#include <asm/msr.h>
#include <asm/timex.h>
#include <asm/io.h>
#include <asm/system.h>
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
#include <linux/acpi.h>
#include <acpi/processor.h>
#endif
u8 numpstates;
};
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
union powernow_acpi_control_t {
struct {
unsigned long fid:5,
/* divide by 10 to get FID. */
static int fid_codes[32] = {
110, 115, 120, 125, 50, 55, 60, 65,
- 70, 75, 80, 85, 90, 95, 100, 105,
+ 70, 75, 80, 85, 90, 95, 100, 105,
30, 190, 40, 200, 130, 135, 140, 210,
150, 225, 160, 165, 170, 180, -1, -1,
};
* configuration purpose.
*/
-static int powernow_acpi_force;
+static int acpi_force;
static struct cpufreq_frequency_table *powernow_table;
}
cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+
+ /* Check we can actually do something before we say anything.*/
+ if (!(edx & (1 << 1 | 1 << 2)))
+ return 0;
+
printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
if (edx & 1 << 1) {
can_scale_vid=1;
}
- if (!(edx & (1 << 1 | 1 << 2))) {
- printk ("nothing.\n");
- return 0;
- }
-
printk (".\n");
return 1;
}
}
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
struct acpi_processor_performance *acpi_processor_perf;
}
+static int __init acer_cpufreq_pst(struct dmi_system_id *d)
+{
+ printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident);
+ printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
+ printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n");
+ return 0;
+}
+
+/*
+ * Some Athlon laptops have really fucked PST tables.
+ * A BIOS update is all that can save them.
+ * Mention this, and disable cpufreq.
+ */
+static struct dmi_system_id __initdata powernow_dmi_table[] = {
+ {
+ .callback = acer_cpufreq_pst,
+ .ident = "Acer Aspire",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"),
+ DMI_MATCH(DMI_BIOS_VERSION, "3A71"),
+ },
+ },
+ { }
+};
+
static int __init powernow_cpu_init (struct cpufreq_policy *policy)
{
union msr_fidvidstatus fidvidstatus;
}
dprintk(KERN_INFO PFX "FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000);
- if ((dmi_broken & BROKEN_CPUFREQ) || powernow_acpi_force) {
+ if (dmi_check_system(powernow_dmi_table) || acpi_force) {
printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n");
result = powernow_acpi_init();
} else {
static void __exit powernow_exit (void)
{
-#ifdef CONFIG_ACPI_PROCESSOR
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
if (acpi_processor_perf) {
acpi_processor_unregister_performance(acpi_processor_perf, 0);
kfree(acpi_processor_perf);
kfree(powernow_table);
}
-module_param(powernow_acpi_force, int, 0444);
-
+module_param(acpi_force, int, 0444);
MODULE_PARM_DESC(acpi_force, "Force ACPI to be used");
MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");