diff options
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index c64ddd9d9979..527390cd6115 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, |
@@ -3252,14 +3302,12 @@ int create_irq(void) | |||
3252 | void destroy_irq(unsigned int irq) | 3302 | void destroy_irq(unsigned int irq) |
3253 | { | 3303 | { |
3254 | unsigned long flags; | 3304 | unsigned long flags; |
3255 | struct irq_cfg *cfg; | ||
3256 | 3305 | ||
3257 | dynamic_irq_cleanup_keep_chip_data(irq); | 3306 | dynamic_irq_cleanup_keep_chip_data(irq); |
3258 | 3307 | ||
3259 | free_irte(irq); | 3308 | free_irte(irq); |
3260 | spin_lock_irqsave(&vector_lock, flags); | 3309 | spin_lock_irqsave(&vector_lock, flags); |
3261 | cfg = irq_to_desc(irq)->chip_data; | 3310 | __clear_irq_vector(irq, get_irq_chip_data(irq)); |
3262 | __clear_irq_vector(irq, cfg); | ||
3263 | spin_unlock_irqrestore(&vector_lock, flags); | 3311 | spin_unlock_irqrestore(&vector_lock, flags); |
3264 | } | 3312 | } |
3265 | 3313 | ||