# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/04/01 05:07:54-05:00 len.brown@intel.com # [ACPI] PCI bridge interrupt fix (David Shaohua Li) # http://bugzilla.kernel.org/show_bug.cgi?id=2409 # # drivers/acpi/pci_irq.c # 2004/04/01 05:06:16-05:00 len.brown@intel.com +20 -15 # delete bad bridge interrupt fix # replace it with a specific fix for cardbus bridge # http://bugzilla.kernel.org/show_bug.cgi?id=2409 # diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c --- a/drivers/acpi/pci_irq.c Thu Apr 1 05:07:56 2004 +++ b/drivers/acpi/pci_irq.c Thu Apr 1 05:07:56 2004 @@ -277,11 +277,6 @@ return_VALUE(entry->irq); } -/* - * current thinking is that acpi_pci_irq_derive() adds no value - * and should be deleted, so warn if it actually does something. - */ - static int acpi_pci_irq_derive ( struct pci_dev *dev, @@ -289,6 +284,7 @@ { struct pci_dev *bridge = dev; int irq = 0; + u8 bridge_pin = 0; ACPI_FUNCTION_TRACE("acpi_pci_irq_derive"); @@ -297,12 +293,28 @@ /* * Attempt to derive an IRQ for this device from a parent bridge's - * PCI interrupt routing entry (a.k.a. the "bridge swizzle"). + * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge) */ while (!irq && bridge->bus->self) { pin = (pin + PCI_SLOT(bridge->devfn)) % 4; bridge = bridge->bus->self; - irq = acpi_pci_irq_lookup(0, bridge->bus->number, PCI_SLOT(bridge->devfn), pin); + + if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { + /* PC card has the same IRQ as its cardbridge */ + pci_read_config_byte(bridge, PCI_INTERRUPT_PIN, &bridge_pin); + if (!bridge_pin) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "No interrupt pin configured for device %s\n", + pci_name(bridge))); + return_VALUE(0); + } + /* Pin is from 0 to 3 */ + bridge_pin --; + pin = bridge_pin; + } + + irq = acpi_pci_irq_lookup(0, bridge->bus->number, + PCI_SLOT(bridge->devfn), pin); } if (!irq) { @@ -310,7 +322,7 @@ return_VALUE(0); } - ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Derive IRQ %d for device %s from %s\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n", irq, pci_name(dev), pci_name(bridge))); return_VALUE(irq); @@ -347,13 +359,6 @@ */ irq = acpi_pci_irq_lookup(0, dev->bus->number, PCI_SLOT(dev->devfn), pin); - /* - * Check if the device has an IRQ, - * Hotplug devices may get IRQs by scanning - */ - if (!irq && dev->irq) - irq = dev->irq; - /* * If no PRT entry was found, we'll try to derive an IRQ from the * device's parent bridge.