xtensa: s6000 variant

Support for the Stretch S6000 Xtensa core variant.

Signed-off-by: Johannes Weiner <jw@emlix.com>
Signed-off-by: Oskar Schirmer <os@emlix.com>
Signed-off-by: Chris Zankel <chris@zankel.net>
diff --git a/arch/xtensa/variants/s6000/irq.c b/arch/xtensa/variants/s6000/irq.c
new file mode 100644
index 0000000..6651e32
--- /dev/null
+++ b/arch/xtensa/variants/s6000/irq.c
@@ -0,0 +1,74 @@
+/*
+ * s6000 irq crossbar
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors:	Johannes Weiner <jw@emlix.com>
+ *		Oskar Schirmer <os@emlix.com>
+ */
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <variant/hardware.h>
+
+/* S6_REG_INTC */
+#define INTC_STATUS	0x000
+#define INTC_RAW	0x010
+#define INTC_STATUS_AG	0x100
+#define INTC_CFG(n)	(0x200 + 4 * (n))
+
+/*
+ * The s6000 has a crossbar that multiplexes interrupt output lines
+ * from the peripherals to input lines on the xtensa core.
+ *
+ * We leave the mapping decisions to the platform as it depends on the
+ * actually connected peripherals which distribution makes sense.
+ */
+extern const signed char *platform_irq_mappings[NR_IRQS];
+
+static unsigned long scp_to_intc_enable[] = {
+#define	TO_INTC_ENABLE(n)	(((n) << 1) + 1)
+	TO_INTC_ENABLE(0),
+	TO_INTC_ENABLE(1),
+	TO_INTC_ENABLE(2),
+	TO_INTC_ENABLE(3),
+	TO_INTC_ENABLE(4),
+	TO_INTC_ENABLE(5),
+	TO_INTC_ENABLE(6),
+	TO_INTC_ENABLE(7),
+	TO_INTC_ENABLE(8),
+	TO_INTC_ENABLE(9),
+	TO_INTC_ENABLE(10),
+	TO_INTC_ENABLE(11),
+	TO_INTC_ENABLE(12),
+	-1,
+	-1,
+	TO_INTC_ENABLE(13),
+	-1,
+	TO_INTC_ENABLE(14),
+	-1,
+	TO_INTC_ENABLE(15),
+#undef	TO_INTC_ENABLE
+};
+
+static void irq_set(unsigned int irq, int enable)
+{
+	unsigned long en;
+	const signed char *m = platform_irq_mappings[irq];
+
+	if (!m)
+		return;
+	en = enable ? scp_to_intc_enable[irq] : 0;
+	while (*m >= 0) {
+		writel(en, S6_REG_INTC + INTC_CFG(*m));
+		m++;
+	}
+}
+
+void variant_irq_enable(unsigned int irq)
+{
+	irq_set(irq, 1);
+}
+
+void variant_irq_disable(unsigned int irq)
+{
+	irq_set(irq, 0);
+}