diff mbox

[4/4] x86/pci: update pirq_enable_irq to setup io apic routing -v2

Message ID 49FC8696.4020603@kernel.org (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Yinghai Lu May 2, 2009, 5:44 p.m. UTC
so we could set io apic routing only when enable device irq.

also could make setup_IO_APIC_irqs and setup_ioapic_dest only handle
first ioapic...

v2: remove one one not needed style change.
    merge the patch only setup io_apic for acpi on in setup_IO_APIC_irqs

[ Impact: make mptable irq enable more like acpi is used, and numa_irq_desc could get correct node when acpi=off ]

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
 arch/x86/kernel/apic/io_apic.c |  148 ++++++++++++++++++++---------------------
 arch/x86/pci/irq.c             |   84 ++++++++---------------
 2 files changed, 103 insertions(+), 129 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Ingo Molnar May 6, 2009, 12:45 p.m. UTC | #1
* Yinghai Lu <yinghai@kernel.org> wrote:

> so we could set io apic routing only when enable device irq.
> 
> also could make setup_IO_APIC_irqs and setup_ioapic_dest only handle
> first ioapic...
> 
> v2: remove one one not needed style change.
>     merge the patch only setup io_apic for acpi on in setup_IO_APIC_irqs
> 
> [ Impact: make mptable irq enable more like acpi is used, and numa_irq_desc could get correct node when acpi=off ]
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> 
> ---
>  arch/x86/kernel/apic/io_apic.c |  148 ++++++++++++++++++++---------------------
>  arch/x86/pci/irq.c             |   84 ++++++++---------------
>  2 files changed, 103 insertions(+), 129 deletions(-)

Ok, i guess this makes sense with acpi-less bootup modes.

There's hefty impact on io_apic.c and pci/irq.c as well. The io-apic 
code already has a fair amount of changes queued up. Jesse: do you 
have pci/irq.c changes queued up? If you agree with the patch, how 
should we handle this?

A few mostly cosmetic comments:

> +#ifdef CONFIG_ACPI
> +	if (!acpi_disabled && acpi_ioapic) {
> +		apic_id = mp_find_ioapic(0);
> +		if (apic_id < 0)
> +			apic_id = 0;
> +	}
> +#endif

that should go into a helper. I suspect.

>  
> -			idx = find_irq_entry(apic_id, pin, mp_INT);
> -			if (idx == -1) {
> -				if (!notcon) {
> -					notcon = 1;
> -					apic_printk(APIC_VERBOSE,
> -						KERN_DEBUG " %d-%d",
> -						mp_ioapics[apic_id].apicid, pin);
> -				} else
> -					apic_printk(APIC_VERBOSE, " %d-%d",
> -						mp_ioapics[apic_id].apicid, pin);
> -				continue;
> -			}
> -			if (notcon) {
> +	for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
> +		idx = find_irq_entry(apic_id, pin, mp_INT);
> +		if (idx == -1) {
> +			if (!notcon) {
> +				notcon = 1;
>  				apic_printk(APIC_VERBOSE,
> -					" (apicid-pin) not connected\n");
> -				notcon = 0;
> -			}
> +					KERN_DEBUG " %d-%d",
> +					mp_ioapics[apic_id].apicid, pin);
> +			} else
> +				apic_printk(APIC_VERBOSE, " %d-%d",
> +					mp_ioapics[apic_id].apicid, pin);
> +			continue;
> +		}
> +		if (notcon) {
> +			apic_printk(APIC_VERBOSE,
> +				" (apicid-pin) not connected\n");
> +			notcon = 0;
> +		}
>  
> -			irq = pin_2_irq(idx, apic_id, pin);
> +		irq = pin_2_irq(idx, apic_id, pin);
>  
> -			/*
> -			 * Skip the timer IRQ if there's a quirk handler
> -			 * installed and if it returns 1:
> -			 */
> -			if (apic->multi_timer_check &&
> -					apic->multi_timer_check(apic_id, irq))
> -				continue;
> -
> -			desc = irq_to_desc_alloc_node(irq, node);
> -			if (!desc) {
> -				printk(KERN_INFO "can not get irq_desc for %d\n", irq);
> -				continue;
> -			}
> -			cfg = desc->chip_data;
> -			add_pin_to_irq_node(cfg, node, apic_id, pin);
> +		/*
> +		 * Skip the timer IRQ if there's a quirk handler
> +		 * installed and if it returns 1:
> +		 */
> +		if (apic->multi_timer_check &&
> +				apic->multi_timer_check(apic_id, irq))
> +			continue;
>  
> -			setup_IO_APIC_irq(apic_id, pin, irq, desc,
> -					irq_trigger(idx), irq_polarity(idx));
> +		desc = irq_to_desc_alloc_node(irq, node);
> +		if (!desc) {
> +			printk(KERN_INFO "can not get irq_desc for %d\n", irq);
> +			continue;
>  		}
> +		cfg = desc->chip_data;
> +		add_pin_to_irq_node(cfg, node, apic_id, pin);
> +		set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
> +		setup_IO_APIC_irq(apic_id, pin, irq, desc,
> +				irq_trigger(idx), irq_polarity(idx));
>  	}

this loop has become quite large now - could its body be moved into 
a helper inline function?

> +#ifdef CONFIG_ACPI
> +	if (!acpi_disabled && acpi_ioapic) {
> +		ioapic = mp_find_ioapic(0);
> +		if (ioapic < 0)
> +			ioapic = 0;
> +	}
> +#endif

Needs a helper too?

> Index: linux-2.6/arch/x86/pci/irq.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/pci/irq.c
> +++ linux-2.6/arch/x86/pci/irq.c
> @@ -889,6 +889,9 @@ static int pcibios_lookup_irq(struct pci
>  		return 0;
>  	}
>  
> +	if (io_apic_assign_pci_irqs)
> +		return 0;
> +
>  	/* Find IRQ routing entry */
>  
>  	if (!pirq_table)
> @@ -1039,63 +1042,15 @@ static void __init pcibios_fixup_irqs(vo
>  		pirq_penalty[dev->irq]++;
>  	}
>  
> +	if (io_apic_assign_pci_irqs)
> +		return;
> +
>  	dev = NULL;
>  	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
>  		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
>  		if (!pin)
>  			continue;
>  
> -#ifdef CONFIG_X86_IO_APIC
> -		/*
> -		 * Recalculate IRQ numbers if we use the I/O APIC.
> -		 */
> -		if (io_apic_assign_pci_irqs) {
> -			int irq;
> -			int ioapic = -1, ioapic_pin = -1;
> -			int triggering, polarity;
> -
> -			/*
> -			 * interrupt pins are numbered starting from 1
> -			 */
> -			irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
> -						PCI_SLOT(dev->devfn), pin - 1,
> -						&ioapic, &ioapic_pin,
> -						&triggering, &polarity);
> -			/*
> -			 * Busses behind bridges are typically not listed in the
> -			 * MP-table.  In this case we have to look up the IRQ
> -			 * based on the parent bus, parent slot, and pin number.
> -			 * The SMP code detects such bridged busses itself so we
> -			 * should get into this branch reliably.
> -			 */
> -			if (irq < 0 && dev->bus->parent) {
> -				/* go back to the bridge */
> -				struct pci_dev *bridge = dev->bus->self;
> -				int bus;
> -
> -				pin = pci_swizzle_interrupt_pin(dev, pin);
> -				bus = bridge->bus->number;
> -				irq = IO_APIC_get_PCI_irq_vector(bus,
> -						PCI_SLOT(bridge->devfn),
> -						pin - 1,
> -						&ioapic, &ioapic_pin,
> -						&triggering, &polarity);
> -				if (irq >= 0)
> -					dev_warn(&dev->dev,
> -						"using bridge %s INT %c to "
> -							"get IRQ %d\n",
> -						 pci_name(bridge),
> -						 'A' + pin - 1, irq);
> -			}
> -			if (irq >= 0) {
> -				dev_info(&dev->dev,
> -					"PCI->APIC IRQ transform: INT %c "
> -						"-> IRQ %d\n",
> -					'A' + pin - 1, irq);
> -				dev->irq = irq;
> -			}
> -		}
> -#endif

nice!

>  		/*
>  		 * Still no IRQ? Try to lookup one...
>  		 */
> @@ -1190,6 +1145,19 @@ int __init pcibios_irq_init(void)
>  	pcibios_enable_irq = pirq_enable_irq;
>  
>  	pcibios_fixup_irqs();
> +
> +	if (io_apic_assign_pci_irqs && pci_routeirq) {
> +		struct pci_dev *dev = NULL;
> +		/*
> +		 * PCI IRQ routing is set up by pci_enable_device(), but we
> +		 * also do it here in case there are still broken drivers that
> +		 * don't use pci_enable_device().
> +		 */
> +		printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
> +		for_each_pci_dev(dev)
> +			pirq_enable_irq(dev);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -1220,13 +1188,17 @@ void pcibios_penalize_isa_irq(int irq, i
>  static int pirq_enable_irq(struct pci_dev *dev)
>  {
>  	u8 pin;
> -	struct pci_dev *temp_dev;
>  
>  	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
> -	if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
> +	if (pin && !pcibios_lookup_irq(dev, 1)) {
>  		char *msg = "";
>  
> +		if (!io_apic_assign_pci_irqs && dev->irq)
> +			return 0;
> +
>  		if (io_apic_assign_pci_irqs) {
> +#ifdef CONFIG_X86_IO_APIC
> +			struct pci_dev *temp_dev;
>  			int irq;
>  			int ioapic = -1, ioapic_pin = -1;
>  			int triggering, polarity;
> @@ -1261,12 +1233,16 @@ static int pirq_enable_irq(struct pci_de
>  			}
>  			dev = temp_dev;
>  			if (irq >= 0) {
> +				io_apic_set_pci_routing(&dev->dev, ioapic,
> +							ioapic_pin, irq,
> +							triggering, polarity);
> +				dev->irq = irq;
>  				dev_info(&dev->dev, "PCI->APIC IRQ transform: "
>  					 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
> -				dev->irq = irq;
>  				return 0;
>  			} else
>  				msg = "; probably buggy MP table";
> +#endif
>  		} else if (pci_probe & PCI_BIOS_IRQ_SCAN)
>  			msg = "";
>  		else

What a [pre-existing] maze of if else if else. Now also burdened 
with an #ifdef. New helper(s) needed?

	Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jesse Barnes May 6, 2009, 3:48 p.m. UTC | #2
On Wed, 6 May 2009 14:45:58 +0200
Ingo Molnar <mingo@elte.hu> wrote:

> 
> * Yinghai Lu <yinghai@kernel.org> wrote:
> 
> > so we could set io apic routing only when enable device irq.
> > 
> > also could make setup_IO_APIC_irqs and setup_ioapic_dest only handle
> > first ioapic...
> > 
> > v2: remove one one not needed style change.
> >     merge the patch only setup io_apic for acpi on in
> > setup_IO_APIC_irqs
> > 
> > [ Impact: make mptable irq enable more like acpi is used, and
> > numa_irq_desc could get correct node when acpi=off ]
> > 
> > Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> > 
> > ---
> >  arch/x86/kernel/apic/io_apic.c |  148
> > ++++++++++++++++++++---------------------
> > arch/x86/pci/irq.c             |   84 ++++++++--------------- 2
> > files changed, 103 insertions(+), 129 deletions(-)
> 
> Ok, i guess this makes sense with acpi-less bootup modes.
> 
> There's hefty impact on io_apic.c and pci/irq.c as well. The io-apic 
> code already has a fair amount of changes queued up. Jesse: do you 
> have pci/irq.c changes queued up? If you agree with the patch, how 
> should we handle this?

No I don't have anything recent...  and since this stuff is intertwined
with the io_apic changes I'm fine with it going through you guys.
diff mbox

Patch

Index: linux-2.6/arch/x86/kernel/apic/io_apic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-2.6/arch/x86/kernel/apic/io_apic.c
@@ -1481,9 +1481,13 @@  static void setup_IO_APIC_irq(int apic_i
 	ioapic_write_entry(apic_id, pin, entry);
 }
 
+static struct {
+	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
+} mp_ioapic_routing[MAX_IO_APICS];
+
 static void __init setup_IO_APIC_irqs(void)
 {
-	int apic_id, pin, idx, irq;
+	int apic_id = 0, pin, idx, irq;
 	int notcon = 0;
 	struct irq_desc *desc;
 	struct irq_cfg *cfg;
@@ -1491,48 +1495,53 @@  static void __init setup_IO_APIC_irqs(vo
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
-	for (apic_id = 0; apic_id < nr_ioapics; apic_id++) {
-		for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+#ifdef CONFIG_ACPI
+	if (!acpi_disabled && acpi_ioapic) {
+		apic_id = mp_find_ioapic(0);
+		if (apic_id < 0)
+			apic_id = 0;
+	}
+#endif
 
-			idx = find_irq_entry(apic_id, pin, mp_INT);
-			if (idx == -1) {
-				if (!notcon) {
-					notcon = 1;
-					apic_printk(APIC_VERBOSE,
-						KERN_DEBUG " %d-%d",
-						mp_ioapics[apic_id].apicid, pin);
-				} else
-					apic_printk(APIC_VERBOSE, " %d-%d",
-						mp_ioapics[apic_id].apicid, pin);
-				continue;
-			}
-			if (notcon) {
+	for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+		idx = find_irq_entry(apic_id, pin, mp_INT);
+		if (idx == -1) {
+			if (!notcon) {
+				notcon = 1;
 				apic_printk(APIC_VERBOSE,
-					" (apicid-pin) not connected\n");
-				notcon = 0;
-			}
+					KERN_DEBUG " %d-%d",
+					mp_ioapics[apic_id].apicid, pin);
+			} else
+				apic_printk(APIC_VERBOSE, " %d-%d",
+					mp_ioapics[apic_id].apicid, pin);
+			continue;
+		}
+		if (notcon) {
+			apic_printk(APIC_VERBOSE,
+				" (apicid-pin) not connected\n");
+			notcon = 0;
+		}
 
-			irq = pin_2_irq(idx, apic_id, pin);
+		irq = pin_2_irq(idx, apic_id, pin);
 
-			/*
-			 * Skip the timer IRQ if there's a quirk handler
-			 * installed and if it returns 1:
-			 */
-			if (apic->multi_timer_check &&
-					apic->multi_timer_check(apic_id, irq))
-				continue;
-
-			desc = irq_to_desc_alloc_node(irq, node);
-			if (!desc) {
-				printk(KERN_INFO "can not get irq_desc for %d\n", irq);
-				continue;
-			}
-			cfg = desc->chip_data;
-			add_pin_to_irq_node(cfg, node, apic_id, pin);
+		/*
+		 * Skip the timer IRQ if there's a quirk handler
+		 * installed and if it returns 1:
+		 */
+		if (apic->multi_timer_check &&
+				apic->multi_timer_check(apic_id, irq))
+			continue;
 
-			setup_IO_APIC_irq(apic_id, pin, irq, desc,
-					irq_trigger(idx), irq_polarity(idx));
+		desc = irq_to_desc_alloc_node(irq, node);
+		if (!desc) {
+			printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+			continue;
 		}
+		cfg = desc->chip_data;
+		add_pin_to_irq_node(cfg, node, apic_id, pin);
+		set_bit(pin, mp_ioapic_routing[apic_id].pin_programmed);
+		setup_IO_APIC_irq(apic_id, pin, irq, desc,
+				irq_trigger(idx), irq_polarity(idx));
 	}
 
 	if (notcon)
@@ -3877,10 +3886,6 @@  static int __io_apic_set_pci_routing(str
 	return 0;
 }
 
-static struct {
-	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
-} mp_ioapic_routing[MAX_IO_APICS];
-
 int io_apic_set_pci_routing(struct device *dev, int ioapic, int pin, int irq,
 				 int triggering, int polarity)
 {
@@ -4024,51 +4029,44 @@  int acpi_get_override_irq(int bus_irq, i
 #ifdef CONFIG_SMP
 void __init setup_ioapic_dest(void)
 {
-	int pin, ioapic, irq, irq_entry;
+	int pin, ioapic = 0, irq, irq_entry;
 	struct irq_desc *desc;
-	struct irq_cfg *cfg;
 	const struct cpumask *mask;
 
 	if (skip_ioapic_setup == 1)
 		return;
 
-	for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
-		for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
-			irq_entry = find_irq_entry(ioapic, pin, mp_INT);
-			if (irq_entry == -1)
-				continue;
-			irq = pin_2_irq(irq_entry, ioapic, pin);
-
-			/* setup_IO_APIC_irqs could fail to get vector for some device
-			 * when you have too many devices, because at that time only boot
-			 * cpu is online.
-			 */
-			desc = irq_to_desc(irq);
-			cfg = desc->chip_data;
-			if (!cfg->vector) {
-				setup_IO_APIC_irq(ioapic, pin, irq, desc,
-						  irq_trigger(irq_entry),
-						  irq_polarity(irq_entry));
-				continue;
+#ifdef CONFIG_ACPI
+	if (!acpi_disabled && acpi_ioapic) {
+		ioapic = mp_find_ioapic(0);
+		if (ioapic < 0)
+			ioapic = 0;
+	}
+#endif
 
-			}
+	for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+		irq_entry = find_irq_entry(ioapic, pin, mp_INT);
+		if (irq_entry == -1)
+			continue;
+		irq = pin_2_irq(irq_entry, ioapic, pin);
 
-			/*
-			 * Honour affinities which have been set in early boot
-			 */
-			if (desc->status &
-			    (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
-				mask = desc->affinity;
-			else
-				mask = apic->target_cpus();
+		desc = irq_to_desc(irq);
 
-			if (intr_remapping_enabled)
-				set_ir_ioapic_affinity_irq_desc(desc, mask);
-			else
-				set_ioapic_affinity_irq_desc(desc, mask);
-		}
+		/*
+		 * Honour affinities which have been set in early boot
+		 */
+		if (desc->status &
+		    (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
+			mask = desc->affinity;
+		else
+			mask = apic->target_cpus();
 
+		if (intr_remapping_enabled)
+			set_ir_ioapic_affinity_irq_desc(desc, mask);
+		else
+			set_ioapic_affinity_irq_desc(desc, mask);
 	}
+
 }
 #endif
 
Index: linux-2.6/arch/x86/pci/irq.c
===================================================================
--- linux-2.6.orig/arch/x86/pci/irq.c
+++ linux-2.6/arch/x86/pci/irq.c
@@ -889,6 +889,9 @@  static int pcibios_lookup_irq(struct pci
 		return 0;
 	}
 
+	if (io_apic_assign_pci_irqs)
+		return 0;
+
 	/* Find IRQ routing entry */
 
 	if (!pirq_table)
@@ -1039,63 +1042,15 @@  static void __init pcibios_fixup_irqs(vo
 		pirq_penalty[dev->irq]++;
 	}
 
+	if (io_apic_assign_pci_irqs)
+		return;
+
 	dev = NULL;
 	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 		if (!pin)
 			continue;
 
-#ifdef CONFIG_X86_IO_APIC
-		/*
-		 * Recalculate IRQ numbers if we use the I/O APIC.
-		 */
-		if (io_apic_assign_pci_irqs) {
-			int irq;
-			int ioapic = -1, ioapic_pin = -1;
-			int triggering, polarity;
-
-			/*
-			 * interrupt pins are numbered starting from 1
-			 */
-			irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
-						PCI_SLOT(dev->devfn), pin - 1,
-						&ioapic, &ioapic_pin,
-						&triggering, &polarity);
-			/*
-			 * Busses behind bridges are typically not listed in the
-			 * MP-table.  In this case we have to look up the IRQ
-			 * based on the parent bus, parent slot, and pin number.
-			 * The SMP code detects such bridged busses itself so we
-			 * should get into this branch reliably.
-			 */
-			if (irq < 0 && dev->bus->parent) {
-				/* go back to the bridge */
-				struct pci_dev *bridge = dev->bus->self;
-				int bus;
-
-				pin = pci_swizzle_interrupt_pin(dev, pin);
-				bus = bridge->bus->number;
-				irq = IO_APIC_get_PCI_irq_vector(bus,
-						PCI_SLOT(bridge->devfn),
-						pin - 1,
-						&ioapic, &ioapic_pin,
-						&triggering, &polarity);
-				if (irq >= 0)
-					dev_warn(&dev->dev,
-						"using bridge %s INT %c to "
-							"get IRQ %d\n",
-						 pci_name(bridge),
-						 'A' + pin - 1, irq);
-			}
-			if (irq >= 0) {
-				dev_info(&dev->dev,
-					"PCI->APIC IRQ transform: INT %c "
-						"-> IRQ %d\n",
-					'A' + pin - 1, irq);
-				dev->irq = irq;
-			}
-		}
-#endif
 		/*
 		 * Still no IRQ? Try to lookup one...
 		 */
@@ -1190,6 +1145,19 @@  int __init pcibios_irq_init(void)
 	pcibios_enable_irq = pirq_enable_irq;
 
 	pcibios_fixup_irqs();
+
+	if (io_apic_assign_pci_irqs && pci_routeirq) {
+		struct pci_dev *dev = NULL;
+		/*
+		 * PCI IRQ routing is set up by pci_enable_device(), but we
+		 * also do it here in case there are still broken drivers that
+		 * don't use pci_enable_device().
+		 */
+		printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n");
+		for_each_pci_dev(dev)
+			pirq_enable_irq(dev);
+	}
+
 	return 0;
 }
 
@@ -1220,13 +1188,17 @@  void pcibios_penalize_isa_irq(int irq, i
 static int pirq_enable_irq(struct pci_dev *dev)
 {
 	u8 pin;
-	struct pci_dev *temp_dev;
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-	if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
+	if (pin && !pcibios_lookup_irq(dev, 1)) {
 		char *msg = "";
 
+		if (!io_apic_assign_pci_irqs && dev->irq)
+			return 0;
+
 		if (io_apic_assign_pci_irqs) {
+#ifdef CONFIG_X86_IO_APIC
+			struct pci_dev *temp_dev;
 			int irq;
 			int ioapic = -1, ioapic_pin = -1;
 			int triggering, polarity;
@@ -1261,12 +1233,16 @@  static int pirq_enable_irq(struct pci_de
 			}
 			dev = temp_dev;
 			if (irq >= 0) {
+				io_apic_set_pci_routing(&dev->dev, ioapic,
+							ioapic_pin, irq,
+							triggering, polarity);
+				dev->irq = irq;
 				dev_info(&dev->dev, "PCI->APIC IRQ transform: "
 					 "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
-				dev->irq = irq;
 				return 0;
 			} else
 				msg = "; probably buggy MP table";
+#endif
 		} else if (pci_probe & PCI_BIOS_IRQ_SCAN)
 			msg = "";
 		else