diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-22 19:20:34 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-22 19:20:34 -0500 |
commit | d02e30c31c57683a66ed68a1bcff900ca78f6d56 (patch) | |
tree | c3ce99a00061bcc1199b50fa838147d876c56717 /arch/x86/kernel/apic/io_apic.c | |
parent | 0fdc7a8022c3eaff6b5ee27ffb9e913e5e58d8e9 (diff) | |
parent | aef55d4922e62a0d887e60d87319f3718aec6ced (diff) |
Merge branch 'x86/irq' into x86/apic
Merge reason:
Conflicts in arch/x86/kernel/apic/io_apic.c
Resolved Conflicts:
arch/x86/kernel/apic/io_apic.c
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 103 |
1 files changed, 64 insertions, 39 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index d55e43d352b3..979589881c80 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1541,6 +1541,56 @@ static void __init setup_IO_APIC_irqs(void) | |||
1541 | } | 1541 | } |
1542 | 1542 | ||
1543 | /* | 1543 | /* |
1544 | * for the gsit that is not in first ioapic | ||
1545 | * but could not use acpi_register_gsi() | ||
1546 | * like some special sci in IBM x3330 | ||
1547 | */ | ||
1548 | void setup_IO_APIC_irq_extra(u32 gsi) | ||
1549 | { | ||
1550 | int apic_id = 0, pin, idx, irq; | ||
1551 | int node = cpu_to_node(boot_cpu_id); | ||
1552 | struct irq_desc *desc; | ||
1553 | struct irq_cfg *cfg; | ||
1554 | |||
1555 | /* | ||
1556 | * Convert 'gsi' to 'ioapic.pin'. | ||
1557 | */ | ||
1558 | apic_id = mp_find_ioapic(gsi); | ||
1559 | if (apic_id < 0) | ||
1560 | return; | ||
1561 | |||
1562 | pin = mp_find_ioapic_pin(apic_id, gsi); | ||
1563 | idx = find_irq_entry(apic_id, pin, mp_INT); | ||
1564 | if (idx == -1) | ||
1565 | return; | ||
1566 | |||
1567 | irq = pin_2_irq(idx, apic_id, pin); | ||
1568 | #ifdef CONFIG_SPARSE_IRQ | ||
1569 | desc = irq_to_desc(irq); | ||
1570 | if (desc) | ||
1571 | return; | ||
1572 | #endif | ||
1573 | desc = irq_to_desc_alloc_node(irq, node); | ||
1574 | if (!desc) { | ||
1575 | printk(KERN_INFO "can not get irq_desc for %d\n", irq); | ||
1576 | return; | ||
1577 | } | ||
1578 | |||
1579 | cfg = desc->chip_data; | ||
1580 | add_pin_to_irq_node(cfg, node, apic_id, pin); | ||
1581 | |||
1582 | if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { | ||
1583 | pr_debug("Pin %d-%d already programmed\n", | ||
1584 | mp_ioapics[apic_id].apicid, pin); | ||
1585 | return; | ||
1586 | } | ||
1587 | set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed); | ||
1588 | |||
1589 | setup_IO_APIC_irq(apic_id, pin, irq, desc, | ||
1590 | irq_trigger(idx), irq_polarity(idx)); | ||
1591 | } | ||
1592 | |||
1593 | /* | ||
1544 | * Set up the timer pin, possibly with the 8259A-master behind. | 1594 | * Set up the timer pin, possibly with the 8259A-master behind. |
1545 | */ | 1595 | */ |
1546 | static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, | 1596 | static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin, |
@@ -1832,7 +1882,7 @@ __apicdebuginit(void) print_PIC(void) | |||
1832 | 1882 | ||
1833 | printk(KERN_DEBUG "\nprinting PIC contents\n"); | 1883 | printk(KERN_DEBUG "\nprinting PIC contents\n"); |
1834 | 1884 | ||
1835 | spin_lock_irqsave(&i8259A_lock, flags); | 1885 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
1836 | 1886 | ||
1837 | v = inb(0xa1) << 8 | inb(0x21); | 1887 | v = inb(0xa1) << 8 | inb(0x21); |
1838 | printk(KERN_DEBUG "... PIC IMR: %04x\n", v); | 1888 | printk(KERN_DEBUG "... PIC IMR: %04x\n", v); |
@@ -1846,7 +1896,7 @@ __apicdebuginit(void) print_PIC(void) | |||
1846 | outb(0x0a,0xa0); | 1896 | outb(0x0a,0xa0); |
1847 | outb(0x0a,0x20); | 1897 | outb(0x0a,0x20); |
1848 | 1898 | ||
1849 | spin_unlock_irqrestore(&i8259A_lock, flags); | 1899 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
1850 | 1900 | ||
1851 | printk(KERN_DEBUG "... PIC ISR: %04x\n", v); | 1901 | printk(KERN_DEBUG "... PIC ISR: %04x\n", v); |
1852 | 1902 | ||
@@ -2436,6 +2486,13 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
2436 | cfg = irq_cfg(irq); | 2486 | cfg = irq_cfg(irq); |
2437 | raw_spin_lock(&desc->lock); | 2487 | raw_spin_lock(&desc->lock); |
2438 | 2488 | ||
2489 | /* | ||
2490 | * Check if the irq migration is in progress. If so, we | ||
2491 | * haven't received the cleanup request yet for this irq. | ||
2492 | */ | ||
2493 | if (cfg->move_in_progress) | ||
2494 | goto unlock; | ||
2495 | |||
2439 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) | 2496 | if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain)) |
2440 | goto unlock; | 2497 | goto unlock; |
2441 | 2498 | ||
@@ -3223,12 +3280,9 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) | |||
3223 | } | 3280 | } |
3224 | raw_spin_unlock_irqrestore(&vector_lock, flags); | 3281 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
3225 | 3282 | ||
3226 | if (irq > 0) { | 3283 | if (irq > 0) |
3227 | dynamic_irq_init(irq); | 3284 | dynamic_irq_init_keep_chip_data(irq); |
3228 | /* restore it, in case dynamic_irq_init clear it */ | 3285 | |
3229 | if (desc_new) | ||
3230 | desc_new->chip_data = cfg_new; | ||
3231 | } | ||
3232 | return irq; | 3286 | return irq; |
3233 | } | 3287 | } |
3234 | 3288 | ||
@@ -3250,19 +3304,12 @@ int create_irq(void) | |||
3250 | void destroy_irq(unsigned int irq) | 3304 | void destroy_irq(unsigned int irq) |
3251 | { | 3305 | { |
3252 | unsigned long flags; | 3306 | unsigned long flags; |
3253 | struct irq_cfg *cfg; | ||
3254 | struct irq_desc *desc; | ||
3255 | 3307 | ||
3256 | /* store it, in case dynamic_irq_cleanup clear it */ | 3308 | dynamic_irq_cleanup_keep_chip_data(irq); |
3257 | desc = irq_to_desc(irq); | ||
3258 | cfg = desc->chip_data; | ||
3259 | dynamic_irq_cleanup(irq); | ||
3260 | /* connect back irq_cfg */ | ||
3261 | desc->chip_data = cfg; | ||
3262 | 3309 | ||
3263 | free_irte(irq); | 3310 | free_irte(irq); |
3264 | raw_spin_lock_irqsave(&vector_lock, flags); | 3311 | raw_spin_lock_irqsave(&vector_lock, flags); |
3265 | __clear_irq_vector(irq, cfg); | 3312 | __clear_irq_vector(irq, get_irq_chip_data(irq)); |
3266 | raw_spin_unlock_irqrestore(&vector_lock, flags); | 3313 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
3267 | } | 3314 | } |
3268 | 3315 | ||
@@ -3829,28 +3876,6 @@ void __init probe_nr_irqs_gsi(void) | |||
3829 | printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); | 3876 | printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); |
3830 | } | 3877 | } |
3831 | 3878 | ||
3832 | #ifdef CONFIG_SPARSE_IRQ | ||
3833 | int __init arch_probe_nr_irqs(void) | ||
3834 | { | ||
3835 | int nr; | ||
3836 | |||
3837 | if (nr_irqs > (NR_VECTORS * nr_cpu_ids)) | ||
3838 | nr_irqs = NR_VECTORS * nr_cpu_ids; | ||
3839 | |||
3840 | nr = nr_irqs_gsi + 8 * nr_cpu_ids; | ||
3841 | #if defined(CONFIG_PCI_MSI) || defined(CONFIG_HT_IRQ) | ||
3842 | /* | ||
3843 | * for MSI and HT dyn irq | ||
3844 | */ | ||
3845 | nr += nr_irqs_gsi * 64; | ||
3846 | #endif | ||
3847 | if (nr < nr_irqs) | ||
3848 | nr_irqs = nr; | ||
3849 | |||
3850 | return 0; | ||
3851 | } | ||
3852 | #endif | ||
3853 | |||
3854 | static int __io_apic_set_pci_routing(struct device *dev, int irq, | 3879 | static int __io_apic_set_pci_routing(struct device *dev, int irq, |
3855 | struct io_apic_irq_attr *irq_attr) | 3880 | struct io_apic_irq_attr *irq_attr) |
3856 | { | 3881 | { |