upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / arch / i386 / kernel / acpi / boot.c
index 8a05362..06976cc 100644 (file)
@@ -40,7 +40,7 @@
 #ifdef CONFIG_X86_64
 
 static inline void  acpi_madt_oem_check(char *oem_id, char *oem_table_id) { }
-static inline void clustered_apic_check(void) { }
+extern void __init clustered_apic_check(void);
 static inline int ioapic_setup_disabled(void) { return 0; }
 #include <asm/proto.h>
 
@@ -409,28 +409,38 @@ acpi_parse_nmi_src (
 void __init
 acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 {
-       unsigned char mask = 1 << (irq & 7);
-       unsigned int port = 0x4d0 + (irq >> 3);
-       unsigned char val = inb(port);
+       unsigned int mask = 1 << irq;
+       unsigned int old, new;
 
-       
-       printk(PREFIX "IRQ%d SCI:", irq);
-       if (!(val & mask)) {
-               printk(" Edge");
+       /* Real old ELCR mask */
+       old = inb(0x4d0) | (inb(0x4d1) << 8);
 
-               if (trigger == 3) {
-                       printk(" set to Level");
-                       outb(val | mask, port);
-               }
-       } else {
-               printk(" Level");
+       /*
+        * If we use ACPI to set PCI irq's, then we should clear ELCR
+        * since we will set it correctly as we enable the PCI irq
+        * routing.
+        */
+       new = acpi_noirq ? old : 0;
 
-               if (trigger == 1) {
-                       printk(" set to Edge");
-                       outb(val & ~mask, port);
-               }
+       /*
+        * Update SCI information in the ELCR, it isn't in the PCI
+        * routing tables..
+        */
+       switch (trigger) {
+       case 1: /* Edge - clear */
+               new &= ~mask;
+               break;
+       case 3: /* Level - set */
+               new |= mask;
+               break;
        }
-       printk(" Trigger.\n");
+
+       if (old == new)
+               return;
+
+       printk(PREFIX "setting ELCR to %04x (from %04x)\n", new, old);
+       outb(new, 0x4d0);
+       outb(new >> 8, 0x4d1);
 }
 
 
@@ -450,31 +460,26 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
 {
        unsigned int irq;
+       unsigned int plat_gsi = gsi;
 
 #ifdef CONFIG_PCI
        /*
         * Make sure all (legacy) PCI IRQs are set as level-triggered.
         */
        if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
-               static u16 irq_mask;
                extern void eisa_set_level_irq(unsigned int irq);
 
-               if (edge_level == ACPI_LEVEL_SENSITIVE) {
-                       if ((gsi < 16) && !((1 << gsi) & irq_mask)) {
-                               Dprintk(KERN_DEBUG PREFIX "Setting GSI %u as level-triggered\n", gsi);
-                               irq_mask |= (1 << gsi);
+               if (edge_level == ACPI_LEVEL_SENSITIVE)
                                eisa_set_level_irq(gsi);
-                       }
-               }
        }
 #endif
 
 #ifdef CONFIG_X86_IO_APIC
        if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
-               mp_register_gsi(gsi, edge_level, active_high_low);
+               plat_gsi = mp_register_gsi(gsi, edge_level, active_high_low);
        }
 #endif
-       acpi_gsi_to_irq(gsi, &irq);
+       acpi_gsi_to_irq(plat_gsi, &irq);
        return irq;
 }
 EXPORT_SYMBOL(acpi_register_gsi);
@@ -748,7 +753,7 @@ acpi_process_madt(void)
        int count, error;
 
        count = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
-       if (count == 1) {
+       if (count >= 1) {
 
                /*
                 * Parse MADT LAPIC entries
@@ -823,6 +828,10 @@ acpi_boot_init (void)
                return error;
        }
 
+#ifdef __i386__
+       check_acpi_pci();
+#endif
+
        acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
 
        /*