[U-Boot] [PATCH v6 07/12] arm: add Faraday FTINTC020 interrupt controller support
Kuo-Jung Su
dantesu at gmail.com
Thu Jul 4 05:40:39 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 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 | 156 ++++++++++++++++++++++++++++++++++++++
include/common.h | 3 +
include/faraday/ftintc020.h | 37 +++++++++
4 files changed, 197 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 ecb240a..35926c2 100644
--- a/arch/arm/cpu/faraday/Makefile
+++ b/arch/arm/cpu/faraday/Makefile
@@ -26,6 +26,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..542f616
--- /dev/null
+++ b/arch/arm/cpu/faraday/ftintc020.c
@@ -0,0 +1,156 @@
+/*
+ * arch/arm/cpu/faraday/ftintc020.c
+ *
+ * (C) Copyright 2013 Faraday Technology
+ * Dante Su <dantesu at faraday-tech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#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, ®s->irq32.scr);
+ else
+ writel(mask, ®s->irq64.scr);
+}
+
+void irq_enable(int irq)
+{
+ uint32_t mask = BIT_MASK(irq);
+
+ if (irq < 32)
+ setbits_le32(®s->irq32.ena, mask);
+ else
+ setbits_le32(®s->irq64.ena, mask);
+}
+
+void irq_disable(int irq)
+{
+ uint32_t mask = BIT_MASK(irq);
+
+ if (irq < 32)
+ clrbits_le32(®s->irq32.ena, mask);
+ else
+ clrbits_le32(®s->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(®s->irq32.tmr, mask);
+ else
+ setbits_le32(®s->irq64.tmr, mask);
+ } else {
+ if (irq < 32)
+ clrbits_le32(®s->irq32.tmr, mask);
+ else
+ clrbits_le32(®s->irq64.tmr, mask);
+ }
+
+ if (low) {
+ if (irq < 32)
+ setbits_le32(®s->irq32.tlr, mask);
+ else
+ setbits_le32(®s->irq64.tlr, mask);
+ } else {
+ if (irq < 32)
+ clrbits_le32(®s->irq32.tlr, mask);
+ else
+ clrbits_le32(®s->irq64.tlr, mask);
+ }
+}
+
+void do_irq(struct pt_regs *pt_regs)
+{
+ int irq;
+ uint32_t stat;
+
+ irq = 32;
+ stat = readl(®s->irq64.sr); /* IRQ 32 ~ 63 */
+ if (!stat) {
+ irq = 0;
+ stat = readl(®s->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, ®s->irq32.ena);
+ writel(0xffffffff, ®s->irq32.scr);
+ writel(0x00000000, ®s->irq32.tmr);
+ writel(0x00000000, ®s->irq32.tlr);
+
+ writel(0x00000000, ®s->irq64.ena);
+ writel(0xffffffff, ®s->irq64.scr);
+ writel(0x00000000, ®s->irq64.tmr);
+ writel(0x00000000, ®s->irq64.tlr);
+
+ return 0;
+}
diff --git a/include/common.h b/include/common.h
index e5220cf..ec3bf0d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -110,6 +110,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..e23d1e7
--- /dev/null
+++ b/include/faraday/ftintc020.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/cpu/faraday/ftintc020.h
+ *
+ * (C) Copyright 2010 Faraday Technology
+ * Dante Su <dantesu at faraday-tech.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ */
+
+#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