diff options
Diffstat (limited to 'arch/x86/pci/irq.c')
-rw-r--r-- | arch/x86/pci/irq.c | 86 |
1 files changed, 51 insertions, 35 deletions
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 8e077185e185..bf69dbe08bff 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -493,7 +493,7 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq | |||
493 | if (pirq <= 4) | 493 | if (pirq <= 4) |
494 | irq = read_config_nybble(router, 0x56, pirq - 1); | 494 | irq = read_config_nybble(router, 0x56, pirq - 1); |
495 | dev_info(&dev->dev, | 495 | dev_info(&dev->dev, |
496 | "AMD756: dev [%04x/%04x], router PIRQ %d get IRQ %d\n", | 496 | "AMD756: dev [%04x:%04x], router PIRQ %d get IRQ %d\n", |
497 | dev->vendor, dev->device, pirq, irq); | 497 | dev->vendor, dev->device, pirq, irq); |
498 | return irq; | 498 | return irq; |
499 | } | 499 | } |
@@ -501,7 +501,7 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq | |||
501 | static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | 501 | static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
502 | { | 502 | { |
503 | dev_info(&dev->dev, | 503 | dev_info(&dev->dev, |
504 | "AMD756: dev [%04x/%04x], router PIRQ %d set IRQ %d\n", | 504 | "AMD756: dev [%04x:%04x], router PIRQ %d set IRQ %d\n", |
505 | dev->vendor, dev->device, pirq, irq); | 505 | dev->vendor, dev->device, pirq, irq); |
506 | if (pirq <= 4) | 506 | if (pirq <= 4) |
507 | write_config_nybble(router, 0x56, pirq - 1, irq); | 507 | write_config_nybble(router, 0x56, pirq - 1, irq); |
@@ -590,13 +590,20 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
590 | case PCI_DEVICE_ID_INTEL_ICH10_1: | 590 | case PCI_DEVICE_ID_INTEL_ICH10_1: |
591 | case PCI_DEVICE_ID_INTEL_ICH10_2: | 591 | case PCI_DEVICE_ID_INTEL_ICH10_2: |
592 | case PCI_DEVICE_ID_INTEL_ICH10_3: | 592 | case PCI_DEVICE_ID_INTEL_ICH10_3: |
593 | case PCI_DEVICE_ID_INTEL_PCH_0: | ||
594 | case PCI_DEVICE_ID_INTEL_PCH_1: | ||
595 | r->name = "PIIX/ICH"; | 593 | r->name = "PIIX/ICH"; |
596 | r->get = pirq_piix_get; | 594 | r->get = pirq_piix_get; |
597 | r->set = pirq_piix_set; | 595 | r->set = pirq_piix_set; |
598 | return 1; | 596 | return 1; |
599 | } | 597 | } |
598 | |||
599 | if ((device >= PCI_DEVICE_ID_INTEL_PCH_LPC_MIN) && | ||
600 | (device <= PCI_DEVICE_ID_INTEL_PCH_LPC_MAX)) { | ||
601 | r->name = "PIIX/ICH"; | ||
602 | r->get = pirq_piix_get; | ||
603 | r->set = pirq_piix_set; | ||
604 | return 1; | ||
605 | } | ||
606 | |||
600 | return 0; | 607 | return 0; |
601 | } | 608 | } |
602 | 609 | ||
@@ -823,7 +830,7 @@ static void __init pirq_find_router(struct irq_router *r) | |||
823 | r->get = NULL; | 830 | r->get = NULL; |
824 | r->set = NULL; | 831 | r->set = NULL; |
825 | 832 | ||
826 | DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n", | 833 | DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n", |
827 | rt->rtr_vendor, rt->rtr_device); | 834 | rt->rtr_vendor, rt->rtr_device); |
828 | 835 | ||
829 | pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); | 836 | pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); |
@@ -843,7 +850,7 @@ static void __init pirq_find_router(struct irq_router *r) | |||
843 | h->probe(r, pirq_router_dev, pirq_router_dev->device)) | 850 | h->probe(r, pirq_router_dev, pirq_router_dev->device)) |
844 | break; | 851 | break; |
845 | } | 852 | } |
846 | dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x/%04x]\n", | 853 | dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n", |
847 | pirq_router.name, | 854 | pirq_router.name, |
848 | pirq_router_dev->vendor, pirq_router_dev->device); | 855 | pirq_router_dev->vendor, pirq_router_dev->device); |
849 | 856 | ||
@@ -1043,35 +1050,44 @@ static void __init pcibios_fixup_irqs(void) | |||
1043 | if (io_apic_assign_pci_irqs) { | 1050 | if (io_apic_assign_pci_irqs) { |
1044 | int irq; | 1051 | int irq; |
1045 | 1052 | ||
1046 | if (pin) { | 1053 | if (!pin) |
1047 | /* | 1054 | continue; |
1048 | * interrupt pins are numbered starting | 1055 | |
1049 | * from 1 | 1056 | /* |
1050 | */ | 1057 | * interrupt pins are numbered starting from 1 |
1051 | pin--; | 1058 | */ |
1052 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, | 1059 | pin--; |
1053 | PCI_SLOT(dev->devfn), pin); | 1060 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, |
1054 | /* | 1061 | PCI_SLOT(dev->devfn), pin); |
1055 | * Busses behind bridges are typically not listed in the MP-table. | 1062 | /* |
1056 | * In this case we have to look up the IRQ based on the parent bus, | 1063 | * Busses behind bridges are typically not listed in the |
1057 | * parent slot, and pin number. The SMP code detects such bridged | 1064 | * MP-table. In this case we have to look up the IRQ |
1058 | * busses itself so we should get into this branch reliably. | 1065 | * based on the parent bus, parent slot, and pin number. |
1059 | */ | 1066 | * The SMP code detects such bridged busses itself so we |
1060 | if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ | 1067 | * should get into this branch reliably. |
1061 | struct pci_dev *bridge = dev->bus->self; | 1068 | */ |
1062 | 1069 | if (irq < 0 && dev->bus->parent) { | |
1063 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; | 1070 | /* go back to the bridge */ |
1064 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1071 | struct pci_dev *bridge = dev->bus->self; |
1065 | PCI_SLOT(bridge->devfn), pin); | 1072 | int bus; |
1066 | if (irq >= 0) | 1073 | |
1067 | dev_warn(&dev->dev, "using bridge %s INT %c to get IRQ %d\n", | 1074 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; |
1068 | pci_name(bridge), | 1075 | bus = bridge->bus->number; |
1069 | 'A' + pin, irq); | 1076 | irq = IO_APIC_get_PCI_irq_vector(bus, |
1070 | } | 1077 | PCI_SLOT(bridge->devfn), pin); |
1071 | if (irq >= 0) { | 1078 | if (irq >= 0) |
1072 | dev_info(&dev->dev, "PCI->APIC IRQ transform: INT %c -> IRQ %d\n", 'A' + pin, irq); | 1079 | dev_warn(&dev->dev, |
1073 | dev->irq = irq; | 1080 | "using bridge %s INT %c to " |
1074 | } | 1081 | "get IRQ %d\n", |
1082 | pci_name(bridge), | ||
1083 | 'A' + pin, irq); | ||
1084 | } | ||
1085 | if (irq >= 0) { | ||
1086 | dev_info(&dev->dev, | ||
1087 | "PCI->APIC IRQ transform: INT %c " | ||
1088 | "-> IRQ %d\n", | ||
1089 | 'A' + pin, irq); | ||
1090 | dev->irq = irq; | ||
1075 | } | 1091 | } |
1076 | } | 1092 | } |
1077 | #endif | 1093 | #endif |