diff mbox

[U-Boot,v2,2/7] x86: mpspec: Move writing ISA interrupt entry after PCI

Message ID BLU436-SMTP188D8ED53C6A24296CEAC01BF840@phx.gbl
State Superseded
Delegated to: Simon Glass
Headers show

Commit Message

Bin Meng July 21, 2015, 12:15 p.m. UTC
On some platforms the I/O APIC interrupt pin#0-15 may be connected
to platform pci devices' interrupt pin. In such cases the legacy ISA
IRQ is not available so we should not write ISA interrupt entry if
it is already occupied.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 arch/x86/lib/mpspec.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)
diff mbox

Patch

diff --git a/arch/x86/lib/mpspec.c b/arch/x86/lib/mpspec.c
index 9b2a59b..f3ad116 100644
--- a/arch/x86/lib/mpspec.c
+++ b/arch/x86/lib/mpspec.c
@@ -21,6 +21,8 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static bool isa_irq_occupied[16];
+
 struct mp_config_table *mp_write_floating_table(struct mp_floating_table *mf)
 {
 	u32 mc;
@@ -243,10 +245,18 @@  static void mptable_add_isa_interrupts(struct mp_config_table *mc, int bus_isa,
 			MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
 			bus_isa, 0, apicid, 2);
 
-	for (i = 3; i < 16; i++)
+	for (i = 3; i < 16; i++) {
+		/*
+		 * Do not write ISA interrupt entry if it is already occupied
+		 * by the platform devices.
+		 */
+		if (isa_irq_occupied[i])
+			continue;
+
 		mp_write_intsrc(mc, MP_INT,
 				MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
 				bus_isa, i, apicid, i);
+	}
 }
 
 /*
@@ -287,10 +297,6 @@  static int mptable_add_intsrc(struct mp_config_table *mc,
 	const u32 *cell;
 	int i;
 
-	/* Legacy Interrupts */
-	debug("Writing ISA IRQs\n");
-	mptable_add_isa_interrupts(mc, bus_isa, apicid, 0);
-
 	/* Get I/O interrupt information from device tree */
 	node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_IRQ_ROUTER);
 	if (node < 0) {
@@ -330,12 +336,22 @@  static int mptable_add_intsrc(struct mp_config_table *mc,
 		}
 
 		dstirq = mp_determine_pci_dstirq(bus, dev, func, pr.pirq);
+		/*
+		 * For PIRQ which is connected to I/O APIC interrupt pin#0-15,
+		 * mark it as occupied so that we can skip it later.
+		 */
+		if (dstirq < 16)
+			isa_irq_occupied[dstirq] = true;
 		mp_write_pci_intsrc(mc, MP_INT, bus, dev, pr.pin,
 				    apicid, dstirq);
 		intsrc_entries++;
 		cell += sizeof(struct pirq_routing) / sizeof(u32);
 	}
 
+	/* Legacy Interrupts */
+	debug("Writing ISA IRQs\n");
+	mptable_add_isa_interrupts(mc, bus_isa, apicid, 0);
+
 	return 0;
 }