acpi/pci_link: Avoid sharing interrupt with SCI if possible
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 2 Apr 2011 11:15:04 +0000 (19:15 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 2 Apr 2011 11:20:06 +0000 (19:20 +0800)
Since ACPI SCI handler is time consuming, sharing its interrupt
with others may cause significant performance penalty.  SCI
interrupt is now shared if we can't find other resorts.

sys/dev/acpica5/acpi_pci_link.c

index b209b6c..3d6bbdc 100644 (file)
@@ -674,7 +674,13 @@ acpi_pci_link_add_reference(device_t dev, int index, device_t pcib, int slot,
                    bios_irq, (int)bus, slot, pin + 'A');
        } else if (!PCI_INTERRUPT_VALID(link->l_bios_irq)) {
                link->l_bios_irq = bios_irq;
-               if (bios_irq < NUM_ISA_INTERRUPTS)
+               /*
+                * Avoid sharing interrupt with SCI if possible,
+                * since ACPI interrupt handler is generally time
+                * consuming.
+                */
+               if (bios_irq < NUM_ISA_INTERRUPTS &&
+                   AcpiGbl_FADT.SciInterrupt != bios_irq)
                        pci_link_bios_isa_irqs |= (1 << bios_irq);
                if (bios_irq != link->l_initial_irq &&
                    PCI_INTERRUPT_VALID(link->l_initial_irq))
@@ -1019,10 +1025,9 @@ acpi_pci_link_choose_irq(device_t dev, struct link *link)
        }
 
        /*
-        * If this is an ISA IRQ, try using the SCI if it is also an ISA
-        * interrupt as a fallback.
+        * Check SCI as the last resort.
         */
-       if (link->l_isa_irq) {
+       if (link->l_isa_irq && !PCI_INTERRUPT_VALID(best_irq)) {
                pos_irq = AcpiGbl_FADT.SciInterrupt;
                pos_weight = pci_link_interrupt_weights[pos_irq];
                if (pos_weight < best_weight) {
@@ -1082,30 +1087,8 @@ acpi_pci_link_route_interrupt(device_t dev, int index)
        return (link->l_irq);
 }
 
-/*
- * This is gross, but we abuse the identify routine to perform one-time
- * SYSINIT() style initialization for the driver.
- */
-static void
-acpi_pci_link_identify(driver_t *driver, device_t parent)
-{
-
-       /*
-        * If the SCI is an ISA IRQ, add it to the bitmask of known good
-        * ISA IRQs.
-        *
-        * XXX: If we are using the APIC, the SCI might have been
-        * rerouted to an APIC pin in which case this is invalid.  However,
-        * if we are using the APIC, we also shouldn't be having any PCI
-        * interrupts routed via ISA IRQs, so this is probably ok.
-        */
-       if (AcpiGbl_FADT.SciInterrupt < NUM_ISA_INTERRUPTS)
-               pci_link_bios_isa_irqs |= (1 << AcpiGbl_FADT.SciInterrupt);
-}
-
 static device_method_t acpi_pci_link_methods[] = {
        /* Device interface */
-       DEVMETHOD(device_identify,      acpi_pci_link_identify),
        DEVMETHOD(device_probe,         acpi_pci_link_probe),
        DEVMETHOD(device_attach,        acpi_pci_link_attach),
        DEVMETHOD(device_resume,        acpi_pci_link_resume),