aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/pci/irq.c')
-rw-r--r--arch/x86/pci/irq.c54
1 files changed, 25 insertions, 29 deletions
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 373b9afe6d44..4064345cf144 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,
533{ 533{
534 struct pci_dev *bridge; 534 struct pci_dev *bridge;
535 int pin = pci_get_interrupt_pin(dev, &bridge); 535 int pin = pci_get_interrupt_pin(dev, &bridge);
536 return pcibios_set_irq_routing(bridge, pin, irq); 536 return pcibios_set_irq_routing(bridge, pin - 1, irq);
537} 537}
538 538
539#endif 539#endif
@@ -887,7 +887,6 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
887 dev_dbg(&dev->dev, "no interrupt pin\n"); 887 dev_dbg(&dev->dev, "no interrupt pin\n");
888 return 0; 888 return 0;
889 } 889 }
890 pin = pin - 1;
891 890
892 /* Find IRQ routing entry */ 891 /* Find IRQ routing entry */
893 892
@@ -897,17 +896,17 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
897 info = pirq_get_info(dev); 896 info = pirq_get_info(dev);
898 if (!info) { 897 if (!info) {
899 dev_dbg(&dev->dev, "PCI INT %c not found in routing table\n", 898 dev_dbg(&dev->dev, "PCI INT %c not found in routing table\n",
900 'A' + pin); 899 'A' + pin - 1);
901 return 0; 900 return 0;
902 } 901 }
903 pirq = info->irq[pin].link; 902 pirq = info->irq[pin - 1].link;
904 mask = info->irq[pin].bitmap; 903 mask = info->irq[pin - 1].bitmap;
905 if (!pirq) { 904 if (!pirq) {
906 dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + pin); 905 dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + pin - 1);
907 return 0; 906 return 0;
908 } 907 }
909 dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x", 908 dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x",
910 'A' + pin, pirq, mask, pirq_table->exclusive_irqs); 909 'A' + pin - 1, pirq, mask, pirq_table->exclusive_irqs);
911 mask &= pcibios_irq_mask; 910 mask &= pcibios_irq_mask;
912 911
913 /* Work around broken HP Pavilion Notebooks which assign USB to 912 /* 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)
949 newirq = i; 948 newirq = i;
950 } 949 }
951 } 950 }
952 dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin, newirq); 951 dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin - 1, newirq);
953 952
954 /* Check if it is hardcoded */ 953 /* Check if it is hardcoded */
955 if ((pirq & 0xf0) == 0xf0) { 954 if ((pirq & 0xf0) == 0xf0) {
@@ -977,18 +976,18 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
977 return 0; 976 return 0;
978 } 977 }
979 } 978 }
980 dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin, irq); 979 dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin - 1, irq);
981 980
982 /* Update IRQ for all devices with the same pirq value */ 981 /* Update IRQ for all devices with the same pirq value */
983 while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { 982 while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
984 pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin); 983 pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
985 if (!pin) 984 if (!pin)
986 continue; 985 continue;
987 pin--; 986
988 info = pirq_get_info(dev2); 987 info = pirq_get_info(dev2);
989 if (!info) 988 if (!info)
990 continue; 989 continue;
991 if (info->irq[pin].link == pirq) { 990 if (info->irq[pin - 1].link == pirq) {
992 /* 991 /*
993 * We refuse to override the dev->irq 992 * We refuse to override the dev->irq
994 * information. Give a warning! 993 * information. Give a warning!
@@ -1042,6 +1041,9 @@ static void __init pcibios_fixup_irqs(void)
1042 dev = NULL; 1041 dev = NULL;
1043 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 1042 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
1044 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 1043 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
1044 if (!pin)
1045 continue;
1046
1045#ifdef CONFIG_X86_IO_APIC 1047#ifdef CONFIG_X86_IO_APIC
1046 /* 1048 /*
1047 * Recalculate IRQ numbers if we use the I/O APIC. 1049 * Recalculate IRQ numbers if we use the I/O APIC.
@@ -1049,15 +1051,11 @@ static void __init pcibios_fixup_irqs(void)
1049 if (io_apic_assign_pci_irqs) { 1051 if (io_apic_assign_pci_irqs) {
1050 int irq; 1052 int irq;
1051 1053
1052 if (!pin)
1053 continue;
1054
1055 /* 1054 /*
1056 * interrupt pins are numbered starting from 1 1055 * interrupt pins are numbered starting from 1
1057 */ 1056 */
1058 pin--;
1059 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, 1057 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
1060 PCI_SLOT(dev->devfn), pin); 1058 PCI_SLOT(dev->devfn), pin - 1);
1061 /* 1059 /*
1062 * Busses behind bridges are typically not listed in the 1060 * Busses behind bridges are typically not listed in the
1063 * MP-table. In this case we have to look up the IRQ 1061 * MP-table. In this case we have to look up the IRQ
@@ -1070,22 +1068,22 @@ static void __init pcibios_fixup_irqs(void)
1070 struct pci_dev *bridge = dev->bus->self; 1068 struct pci_dev *bridge = dev->bus->self;
1071 int bus; 1069 int bus;
1072 1070
1073 pin = (pin + PCI_SLOT(dev->devfn)) % 4; 1071 pin = pci_swizzle_interrupt_pin(dev, pin);
1074 bus = bridge->bus->number; 1072 bus = bridge->bus->number;
1075 irq = IO_APIC_get_PCI_irq_vector(bus, 1073 irq = IO_APIC_get_PCI_irq_vector(bus,
1076 PCI_SLOT(bridge->devfn), pin); 1074 PCI_SLOT(bridge->devfn), pin - 1);
1077 if (irq >= 0) 1075 if (irq >= 0)
1078 dev_warn(&dev->dev, 1076 dev_warn(&dev->dev,
1079 "using bridge %s INT %c to " 1077 "using bridge %s INT %c to "
1080 "get IRQ %d\n", 1078 "get IRQ %d\n",
1081 pci_name(bridge), 1079 pci_name(bridge),
1082 'A' + pin, irq); 1080 'A' + pin - 1, irq);
1083 } 1081 }
1084 if (irq >= 0) { 1082 if (irq >= 0) {
1085 dev_info(&dev->dev, 1083 dev_info(&dev->dev,
1086 "PCI->APIC IRQ transform: INT %c " 1084 "PCI->APIC IRQ transform: INT %c "
1087 "-> IRQ %d\n", 1085 "-> IRQ %d\n",
1088 'A' + pin, irq); 1086 'A' + pin - 1, irq);
1089 dev->irq = irq; 1087 dev->irq = irq;
1090 } 1088 }
1091 } 1089 }
@@ -1093,7 +1091,7 @@ static void __init pcibios_fixup_irqs(void)
1093 /* 1091 /*
1094 * Still no IRQ? Try to lookup one... 1092 * Still no IRQ? Try to lookup one...
1095 */ 1093 */
1096 if (pin && !dev->irq) 1094 if (!dev->irq)
1097 pcibios_lookup_irq(dev, 0); 1095 pcibios_lookup_irq(dev, 0);
1098 } 1096 }
1099} 1097}
@@ -1220,12 +1218,10 @@ static int pirq_enable_irq(struct pci_dev *dev)
1220 if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { 1218 if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
1221 char *msg = ""; 1219 char *msg = "";
1222 1220
1223 pin--; /* interrupt pins are numbered starting from 1 */
1224
1225 if (io_apic_assign_pci_irqs) { 1221 if (io_apic_assign_pci_irqs) {
1226 int irq; 1222 int irq;
1227 1223
1228 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); 1224 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin - 1);
1229 /* 1225 /*
1230 * Busses behind bridges are typically not listed in the MP-table. 1226 * Busses behind bridges are typically not listed in the MP-table.
1231 * In this case we have to look up the IRQ based on the parent bus, 1227 * 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)
1236 while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ 1232 while (irq < 0 && dev->bus->parent) { /* go back to the bridge */
1237 struct pci_dev *bridge = dev->bus->self; 1233 struct pci_dev *bridge = dev->bus->self;
1238 1234
1239 pin = (pin + PCI_SLOT(dev->devfn)) % 4; 1235 pin = pci_swizzle_interrupt_pin(dev, pin);
1240 irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 1236 irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number,
1241 PCI_SLOT(bridge->devfn), pin); 1237 PCI_SLOT(bridge->devfn), pin - 1);
1242 if (irq >= 0) 1238 if (irq >= 0)
1243 dev_warn(&dev->dev, "using bridge %s " 1239 dev_warn(&dev->dev, "using bridge %s "
1244 "INT %c to get IRQ %d\n", 1240 "INT %c to get IRQ %d\n",
1245 pci_name(bridge), 'A' + pin, 1241 pci_name(bridge), 'A' + pin - 1,
1246 irq); 1242 irq);
1247 dev = bridge; 1243 dev = bridge;
1248 } 1244 }
1249 dev = temp_dev; 1245 dev = temp_dev;
1250 if (irq >= 0) { 1246 if (irq >= 0) {
1251 dev_info(&dev->dev, "PCI->APIC IRQ transform: " 1247 dev_info(&dev->dev, "PCI->APIC IRQ transform: "
1252 "INT %c -> IRQ %d\n", 'A' + pin, irq); 1248 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
1253 dev->irq = irq; 1249 dev->irq = irq;
1254 return 0; 1250 return 0;
1255 } else 1251 } else
@@ -1268,7 +1264,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
1268 return 0; 1264 return 0;
1269 1265
1270 dev_warn(&dev->dev, "can't find IRQ for PCI INT %c%s\n", 1266 dev_warn(&dev->dev, "can't find IRQ for PCI INT %c%s\n",
1271 'A' + pin, msg); 1267 'A' + pin - 1, msg);
1272 } 1268 }
1273 return 0; 1269 return 0;
1274} 1270}