Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c
new file mode 100644
index 0000000..4c4497e
--- /dev/null
+++ b/arch/ppc/syslib/mpc52xx_pic.c
@@ -0,0 +1,257 @@
+/*
+ * arch/ppc/syslib/mpc52xx_pic.c
+ *
+ * Programmable Interrupt Controller functions for the Freescale MPC52xx 
+ * embedded CPU.
+ *
+ * 
+ * Maintainer : Sylvain Munaut <tnt@246tNt.com>
+ *
+ * Based on (well, mostly copied from) the code from the 2.4 kernel by
+ * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
+ * 
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Montavista Software, Inc
+ * 
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/stddef.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/mpc52xx.h>
+
+
+static struct mpc52xx_intr __iomem *intr;
+static struct mpc52xx_sdma __iomem *sdma;
+
+static void
+mpc52xx_ic_disable(unsigned int irq)
+{
+	u32 val;
+
+	if (irq == MPC52xx_IRQ0) {
+		val = in_be32(&intr->ctrl);
+		val &= ~(1 << 11);
+		out_be32(&intr->ctrl, val);
+	}
+	else if (irq < MPC52xx_IRQ1) {
+		BUG();
+	}
+	else if (irq <= MPC52xx_IRQ3) {
+		val = in_be32(&intr->ctrl);
+		val &= ~(1 << (10 - (irq - MPC52xx_IRQ1)));
+		out_be32(&intr->ctrl, val);
+	}
+	else if (irq < MPC52xx_SDMA_IRQ_BASE) {
+		val = in_be32(&intr->main_mask);
+		val |= 1 << (16 - (irq - MPC52xx_MAIN_IRQ_BASE));
+		out_be32(&intr->main_mask, val);
+	}
+	else if (irq < MPC52xx_PERP_IRQ_BASE) {
+		val = in_be32(&sdma->IntMask);
+		val |= 1 << (irq - MPC52xx_SDMA_IRQ_BASE);
+		out_be32(&sdma->IntMask, val);
+	}
+	else {
+		val = in_be32(&intr->per_mask);
+		val |= 1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE));
+		out_be32(&intr->per_mask, val);
+	}
+}
+
+static void
+mpc52xx_ic_enable(unsigned int irq)
+{
+	u32 val;
+
+	if (irq == MPC52xx_IRQ0) {
+		val = in_be32(&intr->ctrl);
+		val |= 1 << 11;
+		out_be32(&intr->ctrl, val);
+	}
+	else if (irq < MPC52xx_IRQ1) {
+		BUG();
+	}
+	else if (irq <= MPC52xx_IRQ3) {
+		val = in_be32(&intr->ctrl);
+		val |= 1 << (10 - (irq - MPC52xx_IRQ1));
+		out_be32(&intr->ctrl, val);
+	}
+	else if (irq < MPC52xx_SDMA_IRQ_BASE) {
+		val = in_be32(&intr->main_mask);
+		val &= ~(1 << (16 - (irq - MPC52xx_MAIN_IRQ_BASE)));
+		out_be32(&intr->main_mask, val);
+	}
+	else if (irq < MPC52xx_PERP_IRQ_BASE) {
+		val = in_be32(&sdma->IntMask);
+		val &= ~(1 << (irq - MPC52xx_SDMA_IRQ_BASE));
+		out_be32(&sdma->IntMask, val);
+	}
+	else {
+		val = in_be32(&intr->per_mask);
+		val &= ~(1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE)));
+		out_be32(&intr->per_mask, val);
+	}
+}
+
+static void
+mpc52xx_ic_ack(unsigned int irq)
+{
+	u32 val;
+
+	/*
+	 * Only some irqs are reset here, others in interrupting hardware.
+	 */
+
+	switch (irq) {
+	case MPC52xx_IRQ0:
+		val = in_be32(&intr->ctrl);
+		val |= 0x08000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	case MPC52xx_CCS_IRQ:
+		val = in_be32(&intr->enc_status);
+		val |= 0x00000400;
+		out_be32(&intr->enc_status, val);
+		break;
+	case MPC52xx_IRQ1:
+		val = in_be32(&intr->ctrl);
+		val |= 0x04000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	case MPC52xx_IRQ2:
+		val = in_be32(&intr->ctrl);
+		val |= 0x02000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	case MPC52xx_IRQ3:
+		val = in_be32(&intr->ctrl);
+		val |= 0x01000000;
+		out_be32(&intr->ctrl, val);
+		break;
+	default:
+		if (irq >= MPC52xx_SDMA_IRQ_BASE
+		    && irq < (MPC52xx_SDMA_IRQ_BASE + MPC52xx_SDMA_IRQ_NUM)) {
+			out_be32(&sdma->IntPend,
+				 1 << (irq - MPC52xx_SDMA_IRQ_BASE));
+		}
+		break;
+	}
+}
+
+static void
+mpc52xx_ic_disable_and_ack(unsigned int irq)
+{
+	mpc52xx_ic_disable(irq);
+	mpc52xx_ic_ack(irq);
+}
+
+static void
+mpc52xx_ic_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		mpc52xx_ic_enable(irq);
+}
+
+static struct hw_interrupt_type mpc52xx_ic = {
+	.typename	= " MPC52xx  ",
+	.enable		= mpc52xx_ic_enable,
+	.disable	= mpc52xx_ic_disable,
+	.ack		= mpc52xx_ic_disable_and_ack,
+	.end		= mpc52xx_ic_end,
+};
+
+void __init
+mpc52xx_init_irq(void)
+{
+	int i;
+	u32 intr_ctrl;
+
+	/* Remap the necessary zones */
+	intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
+	sdma = ioremap(MPC52xx_PA(MPC52xx_SDMA_OFFSET), MPC52xx_SDMA_SIZE);
+
+	if ((intr==NULL) || (sdma==NULL))
+		panic("Can't ioremap PIC/SDMA register for init_irq !");
+
+	/* Disable all interrupt sources. */
+	out_be32(&sdma->IntPend, 0xffffffff);	/* 1 means clear pending */
+	out_be32(&sdma->IntMask, 0xffffffff);	/* 1 means disabled */
+	out_be32(&intr->per_mask, 0x7ffffc00);	/* 1 means disabled */
+	out_be32(&intr->main_mask, 0x00010fff);	/* 1 means disabled */
+	intr_ctrl = in_be32(&intr->ctrl);
+	intr_ctrl &=    0x00ff0000;	/* Keeps IRQ[0-3] config */
+	intr_ctrl |=	0x0f000000 |	/* clear IRQ 0-3 */
+			0x00001000 |	/* MEE master external enable */
+			0x00000000 |	/* 0 means disable IRQ 0-3 */
+			0x00000001;	/* CEb route critical normally */
+	out_be32(&intr->ctrl, intr_ctrl);
+
+	/* Zero a bunch of the priority settings.  */
+	out_be32(&intr->per_pri1, 0);
+	out_be32(&intr->per_pri2, 0);
+	out_be32(&intr->per_pri3, 0);
+	out_be32(&intr->main_pri1, 0);
+	out_be32(&intr->main_pri2, 0);
+
+	/* Initialize irq_desc[i].handler's with mpc52xx_ic. */
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].handler = &mpc52xx_ic;
+		irq_desc[i].status = IRQ_LEVEL;
+	}
+
+	#define IRQn_MODE(intr_ctrl,irq) (((intr_ctrl) >> (22-(i<<1))) & 0x03)
+	for (i=0 ; i<4 ; i++) {
+		int mode;
+		mode = IRQn_MODE(intr_ctrl,i);
+		if ((mode == 0x1) || (mode == 0x2))
+			irq_desc[i?MPC52xx_IRQ1+i-1:MPC52xx_IRQ0].status = 0;
+	}
+}
+
+int
+mpc52xx_get_irq(struct pt_regs *regs)
+{
+	u32 status;
+	int irq = -1;
+
+	status = in_be32(&intr->enc_status);
+
+	if (status & 0x00000400) {		/* critical */
+		irq = (status >> 8) & 0x3;
+		if (irq == 2)			/* high priority peripheral */
+			goto peripheral;
+		irq += MPC52xx_CRIT_IRQ_BASE;
+	}
+	else if (status & 0x00200000) {		/* main */
+		irq = (status >> 16) & 0x1f;
+		if (irq == 4)			/* low priority peripheral */
+			goto peripheral;
+		irq += MPC52xx_MAIN_IRQ_BASE;
+	}
+	else if (status & 0x20000000) {		/* peripheral */
+peripheral:
+		irq = (status >> 24) & 0x1f;
+		if (irq == 0) {			/* bestcomm */
+			status = in_be32(&sdma->IntPend);
+			irq = ffs(status) + MPC52xx_SDMA_IRQ_BASE-1;
+		}
+		else
+			irq += MPC52xx_PERP_IRQ_BASE;
+	}
+
+	return irq;
+}
+