diff options
-rw-r--r-- | arch/x86/pci/irq.c | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index fec0123b33a9..d781cc4f725a 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -1041,35 +1041,44 @@ static void __init pcibios_fixup_irqs(void) | |||
1041 | if (io_apic_assign_pci_irqs) { | 1041 | if (io_apic_assign_pci_irqs) { |
1042 | int irq; | 1042 | int irq; |
1043 | 1043 | ||
1044 | if (pin) { | 1044 | if (!pin) |
1045 | /* | 1045 | continue; |
1046 | * interrupt pins are numbered starting | 1046 | |
1047 | * from 1 | 1047 | /* |
1048 | */ | 1048 | * interrupt pins are numbered starting from 1 |
1049 | pin--; | 1049 | */ |
1050 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, | 1050 | pin--; |
1051 | PCI_SLOT(dev->devfn), pin); | 1051 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, |
1052 | /* | 1052 | PCI_SLOT(dev->devfn), pin); |
1053 | * Busses behind bridges are typically not listed in the MP-table. | 1053 | /* |
1054 | * In this case we have to look up the IRQ based on the parent bus, | 1054 | * Busses behind bridges are typically not listed in the |
1055 | * parent slot, and pin number. The SMP code detects such bridged | 1055 | * MP-table. In this case we have to look up the IRQ |
1056 | * busses itself so we should get into this branch reliably. | 1056 | * based on the parent bus, parent slot, and pin number. |
1057 | */ | 1057 | * The SMP code detects such bridged busses itself so we |
1058 | if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ | 1058 | * should get into this branch reliably. |
1059 | struct pci_dev *bridge = dev->bus->self; | 1059 | */ |
1060 | 1060 | if (irq < 0 && dev->bus->parent) { | |
1061 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; | 1061 | /* go back to the bridge */ |
1062 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1062 | struct pci_dev *bridge = dev->bus->self; |
1063 | PCI_SLOT(bridge->devfn), pin); | 1063 | int bus; |
1064 | if (irq >= 0) | 1064 | |
1065 | dev_warn(&dev->dev, "using bridge %s INT %c to get IRQ %d\n", | 1065 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; |
1066 | pci_name(bridge), | 1066 | bus = bridge->bus->number; |
1067 | 'A' + pin, irq); | 1067 | irq = IO_APIC_get_PCI_irq_vector(bus, |
1068 | } | 1068 | PCI_SLOT(bridge->devfn), pin); |
1069 | if (irq >= 0) { | 1069 | if (irq >= 0) |
1070 | dev_info(&dev->dev, "PCI->APIC IRQ transform: INT %c -> IRQ %d\n", 'A' + pin, irq); | 1070 | dev_warn(&dev->dev, |
1071 | dev->irq = irq; | 1071 | "using bridge %s INT %c to " |
1072 | } | 1072 | "get IRQ %d\n", |
1073 | pci_name(bridge), | ||
1074 | 'A' + pin, irq); | ||
1075 | } | ||
1076 | if (irq >= 0) { | ||
1077 | dev_info(&dev->dev, | ||
1078 | "PCI->APIC IRQ transform: INT %c " | ||
1079 | "-> IRQ %d\n", | ||
1080 | 'A' + pin, irq); | ||
1081 | dev->irq = irq; | ||
1073 | } | 1082 | } |
1074 | } | 1083 | } |
1075 | #endif | 1084 | #endif |