[U-Boot] [PATCH v7 06/11] arm: add Faraday FTINTC020 interrupt controller support

Kuo-Jung Su dantesu at gmail.com
Mon Jul 29 07:51:48 CEST 2013


From: Kuo-Jung Su <dantesu at faraday-tech.com>

Signed-off-by: Kuo-Jung Su <dantesu at faraday-tech.com>
CC: Albert Aribaud <albert.u.boot at aribaud.net>
---
Changes for v7:
   - Update license to use SPDX identifiers.

Changes for v6:
   - Nothing updates

Changes for v5:
   - Coding Style cleanup.
   - Now the irq is always enabled inside irq_install_handler().

Changes for v4:
   - Coding Style cleanup.
   - Break up from [arm: add Faraday A36x SoC platform support]

Changes for v3:
   - Coding Style cleanup.
   - Drop macros for wirtel()/readl(), call them directly.
   - Always insert a blank line between declarations and code.
   - Add '__iomem' to all the declaration of HW register pointers.

Changes for v2:
   - Coding Style cleanup.
   - Use readl(), writel(), clrsetbits_le32() to replace REG() macros.
   - Use structure based hardware registers to replace the macro constants.
   - Replace BIT() with BIT_MASK().

 arch/arm/cpu/faraday/Makefile    |    1 +
 arch/arm/cpu/faraday/ftintc020.c |  144 ++++++++++++++++++++++++++++++++++++++
 include/common.h                 |    3 +
 include/faraday/ftintc020.h      |   36 ++++++++++
 4 files changed, 184 insertions(+)
 create mode 100644 arch/arm/cpu/faraday/ftintc020.c
 create mode 100644 include/faraday/ftintc020.h

diff --git a/arch/arm/cpu/faraday/Makefile b/arch/arm/cpu/faraday/Makefile
index acc09eb..6302a1d 100644
--- a/arch/arm/cpu/faraday/Makefile
+++ b/arch/arm/cpu/faraday/Makefile
@@ -10,6 +10,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).o

 src-y  := cpu.o
+src-$(CONFIG_FTINTC020)   += ftintc020.o

 START	= start.o
 COBJS	= $(src-y)
diff --git a/arch/arm/cpu/faraday/ftintc020.c b/arch/arm/cpu/faraday/ftintc020.c
new file mode 100644
index 0000000..bc36674
--- /dev/null
+++ b/arch/arm/cpu/faraday/ftintc020.c
@@ -0,0 +1,144 @@
+/*
+ * arch/arm/cpu/faraday/ftintc020.c
+ *
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu at faraday-tech.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include <faraday/ftintc020.h>
+
+static struct ftintc020_regs *regs = (void __iomem *)CONFIG_FTINTC020_BASE;
+
+static struct {
+	void  *data;
+	void (*func)(void *data);
+} irq_hndl[64];
+
+static inline void irq_acknowledge(int irq)
+{
+	uint32_t mask = BIT_MASK(irq);
+
+	if (irq < 32)
+		writel(mask, &regs->irq32.scr);
+	else
+		writel(mask, &regs->irq64.scr);
+}
+
+void irq_enable(int irq)
+{
+	uint32_t mask = BIT_MASK(irq);
+
+	if (irq < 32)
+		setbits_le32(&regs->irq32.ena, mask);
+	else
+		setbits_le32(&regs->irq64.ena, mask);
+}
+
+void irq_disable(int irq)
+{
+	uint32_t mask = BIT_MASK(irq);
+
+	if (irq < 32)
+		clrbits_le32(&regs->irq32.ena, mask);
+	else
+		clrbits_le32(&regs->irq64.ena, mask);
+}
+
+void irq_set_trigger(int irq, int edge, int low)
+{
+	uint32_t mask = BIT_MASK(irq);
+
+	if (edge) {
+		if (irq < 32)
+			setbits_le32(&regs->irq32.tmr, mask);
+		else
+			setbits_le32(&regs->irq64.tmr, mask);
+	} else {
+		if (irq < 32)
+			clrbits_le32(&regs->irq32.tmr, mask);
+		else
+			clrbits_le32(&regs->irq64.tmr, mask);
+	}
+
+	if (low) {
+		if (irq < 32)
+			setbits_le32(&regs->irq32.tlr, mask);
+		else
+			setbits_le32(&regs->irq64.tlr, mask);
+	} else {
+		if (irq < 32)
+			clrbits_le32(&regs->irq32.tlr, mask);
+		else
+			clrbits_le32(&regs->irq64.tlr, mask);
+	}
+}
+
+void do_irq(struct pt_regs *pt_regs)
+{
+	int irq;
+	uint32_t stat;
+
+	irq  = 32;
+	stat = readl(&regs->irq64.sr);     /* IRQ 32 ~ 63 */
+	if (!stat) {
+		irq  = 0;
+		stat = readl(&regs->irq32.sr); /* IRQ  0 ~ 31 */
+	}
+	irq += ffs(stat) - 1;
+
+	if (irq < 0) {
+		printf("interrupts: no irq!?\n");
+		return;
+	}
+
+	if (irq_hndl[irq].func)
+		irq_hndl[irq].func(irq_hndl[irq].data);
+	else
+		printf("Unhandled IRQ = %d\n", irq);
+
+	irq_acknowledge(irq);
+}
+
+void irq_install_handler(int irq, interrupt_handler_t *hndl, void *data)
+{
+	if (irq >= 0 && irq < 64) {
+		irq_hndl[irq].func = hndl;
+		irq_hndl[irq].data = data;
+		irq_enable(irq);
+	}
+}
+
+void irq_free_handler(int irq)
+{
+	if (irq >= 0 && irq < 64) {
+		irq_hndl[irq].func = NULL;
+		irq_hndl[irq].data = NULL;
+		irq_disable(irq);
+	}
+}
+
+int arch_interrupt_init(void)
+{
+	int i;
+
+	for (i = 0; i < 64; ++i)
+		irq_free_handler(i);
+
+	/* hardware reset */
+	writel(0x00000000, &regs->irq32.ena);
+	writel(0xffffffff, &regs->irq32.scr);
+	writel(0x00000000, &regs->irq32.tmr);
+	writel(0x00000000, &regs->irq32.tlr);
+
+	writel(0x00000000, &regs->irq64.ena);
+	writel(0xffffffff, &regs->irq64.scr);
+	writel(0x00000000, &regs->irq64.tmr);
+	writel(0x00000000, &regs->irq64.tlr);
+
+	return 0;
+}
diff --git a/include/common.h b/include/common.h
index 8addf43..dbebecf 100644
--- a/include/common.h
+++ b/include/common.h
@@ -94,6 +94,9 @@ typedef volatile unsigned char	vu_char;
 #ifdef CONFIG_SOC_DA8XX
 #include <asm/arch/hardware.h>
 #endif
+#ifdef CONFIG_FARADAY
+#include <asm/arch-faraday/interrupt.h>
+#endif

 #include <part.h>
 #include <flash.h>
diff --git a/include/faraday/ftintc020.h b/include/faraday/ftintc020.h
new file mode 100644
index 0000000..1afeb7c
--- /dev/null
+++ b/include/faraday/ftintc020.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/cpu/faraday/ftintc020.h
+ *
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu at faraday-tech.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef ARCH_ARM_CPU_FARADAY_FTINTC020_H
+#define ARCH_ARM_CPU_FARADAY_FTINTC020_H
+
+struct ftintc020_pic_regs {
+	uint32_t src; /* source register */
+	uint32_t ena; /* enable register */
+	uint32_t scr; /* status clear register */
+	uint32_t tmr; /* trigger mode register */
+	uint32_t tlr; /* trigger level register */
+	uint32_t sr;  /* status register */
+	uint32_t rsvd[2];
+};
+
+struct ftintc020_regs {
+	/* IRQ/FIQ:  0 ~ 31 */
+	struct ftintc020_pic_regs irq32; /* 0x00 - 0x1C: IRQ 0 ~ 31 */
+	struct ftintc020_pic_regs fiq32; /* 0x20 - 0x3C: FIQ 0 ~ 31 */
+	uint32_t rsvd1[4];               /* 0x40 - 0x4C: Reserved */
+	uint32_t revision;               /* 0x50: Revision Register */
+	uint32_t feature;                /* 0x54: Feature Register */
+	uint32_t rsvd2[2];               /* 0x58 - 0x5C: Reserved */
+	/* IRQ/FIQ: 32 ~ 63 */
+	struct ftintc020_pic_regs irq64; /* 0x60 - 0x7C: IRQ 32 ~ 63 */
+	struct ftintc020_pic_regs fiq64; /* 0x80 - 0x9C: FIQ 32 ~ 63 */
+};
+
+#endif
--
1.7.9.5



More information about the U-Boot mailing list