aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-09-28 14:34:53 -0400
committerThomas Gleixner <tglx@linutronix.de>2010-10-12 10:53:40 -0400
commitfbc6bff04a095e049be290ff6f6ac68839166bd6 (patch)
tree056af820123082b624e757da3d909c1e75d93db2
parentfe6dab4e79e82ec35879bfe1a8968b7d15ac0d91 (diff)
x86: ioapic: Cleanup sparse irq code
Switch over to the new allocator and remove all the magic which was caused by the unability to destroy irq descriptors. Get rid of the create_irq_nr() loop for sparse and non sparse irq. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/kernel/apic/io_apic.c107
2 files changed, 48 insertions, 60 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3ec657f7ee70..8cc510874e1b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -61,7 +61,6 @@ config X86
61 select HAVE_USER_RETURN_NOTIFIER 61 select HAVE_USER_RETURN_NOTIFIER
62 select HAVE_GENERIC_HARDIRQS 62 select HAVE_GENERIC_HARDIRQS
63 select HAVE_SPARSE_IRQ 63 select HAVE_SPARSE_IRQ
64 select NUMA_IRQ_DESC if (SPARSE_IRQ && NUMA)
65 select GENERIC_IRQ_PROBE 64 select GENERIC_IRQ_PROBE
66 select GENERIC_PENDING_IRQ if SMP 65 select GENERIC_PENDING_IRQ if SMP
67 66
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 5aae718a7133..ed340297571e 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -157,6 +157,9 @@ int __init arch_early_irq_init(void)
157 count = ARRAY_SIZE(irq_cfgx); 157 count = ARRAY_SIZE(irq_cfgx);
158 node = cpu_to_node(0); 158 node = cpu_to_node(0);
159 159
160 /* Make sure the legacy interrupts are marked in the bitmap */
161 irq_reserve_irqs(0, legacy_pic->nr_legacy_irqs);
162
160 for (i = 0; i < count; i++) { 163 for (i = 0; i < count; i++) {
161 set_irq_chip_data(i, &cfg[i]); 164 set_irq_chip_data(i, &cfg[i]);
162 zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node); 165 zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
@@ -201,11 +204,15 @@ out_cfg:
201 204
202static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg) 205static void free_irq_cfg(unsigned int at, struct irq_cfg *cfg)
203{ 206{
207 if (!cfg)
208 return;
209 set_irq_chip_data(at, NULL);
204 free_cpumask_var(cfg->domain); 210 free_cpumask_var(cfg->domain);
205 free_cpumask_var(cfg->old_domain); 211 free_cpumask_var(cfg->old_domain);
206 kfree(cfg); 212 kfree(cfg);
207} 213}
208 214
215#if 0
209int arch_init_chip_data(struct irq_desc *desc, int node) 216int arch_init_chip_data(struct irq_desc *desc, int node)
210{ 217{
211 struct irq_cfg *cfg; 218 struct irq_cfg *cfg;
@@ -323,6 +330,7 @@ void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc)
323 } 330 }
324} 331}
325/* end for move_irq_desc */ 332/* end for move_irq_desc */
333#endif
326 334
327#else 335#else
328 336
@@ -1479,11 +1487,9 @@ static struct {
1479 1487
1480static void __init setup_IO_APIC_irqs(void) 1488static void __init setup_IO_APIC_irqs(void)
1481{ 1489{
1482 int apic_id, pin, idx, irq; 1490 int apic_id, pin, idx, irq, notcon = 0;
1483 int notcon = 0;
1484 struct irq_desc *desc;
1485 struct irq_cfg *cfg;
1486 int node = cpu_to_node(0); 1491 int node = cpu_to_node(0);
1492 struct irq_cfg *cfg;
1487 1493
1488 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); 1494 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
1489 1495
@@ -1520,12 +1526,10 @@ static void __init setup_IO_APIC_irqs(void)
1520 apic->multi_timer_check(apic_id, irq)) 1526 apic->multi_timer_check(apic_id, irq))
1521 continue; 1527 continue;
1522 1528
1523 desc = irq_to_desc_alloc_node(irq, node); 1529 cfg = alloc_irq_and_cfg_at(irq, node);
1524 if (!desc) { 1530 if (!cfg)
1525 printk(KERN_INFO "can not get irq_desc for %d\n", irq);
1526 continue; 1531 continue;
1527 } 1532
1528 cfg = get_irq_desc_chip_data(desc);
1529 add_pin_to_irq_node(cfg, node, apic_id, pin); 1533 add_pin_to_irq_node(cfg, node, apic_id, pin);
1530 /* 1534 /*
1531 * don't mark it in pin_programmed, so later acpi could 1535 * don't mark it in pin_programmed, so later acpi could
@@ -1547,9 +1551,7 @@ static void __init setup_IO_APIC_irqs(void)
1547 */ 1551 */
1548void setup_IO_APIC_irq_extra(u32 gsi) 1552void setup_IO_APIC_irq_extra(u32 gsi)
1549{ 1553{
1550 int apic_id = 0, pin, idx, irq; 1554 int apic_id = 0, pin, idx, irq, node = cpu_to_node(0);
1551 int node = cpu_to_node(0);
1552 struct irq_desc *desc;
1553 struct irq_cfg *cfg; 1555 struct irq_cfg *cfg;
1554 1556
1555 /* 1557 /*
@@ -1570,13 +1572,10 @@ void setup_IO_APIC_irq_extra(u32 gsi)
1570 if (apic_id == 0 || irq < NR_IRQS_LEGACY) 1572 if (apic_id == 0 || irq < NR_IRQS_LEGACY)
1571 return; 1573 return;
1572 1574
1573 desc = irq_to_desc_alloc_node(irq, node); 1575 cfg = alloc_irq_and_cfg_at(irq, node);
1574 if (!desc) { 1576 if (!cfg)
1575 printk(KERN_INFO "can not get irq_desc for %d\n", irq);
1576 return; 1577 return;
1577 }
1578 1578
1579 cfg = get_irq_desc_chip_data(desc);
1580 add_pin_to_irq_node(cfg, node, apic_id, pin); 1579 add_pin_to_irq_node(cfg, node, apic_id, pin);
1581 1580
1582 if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) { 1581 if (test_bit(pin, mp_ioapic_routing[apic_id].pin_programmed)) {
@@ -3177,44 +3176,37 @@ device_initcall(ioapic_init_sysfs);
3177/* 3176/*
3178 * Dynamic irq allocate and deallocation 3177 * Dynamic irq allocate and deallocation
3179 */ 3178 */
3180unsigned int create_irq_nr(unsigned int irq_want, int node) 3179unsigned int create_irq_nr(unsigned int from, int node)
3181{ 3180{
3182 /* Allocate an unused irq */ 3181 struct irq_cfg *cfg;
3183 unsigned int irq;
3184 unsigned int new;
3185 unsigned long flags; 3182 unsigned long flags;
3186 struct irq_cfg *cfg_new = NULL; 3183 unsigned int ret = 0;
3187 struct irq_desc *desc_new = NULL; 3184 int irq;
3188
3189 irq = 0;
3190 if (irq_want < nr_irqs_gsi)
3191 irq_want = nr_irqs_gsi;
3192
3193 raw_spin_lock_irqsave(&vector_lock, flags);
3194 for (new = irq_want; new < nr_irqs; new++) {
3195 desc_new = irq_to_desc_alloc_node(new, node);
3196 if (!desc_new) {
3197 printk(KERN_INFO "can not get irq_desc for %d\n", new);
3198 continue;
3199 }
3200 cfg_new = get_irq_desc_chip_data(desc_new);
3201
3202 if (cfg_new->vector != 0)
3203 continue;
3204 3185
3205 desc_new = move_irq_desc(desc_new, node); 3186 if (from < nr_irqs_gsi)
3206 cfg_new = get_irq_desc_chip_data(desc_new); 3187 from = nr_irqs_gsi;
3207 3188
3208 if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0) 3189 irq = alloc_irq_from(from, node);
3209 irq = new; 3190 if (irq < 0)
3210 break; 3191 return 0;
3192 cfg = alloc_irq_cfg(irq, node);
3193 if (!cfg) {
3194 free_irq_at(irq, NULL);
3195 return 0;
3211 } 3196 }
3212 raw_spin_unlock_irqrestore(&vector_lock, flags);
3213 3197
3214 if (irq > 0) 3198 raw_spin_lock_irqsave(&vector_lock, flags);
3215 dynamic_irq_init_keep_chip_data(irq); 3199 if (!__assign_irq_vector(irq, cfg, apic->target_cpus()))
3200 ret = irq;
3201 raw_spin_unlock_irqrestore(&vector_lock, flags);
3216 3202
3217 return irq; 3203 if (ret) {
3204 set_irq_chip_data(irq, cfg);
3205 irq_clear_status_flags(irq, IRQ_NOREQUEST);
3206 } else {
3207 free_irq_at(irq, cfg);
3208 }
3209 return ret;
3218} 3210}
3219 3211
3220int create_irq(void) 3212int create_irq(void)
@@ -3234,14 +3226,16 @@ int create_irq(void)
3234 3226
3235void destroy_irq(unsigned int irq) 3227void destroy_irq(unsigned int irq)
3236{ 3228{
3229 struct irq_cfg *cfg = get_irq_chip_data(irq);
3237 unsigned long flags; 3230 unsigned long flags;
3238 3231
3239 dynamic_irq_cleanup_keep_chip_data(irq); 3232 irq_set_status_flags(irq, IRQ_NOREQUEST|IRQ_NOPROBE);
3240 3233
3241 free_irte(irq); 3234 free_irte(irq);
3242 raw_spin_lock_irqsave(&vector_lock, flags); 3235 raw_spin_lock_irqsave(&vector_lock, flags);
3243 __clear_irq_vector(irq, get_irq_chip_data(irq)); 3236 __clear_irq_vector(irq, cfg);
3244 raw_spin_unlock_irqrestore(&vector_lock, flags); 3237 raw_spin_unlock_irqrestore(&vector_lock, flags);
3238 free_irq_at(irq, cfg);
3245} 3239}
3246 3240
3247/* 3241/*
@@ -3802,7 +3796,6 @@ int __init arch_probe_nr_irqs(void)
3802static int __io_apic_set_pci_routing(struct device *dev, int irq, 3796static int __io_apic_set_pci_routing(struct device *dev, int irq,
3803 struct io_apic_irq_attr *irq_attr) 3797 struct io_apic_irq_attr *irq_attr)
3804{ 3798{
3805 struct irq_desc *desc;
3806 struct irq_cfg *cfg; 3799 struct irq_cfg *cfg;
3807 int node; 3800 int node;
3808 int ioapic, pin; 3801 int ioapic, pin;
@@ -3820,18 +3813,14 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
3820 else 3813 else
3821 node = cpu_to_node(0); 3814 node = cpu_to_node(0);
3822 3815
3823 desc = irq_to_desc_alloc_node(irq, node); 3816 cfg = alloc_irq_and_cfg_at(irq, node);
3824 if (!desc) { 3817 if (!cfg)
3825 printk(KERN_INFO "can not get irq_desc %d\n", irq);
3826 return 0; 3818 return 0;
3827 }
3828 3819
3829 pin = irq_attr->ioapic_pin; 3820 pin = irq_attr->ioapic_pin;
3830 trigger = irq_attr->trigger; 3821 trigger = irq_attr->trigger;
3831 polarity = irq_attr->polarity; 3822 polarity = irq_attr->polarity;
3832 3823
3833 cfg = get_irq_desc_chip_data(desc);
3834
3835 /* 3824 /*
3836 * IRQs < 16 are already in the irq_2_pin[] map 3825 * IRQs < 16 are already in the irq_2_pin[] map
3837 */ 3826 */
@@ -4232,11 +4221,11 @@ void __init pre_init_apic_IRQ0(void)
4232#ifndef CONFIG_SMP 4221#ifndef CONFIG_SMP
4233 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); 4222 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
4234#endif 4223#endif
4235 irq_to_desc_alloc_node(0, 0); 4224 /* Make sure the irq descriptor is set up */
4225 cfg = alloc_irq_and_cfg_at(0, 0);
4236 4226
4237 setup_local_APIC(); 4227 setup_local_APIC();
4238 4228
4239 cfg = irq_cfg(0);
4240 add_pin_to_irq_node(cfg, 0, 0, 0); 4229 add_pin_to_irq_node(cfg, 0, 0, 0);
4241 set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge"); 4230 set_irq_chip_and_handler_name(0, &ioapic_chip, handle_edge_irq, "edge");
4242 4231