diff options
Diffstat (limited to 'arch/x86/pci/irq.c')
-rw-r--r-- | arch/x86/pci/irq.c | 176 |
1 files changed, 92 insertions, 84 deletions
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 6a06a2eb0597..bf69dbe08bff 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -436,7 +436,7 @@ static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
436 | { | 436 | { |
437 | WARN_ON_ONCE(pirq >= 9); | 437 | WARN_ON_ONCE(pirq >= 9); |
438 | if (pirq > 8) { | 438 | if (pirq > 8) { |
439 | printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); | 439 | dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq); |
440 | return 0; | 440 | return 0; |
441 | } | 441 | } |
442 | return read_config_nybble(router, 0x74, pirq-1); | 442 | return read_config_nybble(router, 0x74, pirq-1); |
@@ -446,7 +446,7 @@ static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, | |||
446 | { | 446 | { |
447 | WARN_ON_ONCE(pirq >= 9); | 447 | WARN_ON_ONCE(pirq >= 9); |
448 | if (pirq > 8) { | 448 | if (pirq > 8) { |
449 | printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); | 449 | dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq); |
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | write_config_nybble(router, 0x74, pirq-1, irq); | 452 | write_config_nybble(router, 0x74, pirq-1, irq); |
@@ -492,15 +492,17 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq | |||
492 | irq = 0; | 492 | irq = 0; |
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 | printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n", | 495 | dev_info(&dev->dev, |
496 | dev->vendor, dev->device, pirq, irq); | 496 | "AMD756: dev [%04x:%04x], router PIRQ %d get IRQ %d\n", |
497 | dev->vendor, dev->device, pirq, irq); | ||
497 | return irq; | 498 | return irq; |
498 | } | 499 | } |
499 | 500 | ||
500 | 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) |
501 | { | 502 | { |
502 | printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", | 503 | dev_info(&dev->dev, |
503 | dev->vendor, dev->device, pirq, irq); | 504 | "AMD756: dev [%04x:%04x], router PIRQ %d set IRQ %d\n", |
505 | dev->vendor, dev->device, pirq, irq); | ||
504 | if (pirq <= 4) | 506 | if (pirq <= 4) |
505 | write_config_nybble(router, 0x56, pirq - 1, irq); | 507 | write_config_nybble(router, 0x56, pirq - 1, irq); |
506 | return 1; | 508 | return 1; |
@@ -593,6 +595,15 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
593 | r->set = pirq_piix_set; | 595 | r->set = pirq_piix_set; |
594 | return 1; | 596 | return 1; |
595 | } | 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 | |||
596 | return 0; | 607 | return 0; |
597 | } | 608 | } |
598 | 609 | ||
@@ -730,7 +741,6 @@ static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, | |||
730 | switch (device) { | 741 | switch (device) { |
731 | case PCI_DEVICE_ID_AL_M1533: | 742 | case PCI_DEVICE_ID_AL_M1533: |
732 | case PCI_DEVICE_ID_AL_M1563: | 743 | case PCI_DEVICE_ID_AL_M1563: |
733 | printk(KERN_DEBUG "PCI: Using ALI IRQ Router\n"); | ||
734 | r->name = "ALI"; | 744 | r->name = "ALI"; |
735 | r->get = pirq_ali_get; | 745 | r->get = pirq_ali_get; |
736 | r->set = pirq_ali_set; | 746 | r->set = pirq_ali_set; |
@@ -820,7 +830,7 @@ static void __init pirq_find_router(struct irq_router *r) | |||
820 | r->get = NULL; | 830 | r->get = NULL; |
821 | r->set = NULL; | 831 | r->set = NULL; |
822 | 832 | ||
823 | 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", |
824 | rt->rtr_vendor, rt->rtr_device); | 834 | rt->rtr_vendor, rt->rtr_device); |
825 | 835 | ||
826 | 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); |
@@ -840,11 +850,9 @@ static void __init pirq_find_router(struct irq_router *r) | |||
840 | h->probe(r, pirq_router_dev, pirq_router_dev->device)) | 850 | h->probe(r, pirq_router_dev, pirq_router_dev->device)) |
841 | break; | 851 | break; |
842 | } | 852 | } |
843 | printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n", | 853 | dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n", |
844 | pirq_router.name, | 854 | pirq_router.name, |
845 | pirq_router_dev->vendor, | 855 | pirq_router_dev->vendor, pirq_router_dev->device); |
846 | pirq_router_dev->device, | ||
847 | pci_name(pirq_router_dev)); | ||
848 | 856 | ||
849 | /* The device remains referenced for the kernel lifetime */ | 857 | /* The device remains referenced for the kernel lifetime */ |
850 | } | 858 | } |
@@ -877,7 +885,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
877 | /* Find IRQ pin */ | 885 | /* Find IRQ pin */ |
878 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | 886 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
879 | if (!pin) { | 887 | if (!pin) { |
880 | DBG(KERN_DEBUG " -> no interrupt pin\n"); | 888 | dev_dbg(&dev->dev, "no interrupt pin\n"); |
881 | return 0; | 889 | return 0; |
882 | } | 890 | } |
883 | pin = pin - 1; | 891 | pin = pin - 1; |
@@ -887,20 +895,20 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
887 | if (!pirq_table) | 895 | if (!pirq_table) |
888 | return 0; | 896 | return 0; |
889 | 897 | ||
890 | DBG(KERN_DEBUG "IRQ for %s[%c]", pci_name(dev), 'A' + pin); | ||
891 | info = pirq_get_info(dev); | 898 | info = pirq_get_info(dev); |
892 | if (!info) { | 899 | if (!info) { |
893 | DBG(" -> not found in routing table\n" KERN_DEBUG); | 900 | dev_dbg(&dev->dev, "PCI INT %c not found in routing table\n", |
901 | 'A' + pin); | ||
894 | return 0; | 902 | return 0; |
895 | } | 903 | } |
896 | pirq = info->irq[pin].link; | 904 | pirq = info->irq[pin].link; |
897 | mask = info->irq[pin].bitmap; | 905 | mask = info->irq[pin].bitmap; |
898 | if (!pirq) { | 906 | if (!pirq) { |
899 | DBG(" -> not routed\n" KERN_DEBUG); | 907 | dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + pin); |
900 | return 0; | 908 | return 0; |
901 | } | 909 | } |
902 | DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, | 910 | dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x", |
903 | pirq_table->exclusive_irqs); | 911 | 'A' + pin, pirq, mask, pirq_table->exclusive_irqs); |
904 | mask &= pcibios_irq_mask; | 912 | mask &= pcibios_irq_mask; |
905 | 913 | ||
906 | /* Work around broken HP Pavilion Notebooks which assign USB to | 914 | /* Work around broken HP Pavilion Notebooks which assign USB to |
@@ -930,10 +938,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
930 | if (pci_probe & PCI_USE_PIRQ_MASK) | 938 | if (pci_probe & PCI_USE_PIRQ_MASK) |
931 | newirq = 0; | 939 | newirq = 0; |
932 | else | 940 | else |
933 | printk("\n" KERN_WARNING | 941 | dev_warn(&dev->dev, "IRQ %d doesn't match PIRQ mask " |
934 | "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n" | 942 | "%#x; try pci=usepirqmask\n", newirq, mask); |
935 | KERN_DEBUG, newirq, | ||
936 | pci_name(dev)); | ||
937 | } | 943 | } |
938 | if (!newirq && assign) { | 944 | if (!newirq && assign) { |
939 | for (i = 0; i < 16; i++) { | 945 | for (i = 0; i < 16; i++) { |
@@ -944,39 +950,35 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
944 | newirq = i; | 950 | newirq = i; |
945 | } | 951 | } |
946 | } | 952 | } |
947 | DBG(" -> newirq=%d", newirq); | 953 | dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin, newirq); |
948 | 954 | ||
949 | /* Check if it is hardcoded */ | 955 | /* Check if it is hardcoded */ |
950 | if ((pirq & 0xf0) == 0xf0) { | 956 | if ((pirq & 0xf0) == 0xf0) { |
951 | irq = pirq & 0xf; | 957 | irq = pirq & 0xf; |
952 | DBG(" -> hardcoded IRQ %d\n", irq); | 958 | msg = "hardcoded"; |
953 | msg = "Hardcoded"; | ||
954 | } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \ | 959 | } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \ |
955 | ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask))) { | 960 | ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask))) { |
956 | DBG(" -> got IRQ %d\n", irq); | 961 | msg = "found"; |
957 | msg = "Found"; | ||
958 | eisa_set_level_irq(irq); | 962 | eisa_set_level_irq(irq); |
959 | } else if (newirq && r->set && | 963 | } else if (newirq && r->set && |
960 | (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { | 964 | (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { |
961 | DBG(" -> assigning IRQ %d", newirq); | ||
962 | if (r->set(pirq_router_dev, dev, pirq, newirq)) { | 965 | if (r->set(pirq_router_dev, dev, pirq, newirq)) { |
963 | eisa_set_level_irq(newirq); | 966 | eisa_set_level_irq(newirq); |
964 | DBG(" ... OK\n"); | 967 | msg = "assigned"; |
965 | msg = "Assigned"; | ||
966 | irq = newirq; | 968 | irq = newirq; |
967 | } | 969 | } |
968 | } | 970 | } |
969 | 971 | ||
970 | if (!irq) { | 972 | if (!irq) { |
971 | DBG(" ... failed\n"); | ||
972 | if (newirq && mask == (1 << newirq)) { | 973 | if (newirq && mask == (1 << newirq)) { |
973 | msg = "Guessed"; | 974 | msg = "guessed"; |
974 | irq = newirq; | 975 | irq = newirq; |
975 | } else | 976 | } else { |
977 | dev_dbg(&dev->dev, "can't route interrupt\n"); | ||
976 | return 0; | 978 | return 0; |
979 | } | ||
977 | } | 980 | } |
978 | printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, | 981 | dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin, irq); |
979 | pci_name(dev)); | ||
980 | 982 | ||
981 | /* Update IRQ for all devices with the same pirq value */ | 983 | /* Update IRQ for all devices with the same pirq value */ |
982 | while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { | 984 | while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { |
@@ -996,17 +998,17 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
996 | (!(pci_probe & PCI_USE_PIRQ_MASK) || \ | 998 | (!(pci_probe & PCI_USE_PIRQ_MASK) || \ |
997 | ((1 << dev2->irq) & mask))) { | 999 | ((1 << dev2->irq) & mask))) { |
998 | #ifndef CONFIG_PCI_MSI | 1000 | #ifndef CONFIG_PCI_MSI |
999 | printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n", | 1001 | dev_info(&dev2->dev, "IRQ routing conflict: " |
1000 | pci_name(dev2), dev2->irq, irq); | 1002 | "have IRQ %d, want IRQ %d\n", |
1003 | dev2->irq, irq); | ||
1001 | #endif | 1004 | #endif |
1002 | continue; | 1005 | continue; |
1003 | } | 1006 | } |
1004 | dev2->irq = irq; | 1007 | dev2->irq = irq; |
1005 | pirq_penalty[irq]++; | 1008 | pirq_penalty[irq]++; |
1006 | if (dev != dev2) | 1009 | if (dev != dev2) |
1007 | printk(KERN_INFO | 1010 | dev_info(&dev->dev, "sharing IRQ %d with %s\n", |
1008 | "PCI: Sharing IRQ %d with %s\n", | 1011 | irq, pci_name(dev2)); |
1009 | irq, pci_name(dev2)); | ||
1010 | } | 1012 | } |
1011 | } | 1013 | } |
1012 | return 1; | 1014 | return 1; |
@@ -1025,8 +1027,7 @@ static void __init pcibios_fixup_irqs(void) | |||
1025 | * already in use. | 1027 | * already in use. |
1026 | */ | 1028 | */ |
1027 | if (dev->irq >= 16) { | 1029 | if (dev->irq >= 16) { |
1028 | DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n", | 1030 | dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", dev->irq); |
1029 | pci_name(dev), dev->irq); | ||
1030 | dev->irq = 0; | 1031 | dev->irq = 0; |
1031 | } | 1032 | } |
1032 | /* | 1033 | /* |
@@ -1049,35 +1050,44 @@ static void __init pcibios_fixup_irqs(void) | |||
1049 | if (io_apic_assign_pci_irqs) { | 1050 | if (io_apic_assign_pci_irqs) { |
1050 | int irq; | 1051 | int irq; |
1051 | 1052 | ||
1052 | if (pin) { | 1053 | if (!pin) |
1053 | /* | 1054 | continue; |
1054 | * interrupt pins are numbered starting | 1055 | |
1055 | * from 1 | 1056 | /* |
1056 | */ | 1057 | * interrupt pins are numbered starting from 1 |
1057 | pin--; | 1058 | */ |
1058 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, | 1059 | pin--; |
1059 | PCI_SLOT(dev->devfn), pin); | 1060 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, |
1060 | /* | 1061 | PCI_SLOT(dev->devfn), pin); |
1061 | * Busses behind bridges are typically not listed in the MP-table. | 1062 | /* |
1062 | * 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 |
1063 | * parent slot, and pin number. The SMP code detects such bridged | 1064 | * MP-table. In this case we have to look up the IRQ |
1064 | * busses itself so we should get into this branch reliably. | 1065 | * based on the parent bus, parent slot, and pin number. |
1065 | */ | 1066 | * The SMP code detects such bridged busses itself so we |
1066 | if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ | 1067 | * should get into this branch reliably. |
1067 | struct pci_dev *bridge = dev->bus->self; | 1068 | */ |
1068 | 1069 | if (irq < 0 && dev->bus->parent) { | |
1069 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; | 1070 | /* go back to the bridge */ |
1070 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1071 | struct pci_dev *bridge = dev->bus->self; |
1071 | PCI_SLOT(bridge->devfn), pin); | 1072 | int bus; |
1072 | if (irq >= 0) | 1073 | |
1073 | printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n", | 1074 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; |
1074 | pci_name(bridge), 'A' + pin, irq); | 1075 | bus = bridge->bus->number; |
1075 | } | 1076 | irq = IO_APIC_get_PCI_irq_vector(bus, |
1076 | if (irq >= 0) { | 1077 | PCI_SLOT(bridge->devfn), pin); |
1077 | printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", | 1078 | if (irq >= 0) |
1078 | pci_name(dev), 'A' + pin, irq); | 1079 | dev_warn(&dev->dev, |
1079 | dev->irq = irq; | 1080 | "using bridge %s INT %c to " |
1080 | } | 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; | ||
1081 | } | 1091 | } |
1082 | } | 1092 | } |
1083 | #endif | 1093 | #endif |
@@ -1231,25 +1241,24 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1231 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1241 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, |
1232 | PCI_SLOT(bridge->devfn), pin); | 1242 | PCI_SLOT(bridge->devfn), pin); |
1233 | if (irq >= 0) | 1243 | if (irq >= 0) |
1234 | printk(KERN_WARNING | 1244 | dev_warn(&dev->dev, "using bridge %s " |
1235 | "PCI: using PPB %s[%c] to get irq %d\n", | 1245 | "INT %c to get IRQ %d\n", |
1236 | pci_name(bridge), | 1246 | pci_name(bridge), 'A' + pin, |
1237 | 'A' + pin, irq); | 1247 | irq); |
1238 | dev = bridge; | 1248 | dev = bridge; |
1239 | } | 1249 | } |
1240 | dev = temp_dev; | 1250 | dev = temp_dev; |
1241 | if (irq >= 0) { | 1251 | if (irq >= 0) { |
1242 | printk(KERN_INFO | 1252 | dev_info(&dev->dev, "PCI->APIC IRQ transform: " |
1243 | "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", | 1253 | "INT %c -> IRQ %d\n", 'A' + pin, irq); |
1244 | pci_name(dev), 'A' + pin, irq); | ||
1245 | dev->irq = irq; | 1254 | dev->irq = irq; |
1246 | return 0; | 1255 | return 0; |
1247 | } else | 1256 | } else |
1248 | msg = " Probably buggy MP table."; | 1257 | msg = "; probably buggy MP table"; |
1249 | } else if (pci_probe & PCI_BIOS_IRQ_SCAN) | 1258 | } else if (pci_probe & PCI_BIOS_IRQ_SCAN) |
1250 | msg = ""; | 1259 | msg = ""; |
1251 | else | 1260 | else |
1252 | msg = " Please try using pci=biosirq."; | 1261 | msg = "; please try using pci=biosirq"; |
1253 | 1262 | ||
1254 | /* | 1263 | /* |
1255 | * With IDE legacy devices the IRQ lookup failure is not | 1264 | * With IDE legacy devices the IRQ lookup failure is not |
@@ -1259,9 +1268,8 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1259 | !(dev->class & 0x5)) | 1268 | !(dev->class & 0x5)) |
1260 | return 0; | 1269 | return 0; |
1261 | 1270 | ||
1262 | printk(KERN_WARNING | 1271 | dev_warn(&dev->dev, "can't find IRQ for PCI INT %c%s\n", |
1263 | "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", | 1272 | 'A' + pin, msg); |
1264 | 'A' + pin, pci_name(dev), msg); | ||
1265 | } | 1273 | } |
1266 | return 0; | 1274 | return 0; |
1267 | } | 1275 | } |