upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / drivers / acpi / pci_irq.c
index 23e9945..19f8011 100644 (file)
@@ -227,6 +227,11 @@ acpi_pci_irq_add_prt (
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
 
+/*
+ * acpi_pci_irq_lookup
+ * success: return IRQ >= 0
+ * failure: return -1
+ */
 static int
 acpi_pci_irq_lookup (
        struct pci_bus          *bus,
@@ -249,14 +254,14 @@ acpi_pci_irq_lookup (
        entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin); 
        if (!entry) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n"));
-               return_VALUE(0);
+               return_VALUE(-1);
        }
        
        if (entry->link.handle) {
                irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, edge_level, active_high_low);
-               if (!irq) {
+               if (irq < 0) {
                        ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
-                       return_VALUE(0);
+                       return_VALUE(-1);
                }
        } else {
                irq = entry->link.index;
@@ -269,6 +274,11 @@ acpi_pci_irq_lookup (
        return_VALUE(irq);
 }
 
+/*
+ * acpi_pci_irq_derive
+ * success: return IRQ >= 0
+ * failure: return < 0
+ */
 static int
 acpi_pci_irq_derive (
        struct pci_dev          *dev,
@@ -277,7 +287,7 @@ acpi_pci_irq_derive (
        int                     *active_high_low)
 {
        struct pci_dev          *bridge = dev;
-       int                     irq = 0;
+       int                     irq = -1;
        u8                      bridge_pin = 0;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_derive");
@@ -289,7 +299,7 @@ acpi_pci_irq_derive (
         * Attempt to derive an IRQ for this device from a parent bridge's
         * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
         */
-       while (!irq && bridge->bus->self) {
+       while (irq < 0 && bridge->bus->self) {
                pin = (pin + PCI_SLOT(bridge->devfn)) % 4;
                bridge = bridge->bus->self;
 
@@ -299,7 +309,7 @@ acpi_pci_irq_derive (
                        if (!bridge_pin) {
                                ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
                                        "No interrupt pin configured for device %s\n", pci_name(bridge)));
-                               return_VALUE(0);
+                               return_VALUE(-1);
                        }
                        /* Pin is from 0 to 3 */
                        bridge_pin --;
@@ -310,9 +320,9 @@ acpi_pci_irq_derive (
                        pin, edge_level, active_high_low);
        }
 
-       if (!irq) {
+       if (irq < 0) {
                ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to derive IRQ for device %s\n", pci_name(dev)));
-               return_VALUE(0);
+               return_VALUE(-1);
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n",
@@ -321,6 +331,11 @@ acpi_pci_irq_derive (
        return_VALUE(irq);
 }
 
+/*
+ * acpi_pci_irq_enable
+ * success: return 0
+ * failure: return < 0
+ */
 
 int
 acpi_pci_irq_enable (
@@ -330,6 +345,7 @@ acpi_pci_irq_enable (
        u8                      pin = 0;
        int                     edge_level = ACPI_LEVEL_SENSITIVE;
        int                     active_high_low = ACPI_ACTIVE_LOW;
+       extern int              via_interrupt_line_quirk;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
 
@@ -358,20 +374,20 @@ acpi_pci_irq_enable (
         * If no PRT entry was found, we'll try to derive an IRQ from the
         * device's parent bridge.
         */
-       if (!irq)
+       if (irq < 0)
                irq = acpi_pci_irq_derive(dev, pin, &edge_level, &active_high_low);
  
        /*
         * No IRQ known to the ACPI subsystem - maybe the BIOS / 
         * driver reported one, then use it. Exit in any case.
         */
-       if (!irq) {
+       if (irq < 0) {
                printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI",
                        pci_name(dev), ('A' + pin));
                /* Interrupt Line values above 0xF are forbidden */
-               if (dev->irq && (dev->irq <= 0xF)) {
+               if (dev->irq >= 0 && (dev->irq <= 0xF)) {
                        printk(" - using IRQ %d\n", dev->irq);
-                       return_VALUE(dev->irq);
+                       return_VALUE(0);
                }
                else {
                        printk("\n");
@@ -379,6 +395,9 @@ acpi_pci_irq_enable (
                }
        }
 
+       if (via_interrupt_line_quirk)
+               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15);
+
        dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
        printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI %u "
@@ -388,5 +407,7 @@ acpi_pci_irq_enable (
                (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high",
                dev->irq);
 
-       return_VALUE(dev->irq);
+       return_VALUE(0);
 }
+EXPORT_SYMBOL(acpi_pci_irq_enable);
+