diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c
index df4300c230622a47e506e957a9b05009e8717e86..97dd000039694d362110d15424d56b9bdce1f404 100644
--- a/arch/x86/cpu/irq.c
+++ b/arch/x86/cpu/irq.c
@@ -58,17 +58,28 @@ void pirq_assign_irq(int link, u8 irq)
 		writeb(irq, irq_router.ibase + LINK_N2V(link, base));
 }
 
-static inline void fill_irq_info(struct irq_info **slotp, int *entries, u8 bus,
-				 u8 device, u8 pin, u8 pirq)
+static struct irq_info *check_dup_entry(struct irq_info *slot_base,
+					int entry_num, int bus, int device)
 {
-	struct irq_info *slot = *slotp;
+	struct irq_info *slot = slot_base;
+	int i;
+
+	for (i = 0; i < entry_num; i++) {
+		if (slot->bus == bus && slot->devfn == (device << 3))
+			break;
+		slot++;
+	}
 
+	return (i == entry_num) ? NULL : slot;
+}
+
+static inline void fill_irq_info(struct irq_info *slot, int bus, int device,
+				 int pin, int pirq)
+{
 	slot->bus = bus;
 	slot->devfn = (device << 3) | 0;
 	slot->irq[pin - 1].link = LINK_N2V(pirq, irq_router.link_base);
 	slot->irq[pin - 1].bitmap = irq_router.irq_mask;
-	(*entries)++;
-	(*slotp)++;
 }
 
 __weak void cpu_irq_init(void)
@@ -84,7 +95,7 @@ static int create_pirq_routing_table(void)
 	int len, count;
 	const u32 *cell;
 	struct irq_routing_table *rt;
-	struct irq_info *slot;
+	struct irq_info *slot, *slot_base;
 	int irq_entries = 0;
 	int i;
 	int ret;
@@ -167,7 +178,7 @@ static int create_pirq_routing_table(void)
 	rt->rtr_vendor = PCI_VENDOR_ID_INTEL;
 	rt->rtr_device = PCI_DEVICE_ID_INTEL_ICH7_31;
 
-	slot = rt->slots;
+	slot_base = rt->slots;
 
 	/* Now fill in the irq_info entries in the PIRQ table */
 	for (i = 0; i < count; i++) {
@@ -181,8 +192,44 @@ static int create_pirq_routing_table(void)
 		      i, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
 		      PCI_FUNC(pr.bdf), 'A' + pr.pin - 1,
 		      'A' + pr.pirq);
-		fill_irq_info(&slot, &irq_entries, PCI_BUS(pr.bdf),
-			      PCI_DEV(pr.bdf), pr.pin, pr.pirq);
+
+		slot = check_dup_entry(slot_base, irq_entries,
+				       PCI_BUS(pr.bdf), PCI_DEV(pr.bdf));
+		if (slot) {
+			debug("found entry for bus %d device %d, ",
+			      PCI_BUS(pr.bdf), PCI_DEV(pr.bdf));
+
+			if (slot->irq[pr.pin - 1].link) {
+				debug("skipping\n");
+
+				/*
+				 * Sanity test on the routed PIRQ pin
+				 *
+				 * If they don't match, show a warning to tell
+				 * there might be something wrong with the PIRQ
+				 * routing information in the device tree.
+				 */
+				if (slot->irq[pr.pin - 1].link !=
+					LINK_N2V(pr.pirq, irq_router.link_base))
+					debug("WARNING: Inconsistent PIRQ routing information\n");
+
+				cell += sizeof(struct pirq_routing) /
+					sizeof(u32);
+				continue;
+			} else {
+				debug("writing INT%c\n", 'A' + pr.pin - 1);
+				fill_irq_info(slot, PCI_BUS(pr.bdf),
+					      PCI_DEV(pr.bdf), pr.pin, pr.pirq);
+				cell += sizeof(struct pirq_routing) /
+					sizeof(u32);
+				continue;
+			}
+		}
+
+		slot = slot_base + irq_entries;
+		fill_irq_info(slot, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
+			      pr.pin, pr.pirq);
+		irq_entries++;
 		cell += sizeof(struct pirq_routing) / sizeof(u32);
 	}