[U-Boot] [PATCH v2 13/30] x86: Set up edge triggering on interrupt 9

Simon Glass sjg at chromium.org
Sat Nov 15 02:18:31 CET 2014


Add this additional init in case it is needed by the OS.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Remove i8259 patch and just update the existing interrupt code

 arch/x86/include/asm/interrupt.h | 11 +++++++++++
 arch/x86/lib/pcat_interrupts.c   | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h
index 3f46e09..25abde7 100644
--- a/arch/x86/include/asm/interrupt.h
+++ b/arch/x86/include/asm/interrupt.h
@@ -27,4 +27,15 @@ void specific_eoi(int irq);
 
 extern char exception_stack[];
 
+/**
+ * configure_irq_trigger() - Configure IRQ triggering
+ *
+ * Switch the given interrupt to be level / edge triggered
+ *
+ * @param int_num legacy interrupt number (3-7, 9-15)
+ * @param is_level_triggered true for level triggered interrupt, false for
+ *	edge triggered interrupt
+ */
+void configure_irq_trigger(int int_num, bool is_level_triggered);
+
 #endif
diff --git a/arch/x86/lib/pcat_interrupts.c b/arch/x86/lib/pcat_interrupts.c
index 4c86f7f..2dc2fbd 100644
--- a/arch/x86/lib/pcat_interrupts.c
+++ b/arch/x86/lib/pcat_interrupts.c
@@ -62,6 +62,9 @@ int interrupt_init(void)
 	 */
 	unmask_irq(2);
 
+	/* Interrupt 9 should be level triggered (SCI). The OS might do this */
+	configure_irq_trigger(9, true);
+
 	enable_interrupts();
 
 	return 0;
@@ -114,3 +117,38 @@ void specific_eoi(int irq)
 
 	outb(OCW2_SEOI | irq, MASTER_PIC + OCW2);
 }
+
+#define ELCR1			0x4d0
+#define ELCR2			0x4d1
+
+void configure_irq_trigger(int int_num, bool is_level_triggered)
+{
+	u16 int_bits = inb(ELCR1) | (((u16)inb(ELCR2)) << 8);
+
+	debug("%s: current interrupts are 0x%x\n", __func__, int_bits);
+	if (is_level_triggered)
+		int_bits |= (1 << int_num);
+	else
+		int_bits &= ~(1 << int_num);
+
+	/* Write new values */
+	debug("%s: try to set interrupts 0x%x\n", __func__, int_bits);
+	outb((u8)(int_bits & 0xff), ELCR1);
+	outb((u8)(int_bits >> 8), ELCR2);
+
+#ifdef PARANOID_IRQ_TRIGGERS
+	/*
+	 * Try reading back the new values. This seems like an error but is
+	 * not
+	 */
+	if (inb(ELCR1) != (int_bits & 0xff)) {
+		printf("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
+		       __func__, (int_bits & 0xff), inb(ELCR1));
+	}
+
+	if (inb(ELCR2) != (int_bits >> 8)) {
+		printf("%s: higher order bits are wrong: want 0x%x, got 0x%x\n",
+		       __func__, (int_bits>>8), inb(ELCR2));
+	}
+#endif
+}
-- 
2.1.0.rc2.206.gedb03e5



More information about the U-Boot mailing list