aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic/io_apic.c
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 /arch/x86/kernel/apic/io_apic.c
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>
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r--arch/x86/kernel/apic/io_apic.c150
1 files changed, 74 insertions, 76 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