aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2010-02-10 04:20:05 -0500
committerH. Peter Anvin <hpa@zytor.com>2010-02-10 16:47:39 -0500
commit18dce6ba5c8c6bd0f3ab4efa4cbdd698dab5c40a (patch)
tree03deca24435fade73b13573020dc751204f3b963 /arch
parent318f6b228ba88a394ef560efc1bfe028ad5ae6b6 (diff)
x86: Fix SCI on IOAPIC != 0
Thomas Renninger <trenn@suse.de> reported on IBM x3330 booting a latest kernel on this machine results in: PCI: PCI BIOS revision 2.10 entry at 0xfd61c, last bus=1 PCI: Using configuration type 1 for base access bio: create slab <bio-0> at 0 ACPI: SCI (IRQ30) allocation failed ACPI Exception: AE_NOT_ACQUIRED, Unable to install System Control Interrupt handler (20090903/evevent-161) ACPI: Unable to start the ACPI Interpreter Later all kind of devices fail... and bisect it down to this commit: commit b9c61b70075c87a8612624736faf4a2de5b1ed30 x86/pci: update pirq_enable_irq() to setup io apic routing it turns out we need to set irq routing for the sci on ioapic1 early. -v2: make it work without sparseirq too. -v3: fix checkpatch.pl warning, and cc to stable Reported-by: Thomas Renninger <trenn@suse.de> Bisected-by: Thomas Renninger <trenn@suse.de> Tested-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Yinghai Lu <yinghai@kernel.org> LKML-Reference: <1265793639-15071-2-git-send-email-yinghai@kernel.org> Cc: stable@kernel.org Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/io_apic.h1
-rw-r--r--arch/x86/kernel/acpi/boot.c9
-rw-r--r--arch/x86/kernel/apic/io_apic.c50
3 files changed, 59 insertions, 1 deletions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 7c7c16cde1f8..5f61f6e0ffdd 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -160,6 +160,7 @@ extern int io_apic_get_redir_entries(int ioapic);
160struct io_apic_irq_attr; 160struct io_apic_irq_attr;
161extern int io_apic_set_pci_routing(struct device *dev, int irq, 161extern int io_apic_set_pci_routing(struct device *dev, int irq,
162 struct io_apic_irq_attr *irq_attr); 162 struct io_apic_irq_attr *irq_attr);
163void setup_IO_APIC_irq_extra(u32 gsi);
163extern int (*ioapic_renumber_irq)(int ioapic, int irq); 164extern int (*ioapic_renumber_irq)(int ioapic, int irq);
164extern void ioapic_init_mappings(void); 165extern void ioapic_init_mappings(void);
165extern void ioapic_insert_resources(void); 166extern void ioapic_insert_resources(void);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0acbcdfa5ca4..5c96b75c6ea8 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -446,6 +446,12 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
446int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) 446int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
447{ 447{
448 *irq = gsi; 448 *irq = gsi;
449
450#ifdef CONFIG_X86_IO_APIC
451 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
452 setup_IO_APIC_irq_extra(gsi);
453#endif
454
449 return 0; 455 return 0;
450} 456}
451 457
@@ -473,7 +479,8 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
473 plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); 479 plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
474 } 480 }
475#endif 481#endif
476 acpi_gsi_to_irq(plat_gsi, &irq); 482 irq = plat_gsi;
483
477 return irq; 484 return irq;
478} 485}
479 486
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 53243ca7816d..5e4cce254e43 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1539,6 +1539,56 @@ static void __init setup_IO_APIC_irqs(void)
1539} 1539}
1540 1540
1541/* 1541/*
1542 * for the gsit that is not in first ioapic
1543 * but could not use acpi_register_gsi()
1544 * like some special sci in IBM x3330
1545 */
1546void setup_IO_APIC_irq_extra(u32 gsi)
1547{
1548 int apic_id = 0, pin, idx, irq;
1549 int node = cpu_to_node(boot_cpu_id);
1550 struct irq_desc *desc;
1551 struct irq_cfg *cfg;
1552
1553 /*
1554 * Convert 'gsi' to 'ioapic.pin'.
1555 */
1556 apic_id = mp_find_ioapic(gsi);
1557 if (apic_id < 0)
1558 return;
1559
1560 pin = mp_find_ioapic_pin(apic_id, gsi);
1561 idx = find_irq_entry(apic_id, pin, mp_INT);
1562 if (idx == -1)
1563 return;
1564
1565 irq = pin_2_irq(idx, apic_id, pin);
1566#ifdef CONFIG_SPARSE_IRQ
1567 desc = irq_to_desc(irq);
1568 if (desc)
1569 return;
1570#endif
1571 desc = irq_to_desc_alloc_node(irq, node);
1572 if (!desc) {
1573 printk(KERN_INFO "can not get irq_desc for %d\n", irq);
1574 return;
1575 }
1576
1577 cfg = desc->chip_data;
1578 add_pin_to_irq_node(cfg, node, apic_id, pin);
1579
1580 if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
1581 pr_debug("Pin %d-%d already programmed\n",
1582 mp_ioapics[apic_id].apicid, pin);
1583 return;
1584 }
1585 set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
1586
1587 setup_IO_APIC_irq(apic_id, pin, irq, desc,
1588 irq_trigger(idx), irq_polarity(idx));
1589}
1590
1591/*
1542 * Set up the timer pin, possibly with the 8259A-master behind. 1592 * Set up the timer pin, possibly with the 8259A-master behind.
1543 */ 1593 */
1544static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, 1594static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin,