diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 15:41:01 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 15:41:01 -0800 |
| commit | b424e8d3b438e841cd1700f6433a100a5d611e4a (patch) | |
| tree | 545638d0b925de4c7f740286760767cca86cb91e /arch/x86/pci/irq.c | |
| parent | 7c7758f99d39d529a64d4f60d22129bbf2f16d74 (diff) | |
| parent | f6dc1e5e3d4b523e1616b43beddb04e4fb1d376a (diff) | |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (98 commits)
PCI PM: Put PM callbacks in the order of execution
PCI PM: Run default PM callbacks for all devices using new framework
PCI PM: Register power state of devices during initialization
PCI PM: Call pci_fixup_device from legacy routines
PCI PM: Rearrange code in pci-driver.c
PCI PM: Avoid touching devices behind bridges in unknown state
PCI PM: Move pci_has_legacy_pm_support
PCI PM: Power-manage devices without drivers during suspend-resume
PCI PM: Add suspend counterpart of pci_reenable_device
PCI PM: Fix poweroff and restore callbacks
PCI: Use msleep instead of cpu_relax during ASPM link retraining
PCI: PCIe portdrv: Add kerneldoc comments to remining core funtions
PCI: PCIe portdrv: Rearrange code so that related things are together
PCI: PCIe portdrv: Fix suspend and resume of PCI Express port services
PCI: PCIe portdrv: Add kerneldoc comments to some core functions
x86/PCI: Do not use interrupt links for devices using MSI-X
net: sfc: Use pci_clear_master() to disable bus mastering
PCI: Add pci_clear_master() as opposite of pci_set_master()
PCI hotplug: remove redundant test in cpq hotplug
PCI: pciehp: cleanup register and field definitions
...
Diffstat (limited to 'arch/x86/pci/irq.c')
| -rw-r--r-- | arch/x86/pci/irq.c | 54 |
1 files changed, 25 insertions, 29 deletions
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 373b9afe6d4..4064345cf14 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -533,7 +533,7 @@ static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, { struct pci_dev *bridge; int pin = pci_get_interrupt_pin(dev, &bridge); - return pcibios_set_irq_routing(bridge, pin, irq); + return pcibios_set_irq_routing(bridge, pin - 1, irq); } #endif @@ -887,7 +887,6 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) dev_dbg(&dev->dev, "no interrupt pin\n"); return 0; } - pin = pin - 1; /* Find IRQ routing entry */ @@ -897,17 +896,17 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) info = pirq_get_info(dev); if (!info) { dev_dbg(&dev->dev, "PCI INT %c not found in routing table\n", - 'A' + pin); + 'A' + pin - 1); return 0; } - pirq = info->irq[pin].link; - mask = info->irq[pin].bitmap; + pirq = info->irq[pin - 1].link; + mask = info->irq[pin - 1].bitmap; if (!pirq) { - dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + pin); + dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + pin - 1); return 0; } dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x", - 'A' + pin, pirq, mask, pirq_table->exclusive_irqs); + 'A' + pin - 1, pirq, mask, pirq_table->exclusive_irqs); mask &= pcibios_irq_mask; /* Work around broken HP Pavilion Notebooks which assign USB to @@ -949,7 +948,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) newirq = i; } } - dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin, newirq); + dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin - 1, newirq); /* Check if it is hardcoded */ if ((pirq & 0xf0) == 0xf0) { @@ -977,18 +976,18 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) return 0; } } - dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin, irq); + dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin - 1, irq); /* Update IRQ for all devices with the same pirq value */ while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin); if (!pin) continue; - pin--; + info = pirq_get_info(dev2); if (!info) continue; - if (info->irq[pin].link == pirq) { + if (info->irq[pin - 1].link == pirq) { /* * We refuse to override the dev->irq * information. Give a warning! @@ -1042,6 +1041,9 @@ static void __init pcibios_fixup_irqs(void) dev = NULL; while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (!pin) + continue; + #ifdef CONFIG_X86_IO_APIC /* * Recalculate IRQ numbers if we use the I/O APIC. @@ -1049,15 +1051,11 @@ static void __init pcibios_fixup_irqs(void) if (io_apic_assign_pci_irqs) { int irq; - if (!pin) - continue; - /* * interrupt pins are numbered starting from 1 */ - pin--; irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, - PCI_SLOT(dev->devfn), pin); + PCI_SLOT(dev->devfn), pin - 1); /* * Busses behind bridges are typically not listed in the * MP-table. In this case we have to look up the IRQ @@ -1070,22 +1068,22 @@ static void __init pcibios_fixup_irqs(void) struct pci_dev *bridge = dev->bus->self; int bus; - pin = (pin + PCI_SLOT(dev->devfn)) % 4; + pin = pci_swizzle_interrupt_pin(dev, pin); bus = bridge->bus->number; irq = IO_APIC_get_PCI_irq_vector(bus, - PCI_SLOT(bridge->devfn), pin); + PCI_SLOT(bridge->devfn), pin - 1); if (irq >= 0) dev_warn(&dev->dev, "using bridge %s INT %c to " "get IRQ %d\n", pci_name(bridge), - 'A' + pin, irq); + 'A' + pin - 1, irq); } if (irq >= 0) { dev_info(&dev->dev, "PCI->APIC IRQ transform: INT %c " "-> IRQ %d\n", - 'A' + pin, irq); + 'A' + pin - 1, irq); dev->irq = irq; } } @@ -1093,7 +1091,7 @@ static void __init pcibios_fixup_irqs(void) /* * Still no IRQ? Try to lookup one... */ - if (pin && !dev->irq) + if (!dev->irq) pcibios_lookup_irq(dev, 0); } } @@ -1220,12 +1218,10 @@ static int pirq_enable_irq(struct pci_dev *dev) if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { char *msg = ""; - pin--; /* interrupt pins are numbered starting from 1 */ - if (io_apic_assign_pci_irqs) { int irq; - irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin - 1); /* * Busses behind bridges are typically not listed in the MP-table. * In this case we have to look up the IRQ based on the parent bus, @@ -1236,20 +1232,20 @@ static int pirq_enable_irq(struct pci_dev *dev) while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ struct pci_dev *bridge = dev->bus->self; - pin = (pin + PCI_SLOT(dev->devfn)) % 4; + pin = pci_swizzle_interrupt_pin(dev, pin); irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, - PCI_SLOT(bridge->devfn), pin); + PCI_SLOT(bridge->devfn), pin - 1); if (irq >= 0) dev_warn(&dev->dev, "using bridge %s " "INT %c to get IRQ %d\n", - pci_name(bridge), 'A' + pin, + pci_name(bridge), 'A' + pin - 1, irq); dev = bridge; } dev = temp_dev; if (irq >= 0) { dev_info(&dev->dev, "PCI->APIC IRQ transform: " - "INT %c -> IRQ %d\n", 'A' + pin, irq); + "INT %c -> IRQ %d\n", 'A' + pin - 1, irq); dev->irq = irq; return 0; } else @@ -1268,7 +1264,7 @@ static int pirq_enable_irq(struct pci_dev *dev) return 0; dev_warn(&dev->dev, "can't find IRQ for PCI INT %c%s\n", - 'A' + pin, msg); + 'A' + pin - 1, msg); } return 0; } |
