diff options
| -rw-r--r-- | arch/x86/include/asm/io_apic.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/acpi/boot.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 50 |
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); | |||
| 160 | struct io_apic_irq_attr; | 160 | struct io_apic_irq_attr; |
| 161 | extern int io_apic_set_pci_routing(struct device *dev, int irq, | 161 | extern 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); |
| 163 | void setup_IO_APIC_irq_extra(u32 gsi); | ||
| 163 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); | 164 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); |
| 164 | extern void ioapic_init_mappings(void); | 165 | extern void ioapic_init_mappings(void); |
| 165 | extern void ioapic_insert_resources(void); | 166 | extern 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) | |||
| 446 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | 446 | int 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 | */ | ||
| 1546 | void 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 | */ |
| 1544 | static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, | 1594 | static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, |
