# 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.
