[CPUFREQ] Longhaul - Workaround issues with APIC.
authorRafa³ Bilski <rafalbilski@interia.pl>
Tue, 4 Jul 2006 15:50:57 +0000 (17:50 +0200)
committerDave Jones <davej@redhat.com>
Mon, 31 Jul 2006 22:37:05 +0000 (18:37 -0400)
There is no need to worry about local APIC.
There is need to worry about I/O APIC, because I/O APIC
is replacing good old 8259. According to Nehemiah datasheet VIA is
using 3-wire bus to connect local APIC to I/O APIC.

"[...] When IA32_APIC_BASE[11] is set to 0, processor APICs based on the 3-wire APIC
 bus cannot be generally re-enabled until a system hardware reset. The 3-wire bus
 looses track of arbitration that would be necessary for complete re-enabling. Certain
 (local) APIC functionality can be enabled. [...]"

So we must set disable bit for each interrupt in I/O APIC registers.
Same situation as for PIC - we must poke registers direcly.
How to do this? I don't know. So at the moment it is better to fail.

Signed-off-by: Rafa³ Bilski <rafalbilski@interia.pl>
Signed-off-by: Dave Jones <davej@redhat.com>
arch/i386/kernel/cpu/cpufreq/longhaul.c

index d735cb460612a954b913a50b2aa4730635ec17ac..dfd243f497b2da5c36f190382ab78ffc5b024750 100644 (file)
@@ -688,6 +688,18 @@ static int __init longhaul_init(void)
        if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
                return -ENODEV;
 
+#ifdef CONFIG_SMP
+       if (num_online_cpus() > 1) {
+               return -ENODEV;
+               printk(KERN_ERR PFX "More than 1 CPU detected, longhaul disabled.\n");
+       }
+#endif
+#ifdef CONFIG_X86_IO_APIC
+       if (cpu_has_apic) {
+               printk(KERN_ERR PFX "APIC detected. Longhaul is currently broken in this configuration.\n");
+               return -ENODEV;
+       }
+#endif
        switch (c->x86_model) {
        case 6 ... 9:
                return cpufreq_register_driver(&longhaul_driver);