aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2009-05-06 13:10:06 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-11 04:35:10 -0400
commitb9c61b70075c87a8612624736faf4a2de5b1ed30 (patch)
tree40f4ae74461d20be77b4b260e5384fe937bc5bec
parent5ef2183768bb7d64b85eccbfa1537a61cbefa97c (diff)
x86/pci: update pirq_enable_irq() to setup io apic routing
So we can set io apic routing only when enabling the device irq. This is advantageous for IRQ descriptor allocation affinity: if we set up the IO-APIC entry later, we have a chance to allocate the IRQ descriptor later and know which device it is on and can set affinity accordingly. [ Impact: standardize/enhance irq-enabling sequence for mptable irqs ] Signed-off-by: Yinghai Lu <yinghai@kernel.org> Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Len Brown <lenb@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> LKML-Reference: <4A01C46E.8000501@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/apic/io_apic.c150
-rw-r--r--arch/x86/pci/irq.c84
2 files changed, 104 insertions, 130 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 3a68daee0d99..5d5f4120c743 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1480,9 +1480,13 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
1480 ioapic_write_entry(apic_id, pin, entry); 1480 ioapic_write_entry(apic_id, pin, entry);
1481} 1481}
1482 1482
1483static struct {
1484 DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
1485} mp_ioapic_routing[MAX_IO_APICS];
1486
1483static void __init setup_IO_APIC_irqs(void) 1487static void __init setup_IO_APIC_irqs(void)
1484{ 1488{
1485 int apic_id, pin, idx, irq; 1489 int apic_id = 0, pin, idx, irq;
1486 int notcon = 0; 1490 int notcon = 0;
1487 struct irq_desc *desc; 1491 struct irq_desc *desc;
1488 struct irq_cfg *cfg; 1492 struct irq_cfg *cfg;
@@ -1490,48 +1494,53 @@ static void __init setup_IO_APIC_irqs(void)
1490 1494
1491 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); 1495 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
1492 1496
1493 for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { 1497#ifdef CONFIG_ACPI
1494 for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { 1498 if (!acpi_disabled && acpi_ioapic) {
1495 1499 apic_id = mp_find_ioapic(0);
1496 idx = find_irq_entry(apic_id, pin, mp_INT); 1500 if (apic_id < 0)
1497 if (idx == -1) { 1501 apic_id = 0;
1498 if (!notcon) { 1502 }
1499 notcon = 1; 1503#endif
1500 apic_printk(APIC_VERBOSE,
1501 KERN_DEBUG " %d-%d",
1502 mp_ioapics[apic_id].apicid, pin);
1503 } else
1504 apic_printk(APIC_VERBOSE, " %d-%d",
1505 mp_ioapics[apic_id].apicid, pin);
1506 continue;
1507 }
1508 if (notcon) {
1509 apic_printk(APIC_VERBOSE,
1510 " (apicid-pin) not connected\n");
1511 notcon = 0;
1512 }
1513 1504
1514 irq = pin_2_irq(idx, apic_id, pin); 1505 for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
1506 idx = find_irq_entry(apic_id, pin, mp_INT);
1507 if (idx == -1) {
1508 if (!notcon) {
1509 notcon = 1;
1510 apic_printk(APIC_VERBOSE,
1511 KERN_DEBUG " %d-%d",
1512 mp_ioapics[apic_id].apicid, pin);
1513 } else
1514 apic_printk(APIC_VERBOSE, " %d-%d",
1515 mp_ioapics[apic_id].apicid, pin);
1516 continue;
1517 }
1518 if (notcon) {
1519 apic_printk(APIC_VERBOSE,
1520 " (apicid-pin) not connected\n");
1521 notcon = 0;
1522 }
1515 1523
1516 /* 1524 irq = pin_2_irq(idx, apic_id, pin);
1517 * Skip the timer IRQ if there's a quirk handler
1518 * installed and if it returns 1:
1519 */
1520 if (apic->multi_timer_check &&
1521 apic->multi_timer_check(apic_id, irq))
1522 continue;
1523 1525
1524 desc = irq_to_desc_alloc_node(irq, node); 1526 /*
1525 if (!desc) { 1527 * Skip the timer IRQ if there's a quirk handler
1526 printk(KERN_INFO "can not get irq_desc for %d\n", irq); 1528 * installed and if it returns 1:
1527 continue; 1529 */
1528 } 1530 if (apic->multi_timer_check &&
1529 cfg = desc->chip_data; 1531 apic->multi_timer_check(apic_id, irq))
1530 add_pin_to_irq_node(cfg, node, apic_id, pin); 1532 continue;
1531 1533
1532 setup_IO_APIC_irq(apic_id, pin, irq, desc, 1534 desc = irq_to_desc_alloc_node(irq, node);
1533 irq_trigger(idx), irq_polarity(idx)); 1535 if (!desc) {
1536 printk(KERN_INFO "can not get irq_desc for %d\n", irq);
1537 continue;
1534 } 1538 }
1539 cfg = desc->chip_data;
1540 add_pin_to_irq_node(cfg, node, apic_id, pin);
1541 set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
1542 setup_IO_APIC_irq(apic_id, pin, irq, desc,
1543 irq_trigger(idx), irq_polarity(idx));
1535 } 1544 }
1536 1545
1537 if (notcon) 1546 if (notcon)
@@ -3876,10 +3885,6 @@ static int __io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, in
3876 return 0; 3885 return 0;
3877} 3886}
3878 3887
3879static struct {
3880 DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
3881} mp_ioapic_routing[MAX_IO_APICS];
3882
3883int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq, 3888int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
3884 int triggering, int polarity) 3889 int triggering, int polarity)
3885{ 3890{
@@ -4023,51 +4028,44 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
4023#ifdef CONFIG_SMP 4028#ifdef CONFIG_SMP
4024void __init setup_ioapic_dest(void) 4029void __init setup_ioapic_dest(void)
4025{ 4030{
4026 int pin, ioapic, irq, irq_entry; 4031 int pin, ioapic = 0, irq, irq_entry;
4027 struct irq_desc *desc; 4032 struct irq_desc *desc;
4028 struct irq_cfg *cfg;
4029 const struct cpumask *mask; 4033 const struct cpumask *mask;
4030 4034
4031 if (skip_ioapic_setup == 1) 4035 if (skip_ioapic_setup == 1)
4032 return; 4036 return;
4033 4037
4034 for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { 4038#ifdef CONFIG_ACPI
4035 for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { 4039 if (!acpi_disabled && acpi_ioapic) {
4036 irq_entry = find_irq_entry(ioapic, pin, mp_INT); 4040 ioapic = mp_find_ioapic(0);
4037 if (irq_entry == -1) 4041 if (ioapic < 0)
4038 continue; 4042 ioapic = 0;
4039 irq = pin_2_irq(irq_entry, ioapic, pin); 4043 }
4040 4044#endif
4041 /* setup_IO_APIC_irqs could fail to get vector for some device
4042 * when you have too many devices, because at that time only boot
4043 * cpu is online.
4044 */
4045 desc = irq_to_desc(irq);
4046 cfg = desc->chip_data;
4047 if (!cfg->vector) {
4048 setup_IO_APIC_irq(ioapic, pin, irq, desc,
4049 irq_trigger(irq_entry),
4050 irq_polarity(irq_entry));
4051 continue;
4052 4045
4053 } 4046 for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
4047 irq_entry = find_irq_entry(ioapic, pin, mp_INT);
4048 if (irq_entry == -1)
4049 continue;
4050 irq = pin_2_irq(irq_entry, ioapic, pin);
4054 4051
4055 /* 4052 desc = irq_to_desc(irq);
4056 * Honour affinities which have been set in early boot
4057 */
4058 if (desc->status &
4059 (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
4060 mask = desc->affinity;
4061 else
4062 mask = apic->target_cpus();
4063 4053
4064 if (intr_remapping_enabled) 4054 /*
4065 set_ir_ioapic_affinity_irq_desc(desc, mask); 4055 * Honour affinities which have been set in early boot
4066 else 4056 */
4067 set_ioapic_affinity_irq_desc(desc, mask); 4057 if (desc->status &
4068 } 4058 (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
4059 mask = desc->affinity;
4060 else
4061 mask = apic->target_cpus();
4069 4062
4063 if (intr_remapping_enabled)
4064 set_ir_ioapic_affinity_irq_desc(desc, mask);
4065 else
4066 set_ioapic_affinity_irq_desc(desc, mask);
4070 } 4067 }
4068
4071} 4069}
4072#endif 4070#endif
4073 4071
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index a2f6bde9c4eb..2f3e192615c0 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
889 return 0; 889 return 0;
890 } 890 }
891 891
892 if (io_apic_assign_pci_irqs)
893 return 0;
894
892 /* Find IRQ routing entry */ 895 /* Find IRQ routing entry */
893 896
894 if (!pirq_table) 897 if (!pirq_table)
@@ -1039,63 +1042,15 @@ static void __init pcibios_fixup_irqs(void)
1039 pirq_penalty[dev->irq]++; 1042 pirq_penalty[dev->irq]++;
1040 } 1043 }
1041 1044
1045 if (io_apic_assign_pci_irqs)
1046 return;
1047
1042 dev = NULL; 1048 dev = NULL;
1043 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 1049 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
1044 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 1050 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
1045 if (!pin) 1051 if (!pin)
1046 continue; 1052 continue;
1047 1053
1048#ifdef CONFIG_X86_IO_APIC
1049 /*
1050 * Recalculate IRQ numbers if we use the I/O APIC.
1051 */
1052 if (io_apic_assign_pci_irqs) {
1053 int irq;
1054 int ioapic = -1, ioapic_pin = -1;
1055 int triggering, polarity;
1056
1057 /*
1058 * interrupt pins are numbered starting from 1
1059 */
1060 irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
1061 PCI_SLOT(dev->devfn), pin - 1,
1062 &ioapic, &ioapic_pin,
1063 &triggering, &polarity);
1064 /*
1065 * Busses behind bridges are typically not listed in the
1066 * MP-table. In this case we have to look up the IRQ
1067 * based on the parent bus, parent slot, and pin number.
1068 * The SMP code detects such bridged busses itself so we
1069 * should get into this branch reliably.
1070 */
1071 if (irq < 0 && dev->bus->parent) {
1072 /* go back to the bridge */
1073 struct pci_dev *bridge = dev->bus->self;
1074 int bus;
1075
1076 pin = pci_swizzle_interrupt_pin(dev, pin);
1077 bus = bridge->bus->number;
1078 irq = IO_APIC_get_PCI_irq_vector(bus,
1079 PCI_SLOT(bridge->devfn),
1080 pin - 1,
1081 &ioapic, &ioapic_pin,
1082 &triggering, &polarity);
1083 if (irq >= 0)
1084 dev_warn(&dev->dev,
1085 "using bridge %s INT %c to "
1086 "get IRQ %d\n",
1087 pci_name(bridge),
1088 'A' + pin - 1, irq);
1089 }
1090 if (irq >= 0) {
1091 dev_info(&dev->dev,
1092 "PCI->APIC IRQ transform: INT %c "
1093 "-> IRQ %d\n",
1094 'A' + pin - 1, irq);
1095 dev->irq = irq;
1096 }
1097 }
1098#endif
1099 /* 1054 /*
1100 * Still no IRQ? Try to lookup one... 1055 * Still no IRQ? Try to lookup one...
1101 */ 1056 */
@@ -1190,6 +1145,19 @@ int __init pcibios_irq_init(void)
1190 pcibios_enable_irq = pirq_enable_irq; 1145 pcibios_enable_irq = pirq_enable_irq;
1191 1146
1192 pcibios_fixup_irqs(); 1147 pcibios_fixup_irqs();
1148
1149 if (io_apic_assign_pci_irqs && pci_routeirq) {
1150 struct pci_dev *dev = NULL;
1151 /*
1152 * PCI IRQ routing is set up by pci_enable_device(), but we
1153 * also do it here in case there are still broken drivers that
1154 * don't use pci_enable_device().
1155 */
1156 printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
1157 for_each_pci_dev(dev)
1158 pirq_enable_irq(dev);
1159 }
1160
1193 return 0; 1161 return 0;
1194} 1162}
1195 1163
@@ -1220,13 +1188,17 @@ void pcibios_penalize_isa_irq(int irq, int active)
1220static int pirq_enable_irq(struct pci_dev *dev) 1188static int pirq_enable_irq(struct pci_dev *dev)
1221{ 1189{
1222 u8 pin; 1190 u8 pin;
1223 struct pci_dev *temp_dev;
1224 1191
1225 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 1192 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
1226 if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { 1193 if (pin && !pcibios_lookup_irq(dev, 1)) {
1227 char *msg = ""; 1194 char *msg = "";
1228 1195
1196 if (!io_apic_assign_pci_irqs && dev->irq)
1197 return 0;
1198
1229 if (io_apic_assign_pci_irqs) { 1199 if (io_apic_assign_pci_irqs) {
1200#ifdef CONFIG_X86_IO_APIC
1201 struct pci_dev *temp_dev;
1230 int irq; 1202 int irq;
1231 int ioapic = -1, ioapic_pin = -1; 1203 int ioapic = -1, ioapic_pin = -1;
1232 int triggering, polarity; 1204 int triggering, polarity;
@@ -1261,12 +1233,16 @@ static int pirq_enable_irq(struct pci_dev *dev)
1261 } 1233 }
1262 dev = temp_dev; 1234 dev = temp_dev;
1263 if (irq >= 0) { 1235 if (irq >= 0) {
1236 io_apic_set_pci_routing(&dev->dev, ioapic,
1237 ioapic_pin, irq,
1238 triggering, polarity);
1239 dev->irq = irq;
1264 dev_info(&dev->dev, "PCI->APIC IRQ transform: " 1240 dev_info(&dev->dev, "PCI->APIC IRQ transform: "
1265 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq); 1241 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
1266 dev->irq = irq;
1267 return 0; 1242 return 0;
1268 } else 1243 } else
1269 msg = "; probably buggy MP table"; 1244 msg = "; probably buggy MP table";
1245#endif
1270 } else if (pci_probe & PCI_BIOS_IRQ_SCAN) 1246 } else if (pci_probe & PCI_BIOS_IRQ_SCAN)
1271 msg = ""; 1247 msg = "";
1272 else 1248 else