x86, ioapic: Split up setup_ioapic_entry()
authorYinghai Lu <yinghai.lu@oracle.com>
Wed, 12 Oct 2011 07:33:15 +0000 (00:33 -0700)
committerIngo Molnar <mingo@elte.hu>
Wed, 12 Oct 2011 07:55:18 +0000 (09:55 +0200)
Ingo pointed out that setup_ioapic_entry() is way too big now.

Split the intr-remap code out into setup_ir_ioapic_entry().

Also pass struct io_apic_irq_attr * instead of 5 parameters
in those two functions.

At last in setup_ir_ioapic_entry() we don't need to panic.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Naga Chumbalkar <nagananda.chumbalkar@hp.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Link: http://lkml.kernel.org/r/4E9542BB.4070807@oracle.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/apic/io_apic.c

index a7052fa..2fbb9d6 100644 (file)
@@ -1255,72 +1255,95 @@ static void ioapic_register_intr(unsigned int irq, struct irq_cfg *cfg,
                                      fasteoi ? "fasteoi" : "edge");
 }
 
-static int setup_ioapic_entry(int apic_id, int irq,
-                             struct IO_APIC_route_entry *entry,
-                             unsigned int destination, int trigger,
-                             int polarity, int vector, int pin)
+
+static int setup_ir_ioapic_entry(int irq,
+                             struct IR_IO_APIC_route_entry *entry,
+                             unsigned int destination, int vector,
+                             struct io_apic_irq_attr *attr)
 {
-       /*
-        * add it to the IO-APIC irq-routing table:
-        */
-       memset(entry,0,sizeof(*entry));
+       int index;
+       struct irte irte;
+       int apic_id = mpc_ioapic_id(attr->ioapic);
+       struct intel_iommu *iommu = map_ioapic_to_ir(apic_id);
 
-       if (intr_remapping_enabled) {
-               struct intel_iommu *iommu = map_ioapic_to_ir(apic_id);
-               struct irte irte;
-               struct IR_IO_APIC_route_entry *ir_entry =
-                       (struct IR_IO_APIC_route_entry *) entry;
-               int index;
+       if (!iommu) {
+               pr_warn("No mapping iommu for ioapic %d\n", apic_id);
+               return -ENODEV;
+       }
 
-               if (!iommu)
-                       panic("No mapping iommu for ioapic %d\n", apic_id);
+       index = alloc_irte(iommu, irq, 1);
+       if (index < 0) {
+               pr_warn("Failed to allocate IRTE for ioapic %d\n", apic_id);
+               return -ENOMEM;
+       }
 
-               index = alloc_irte(iommu, irq, 1);
-               if (index < 0)
-                       panic("Failed to allocate IRTE for ioapic %d\n", apic_id);
+       prepare_irte(&irte, vector, destination);
 
-               prepare_irte(&irte, vector, destination);
+       /* Set source-id of interrupt request */
+       set_ioapic_sid(&irte, apic_id);
 
-               /* Set source-id of interrupt request */
-               set_ioapic_sid(&irte, apic_id);
+       modify_irte(irq, &irte);
 
-               modify_irte(irq, &irte);
+       apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: "
+               "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d "
+               "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X "
+               "Avail:%X Vector:%02X Dest:%08X "
+               "SID:%04X SQ:%X SVT:%X)\n",
+               apic_id, irte.present, irte.fpd, irte.dst_mode,
+               irte.redir_hint, irte.trigger_mode, irte.dlvry_mode,
+               irte.avail, irte.vector, irte.dest_id,
+               irte.sid, irte.sq, irte.svt);
+
+       memset(entry, 0, sizeof(*entry));
+
+       entry->index2   = (index >> 15) & 0x1;
+       entry->zero     = 0;
+       entry->format   = 1;
+       entry->index    = (index & 0x7fff);
+       /*
+        * IO-APIC RTE will be configured with virtual vector.
+        * irq handler will do the explicit EOI to the io-apic.
+        */
+       entry->vector   = attr->ioapic_pin;
+       entry->mask     = 0;                    /* enable IRQ */
+       entry->trigger  = attr->trigger;
+       entry->polarity = attr->polarity;
 
-               ir_entry->index2 = (index >> 15) & 0x1;
-               ir_entry->zero = 0;
-               ir_entry->format = 1;
-               ir_entry->index = (index & 0x7fff);
-               /*
-                * IO-APIC RTE will be configured with virtual vector.
-                * irq handler will do the explicit EOI to the io-apic.
-                */
-               ir_entry->vector = pin;
-
-               apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: "
-                       "Set IRTE entry (P:%d FPD:%d Dst_Mode:%d "
-                       "Redir_hint:%d Trig_Mode:%d Dlvry_Mode:%X "
-                       "Avail:%X Vector:%02X Dest:%08X "
-                       "SID:%04X SQ:%X SVT:%X)\n",
-                       apic_id, irte.present, irte.fpd, irte.dst_mode,
-                       irte.redir_hint, irte.trigger_mode, irte.dlvry_mode,
-                       irte.avail, irte.vector, irte.dest_id,
-                       irte.sid, irte.sq, irte.svt);
-       } else {
-               entry->delivery_mode = apic->irq_delivery_mode;
-               entry->dest_mode = apic->irq_dest_mode;
-               entry->dest = destination;
-               entry->vector = vector;
-       }
+       /* Mask level triggered irqs.
+        * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
+        */
+       if (attr->trigger)
+               entry->mask = 1;
 
-       entry->mask = 0;                                /* enable IRQ */
-       entry->trigger = trigger;
-       entry->polarity = polarity;
+       return 0;
+}
 
-       /* Mask level triggered irqs.
+static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
+                              unsigned int destination, int vector,
+                              struct io_apic_irq_attr *attr)
+{
+       if (intr_remapping_enabled)
+               return setup_ir_ioapic_entry(irq,
+                        (struct IR_IO_APIC_route_entry *)entry,
+                        destination, vector, attr);
+
+       memset(entry, 0, sizeof(*entry));
+
+       entry->delivery_mode = apic->irq_delivery_mode;
+       entry->dest_mode     = apic->irq_dest_mode;
+       entry->dest          = destination;
+       entry->vector        = vector;
+       entry->mask          = 0;                       /* enable IRQ */
+       entry->trigger       = attr->trigger;
+       entry->polarity      = attr->polarity;
+
+       /*
+        * Mask level triggered irqs.
         * Use IRQ_DELAYED_DISABLE for edge triggered irqs.
         */
-       if (trigger)
+       if (attr->trigger)
                entry->mask = 1;
+
        return 0;
 }
 
@@ -1351,13 +1374,11 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
                    attr->ioapic, mpc_ioapic_id(attr->ioapic), attr->ioapic_pin,
                    cfg->vector, irq, attr->trigger, attr->polarity, dest);
 
-
-       if (setup_ioapic_entry(mpc_ioapic_id(attr->ioapic), irq, &entry,
-                              dest, attr->trigger, attr->polarity, cfg->vector,
-                              attr->ioapic_pin)) {
-               printk("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
-                      mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
+       if (setup_ioapic_entry(irq, &entry, dest, cfg->vector, attr)) {
+               pr_warn("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
+                       mpc_ioapic_id(attr->ioapic), attr->ioapic_pin);
                __clear_irq_vector(irq, cfg);
+
                return;
        }