Commit-ID:  30ba6dedce8de6816f9c7b7b5992566c9e357574
Gitweb:     http://git.kernel.org/tip/30ba6dedce8de6816f9c7b7b5992566c9e357574
Author:     Jiang Liu <jiang....@linux.intel.com>
AuthorDate: Tue, 25 Nov 2014 15:49:30 +0800
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Wed, 26 Nov 2014 23:52:46 +0100

x86, irq: Refine the way to allocate irq_cfg for legacy IRQs

To support legacy ISA IRQs, we need to preallocate irq_cfg structures
for legacy ISA IRQs. Refine the way to allocate irq_cfg for legacy ISA
IRQs, so it's more friend to hierarchy irqdomain implementation.

Signed-off-by: Jiang Liu <jiang....@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.w...@oracle.com>
Cc: Tony Luck <tony.l...@intel.com>
Cc: Joerg Roedel <j...@8bytes.org>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Bjorn Helgaas <bhelg...@google.com>
Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org>
Cc: Rafael J. Wysocki <r...@rjwysocki.net>
Cc: Randy Dunlap <rdun...@infradead.org>
Cc: Yinghai Lu <ying...@kernel.org>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Grant Likely <grant.lik...@linaro.org>
Link: 
http://lkml.kernel.org/r/1416901802-24211-7-git-send-email-jiang....@linux.intel.com
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Tested-by: Joerg Roedel <jroe...@suse.de>
---
 arch/x86/kernel/apic/io_apic.c | 13 +------------
 arch/x86/kernel/apic/vector.c  | 42 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e465171..74a0e95 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -254,8 +254,7 @@ static void free_ioapic_saved_registers(int idx)
 
 int __init arch_early_ioapic_init(void)
 {
-       struct irq_cfg *cfg;
-       int i, node = cpu_to_node(0);
+       int i;
 
        if (!nr_legacy_irqs())
                io_apic_irqs = ~0UL;
@@ -263,16 +262,6 @@ int __init arch_early_ioapic_init(void)
        for_each_ioapic(i)
                alloc_ioapic_saved_registers(i);
 
-       /*
-        * For legacy IRQ's, start with assigning irq0 to irq15 to
-        * IRQ0_VECTOR to IRQ15_VECTOR for all cpu's.
-        */
-       for (i = 0; i < nr_legacy_irqs(); i++) {
-               cfg = alloc_irq_and_cfg_at(i, node);
-               cfg->vector = IRQ0_VECTOR + i;
-               cpumask_setall(cfg->domain);
-       }
-
        return 0;
 }
 
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 609db19..4b8fad9 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -24,6 +24,9 @@
 struct irq_domain *x86_vector_domain;
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static struct irq_chip lapic_controller;
+#ifdef CONFIG_X86_IO_APIC
+static struct irq_cfg *legacy_irq_cfgs[NR_IRQS_LEGACY];
+#endif
 
 void lock_vector_lock(void)
 {
@@ -283,6 +286,10 @@ static void x86_vector_free_irqs(struct irq_domain *domain,
                        free_remapped_irq(virq);
                        clear_irq_vector(virq + i, irq_data->chip_data);
                        free_irq_cfg(irq_data->chip_data);
+#ifdef CONFIG_X86_IO_APIC
+                       if (virq + i < nr_legacy_irqs())
+                               legacy_irq_cfgs[virq + i] = NULL;
+#endif
                        irq_domain_reset_irq_data(irq_data);
                }
        }
@@ -308,7 +315,12 @@ static int x86_vector_alloc_irqs(struct irq_domain 
*domain, unsigned int virq,
        for (i = 0; i < nr_irqs; i++) {
                irq_data = irq_domain_get_irq_data(domain, virq + i);
                BUG_ON(!irq_data);
-               cfg = alloc_irq_cfg(irq_data->node);
+#ifdef CONFIG_X86_IO_APIC
+               if (virq + i < nr_legacy_irqs() && legacy_irq_cfgs[virq + i])
+                       cfg = legacy_irq_cfgs[virq + i];
+               else
+#endif
+                       cfg = alloc_irq_cfg(irq_data->node);
                if (!cfg) {
                        err = -ENOMEM;
                        goto error;
@@ -357,8 +369,36 @@ int __init arch_probe_nr_irqs(void)
        return nr_legacy_irqs();
 }
 
+#ifdef CONFIG_X86_IO_APIC
+static void init_legacy_irqs(void)
+{
+       int i, node = cpu_to_node(0);
+       struct irq_cfg *cfg;
+
+       /*
+        * For legacy IRQ's, start with assigning irq0 to irq15 to
+        * IRQ0_VECTOR to IRQ15_VECTOR for all cpu's.
+        */
+       for (i = 0; i < nr_legacy_irqs(); i++) {
+               cfg = legacy_irq_cfgs[i] = alloc_irq_cfg(node);
+               BUG_ON(!cfg);
+               /*
+                * For legacy IRQ's, start with assigning irq0 to irq15 to
+                * IRQ0_VECTOR to IRQ15_VECTOR for all cpu's.
+                */
+               cfg->vector = IRQ0_VECTOR + i;
+               cpumask_setall(cfg->domain);
+               irq_set_chip_data(i, cfg);
+       }
+}
+#else
+static void init_legacy_irqs(void) { }
+#endif
+
 int __init arch_early_irq_init(void)
 {
+       init_legacy_irqs();
+
        x86_vector_domain = irq_domain_add_tree(NULL, &x86_vector_domain_ops,
                                                NULL);
        BUG_ON(x86_vector_domain == NULL);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to