summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/apic/vector.c52
1 files changed, 13 insertions, 39 deletions
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 68f885913927..d6feb9ca8f52 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -36,9 +36,6 @@ EXPORT_SYMBOL_GPL(x86_vector_domain);
static DEFINE_RAW_SPINLOCK(vector_lock);
static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask;
static struct irq_chip lapic_controller;
-#ifdef CONFIG_X86_IO_APIC
-static struct apic_chip_data *legacy_irq_data[NR_IRQS_LEGACY];
-#endif
#ifdef CONFIG_SMP
static DEFINE_PER_CPU(struct hlist_head, cleanup_list);
#endif
@@ -317,10 +314,6 @@ static void x86_vector_free_irqs(struct irq_domain *domain,
irq_domain_reset_irq_data(irqd);
raw_spin_unlock_irqrestore(&vector_lock, flags);
free_apic_chip_data(apicd);
-#ifdef CONFIG_X86_IO_APIC
- if (virq + i < nr_legacy_irqs())
- legacy_irq_data[virq + i] = NULL;
-#endif
}
}
}
@@ -344,12 +337,8 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
irqd = irq_domain_get_irq_data(domain, virq + i);
BUG_ON(!irqd);
node = irq_data_get_node(irqd);
-#ifdef CONFIG_X86_IO_APIC
- if (virq + i < nr_legacy_irqs() && legacy_irq_data[virq + i])
- apicd = legacy_irq_data[virq + i];
- else
-#endif
- apicd = alloc_apic_chip_data(node);
+ WARN_ON_ONCE(irqd->chip_data);
+ apicd = alloc_apic_chip_data(node);
if (!apicd) {
err = -ENOMEM;
goto error;
@@ -359,6 +348,17 @@ static int x86_vector_alloc_irqs(struct irq_domain *domain, unsigned int virq,
irqd->chip_data = apicd;
irqd->hwirq = virq + i;
irqd_set_single_target(irqd);
+ /*
+ * Make sure, that the legacy to IOAPIC transition stays on
+ * the same vector. This is required for check_timer() to
+ * work correctly as it might switch back to legacy mode.
+ */
+ if (info->flags & X86_IRQ_ALLOC_LEGACY) {
+ apicd->cfg.vector = ISA_IRQ_VECTOR(virq + i);
+ apicd->cpu = 0;
+ cpumask_copy(apicd->domain, cpumask_of(0));
+ }
+
err = assign_irq_vector_policy(virq + i, node, apicd, info,
irqd);
if (err)
@@ -404,36 +404,10 @@ int __init arch_probe_nr_irqs(void)
return legacy_pic->probe();
}
-#ifdef CONFIG_X86_IO_APIC
-static void __init init_legacy_irqs(void)
-{
- int i, node = cpu_to_node(0);
- struct apic_chip_data *apicd;
-
- /*
- * For legacy IRQ's, start with assigning irq0 to irq15 to
- * ISA_IRQ_VECTOR(i) for all cpu's.
- */
- for (i = 0; i < nr_legacy_irqs(); i++) {
- apicd = legacy_irq_data[i] = alloc_apic_chip_data(node);
- BUG_ON(!apicd);
-
- apicd->cfg.vector = ISA_IRQ_VECTOR(i);
- cpumask_copy(apicd->domain, cpumask_of(0));
- apicd->cpu = 0;
- irq_set_chip_data(i, apicd);
- }
-}
-#else
-static inline void init_legacy_irqs(void) { }
-#endif
-
int __init arch_early_irq_init(void)
{
struct fwnode_handle *fn;
- init_legacy_irqs();
-
fn = irq_domain_alloc_named_fwnode("VECTOR");
BUG_ON(!fn);
x86_vector_domain = irq_domain_create_tree(fn, &x86_vector_domain_ops,