
From: Matt Porter <mporter@kernel.crashing.org>

Merge misc.  4xx core fixes and support for the new cascade scheme in the
440gx.


---

 25-akpm/arch/ppc/boot/simple/embed_config.c |    4 
 25-akpm/arch/ppc/kernel/ppc_ksyms.c         |    2 
 25-akpm/arch/ppc/syslib/ppc405_pci.c        |    8 -
 25-akpm/arch/ppc/syslib/ppc4xx_pic.c        |  145 +++++++++++++++++++++-------
 4 files changed, 113 insertions(+), 46 deletions(-)

diff -puN arch/ppc/boot/simple/embed_config.c~ppc32-4xx-core-fixes-and-440gx-pic-support arch/ppc/boot/simple/embed_config.c
--- 25/arch/ppc/boot/simple/embed_config.c~ppc32-4xx-core-fixes-and-440gx-pic-support	2004-05-12 16:58:15.060874600 -0700
+++ 25-akpm/arch/ppc/boot/simple/embed_config.c	2004-05-12 16:58:15.067873536 -0700
@@ -705,7 +705,7 @@ embed_config(bd_t ** bdp)
 #ifdef CONFIG_IBM_OPENBIOS
 /* This could possibly work for all treeboot roms.
 */
-#if defined(CONFIG_ASH) || defined(CONFIG_BEECH)
+#if defined(CONFIG_ASH) || defined(CONFIG_BEECH) || defined(CONFIG_BUBINGA)
 #define BOARD_INFO_VECTOR       0xFFF80B50 /* openbios 1.19 moved this vector down  - armin */
 #else
 #define BOARD_INFO_VECTOR	0xFFFE0B50
@@ -742,7 +742,7 @@ embed_config(bd_t **bdp)
 	 */
 	mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);     /* 1st reset MAL */
 	while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */	
-	out_be32(EMAC0_BASE,0x20000000);        /* then reset EMAC */
+	out_be32((volatile u32*)EMAC0_BASE,0x20000000);        /* then reset EMAC */
 #endif
 
 	bd = &bdinfo;
diff -puN arch/ppc/kernel/ppc_ksyms.c~ppc32-4xx-core-fixes-and-440gx-pic-support arch/ppc/kernel/ppc_ksyms.c
--- 25/arch/ppc/kernel/ppc_ksyms.c~ppc32-4xx-core-fixes-and-440gx-pic-support	2004-05-12 16:58:15.061874448 -0700
+++ 25-akpm/arch/ppc/kernel/ppc_ksyms.c	2004-05-12 16:58:15.068873384 -0700
@@ -336,7 +336,7 @@ EXPORT_SYMBOL(debugger_fault_handler);
 EXPORT_SYMBOL(cpm_install_handler);
 EXPORT_SYMBOL(cpm_free_handler);
 #endif /* CONFIG_8xx */
-#if defined(CONFIG_8xx) || defined(CONFIG_4xx)
+#if defined(CONFIG_8xx) || defined(CONFIG_40x)
 EXPORT_SYMBOL(__res);
 #endif
 #if defined(CONFIG_8xx)
diff -puN arch/ppc/syslib/ppc405_pci.c~ppc32-4xx-core-fixes-and-440gx-pic-support arch/ppc/syslib/ppc405_pci.c
--- 25/arch/ppc/syslib/ppc405_pci.c~ppc32-4xx-core-fixes-and-440gx-pic-support	2004-05-12 16:58:15.062874296 -0700
+++ 25-akpm/arch/ppc/syslib/ppc405_pci.c	2004-05-12 16:58:15.068873384 -0700
@@ -57,14 +57,6 @@ ppc405_pcibios_fixup_resources(struct pc
 		    )
 		    ) {
 
-			DBG(KERN_ERR "PCI: 0x%lx <= resource[%d] <= 0x%lx"
-			    ", bus 0x%x dev 0x%2.2x.%1.1x,\n"
-			    KERN_ERR "  %s\n"
-			    KERN_ERR "  fixup will be attempted later\n",
-			    min_host_addr, i, max_host_addr,
-			    dev->bus->number, PCI_SLOT(dev->devfn),
-			    PCI_FUNC(dev->devfn), dev->slot.name);
-
 			/* force pcibios_assign_resources() to assign a new address */
 			res->end -= res->start;
 			res->start = 0;
diff -puN arch/ppc/syslib/ppc4xx_pic.c~ppc32-4xx-core-fixes-and-440gx-pic-support arch/ppc/syslib/ppc4xx_pic.c
--- 25/arch/ppc/syslib/ppc4xx_pic.c~ppc32-4xx-core-fixes-and-440gx-pic-support	2004-05-12 16:58:15.064873992 -0700
+++ 25-akpm/arch/ppc/syslib/ppc4xx_pic.c	2004-05-12 16:58:15.070873080 -0700
@@ -142,9 +142,12 @@ ppc403_aic_disable_and_ack(unsigned int 
 #ifndef UIC1
 #define UIC1 UIC0
 #endif
+#ifndef UIC2
+#define UIC2 UIC1
+#endif
 
 static void
-ppc405_uic_enable(unsigned int irq)
+ppc4xx_uic_enable(unsigned int irq)
 {
 	int bit, word;
 	irq_desc_t *desc = irq_desc + irq;
@@ -153,7 +156,7 @@ ppc405_uic_enable(unsigned int irq)
 	word = irq >> 5;
 
 #ifdef UIC_DEBUG
-	printk("ppc405_uic_enable - irq %d word %d bit 0x%x\n", irq, word, bit);
+	printk("ppc4xx_uic_enable - irq %d word %d bit 0x%x\n", irq, word, bit);
 #endif
 	ppc_cached_irq_mask[word] |= 1 << (31 - bit);
 	switch (word) {
@@ -162,38 +165,35 @@ ppc405_uic_enable(unsigned int irq)
 		if ((mfdcr(DCRN_UIC_TR(UIC0)) & (1 << (31 - bit))) == 0)
 			desc->status |= IRQ_LEVEL;
 		else
-		/* lets hope this works since in linux/irq.h
-		 * there is no define for EDGE and it's assumed
-		 * once you set status to LEVEL you would not
-		 * want to change it - Armin
-		 */
-		desc->status = desc->status & ~IRQ_LEVEL;
+			desc->status = desc->status & ~IRQ_LEVEL;
 		break;
 	case 1:
 		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
 		if ((mfdcr(DCRN_UIC_TR(UIC1)) & (1 << (31 - bit))) == 0)
 			desc->status |= IRQ_LEVEL;
 		else
-		/* lets hope this works since in linux/irq.h
-		 * there is no define for EDGE and it's assumed
-		 * once you set status to LEVEL you would not
-		 * want to change it - Armin
-		 */
-		desc->status = desc->status & ~IRQ_LEVEL;
+			desc->status = desc->status & ~IRQ_LEVEL;
+	break;
+	case 2:
+		mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
+		if ((mfdcr(DCRN_UIC_TR(UIC2)) & (1 << (31 - bit))) == 0)
+			desc->status |= IRQ_LEVEL;
+		else
+			desc->status = desc->status & ~IRQ_LEVEL;
 	break;
 	}
 
 }
 
 static void
-ppc405_uic_disable(unsigned int irq)
+ppc4xx_uic_disable(unsigned int irq)
 {
 	int bit, word;
 
 	bit = irq & 0x1f;
 	word = irq >> 5;
 #ifdef UIC_DEBUG
-	printk("ppc405_uic_disable - irq %d word %d bit 0x%x\n", irq, word,
+	printk("ppc4xx_uic_disable - irq %d word %d bit 0x%x\n", irq, word,
 	       bit);
 #endif
 	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
@@ -204,11 +204,14 @@ ppc405_uic_disable(unsigned int irq)
 	case 1:
 		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
 		break;
+	case 2:
+		mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
+		break;
 	}
 }
 
 static void
-ppc405_uic_disable_and_ack(unsigned int irq)
+ppc4xx_uic_disable_and_ack(unsigned int irq)
 {
 	int bit, word;
 
@@ -216,7 +219,7 @@ ppc405_uic_disable_and_ack(unsigned int 
 	word = irq >> 5;
 
 #ifdef UIC_DEBUG
-	printk("ppc405_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq,
+	printk("ppc4xx_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq,
 	       word, bit);
 #endif
 	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
@@ -224,16 +227,30 @@ ppc405_uic_disable_and_ack(unsigned int 
 	case 0:
 		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
 		mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - bit)));
+#if (NR_UICS > 2)
+		mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
+#endif
 		break;
 	case 1:
 		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
 		mtdcr(DCRN_UIC_SR(UIC1), (1 << (31 - bit)));
+#if (NR_UICS > 2)
+		mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
+#endif
+		break;
+	case 2:
+		mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
+		mtdcr(DCRN_UIC_SR(UIC2), (1 << (31 - bit)));
+#if (NR_UICS > 2)
+		mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
+#endif
 		break;
 	}
+
 }
 
 static void
-ppc405_uic_end(unsigned int irq)
+ppc4xx_uic_end(unsigned int irq)
 {
 	int bit, word;
 	unsigned int tr_bits;
@@ -242,7 +259,7 @@ ppc405_uic_end(unsigned int irq)
 	word = irq >> 5;
 
 #ifdef UIC_DEBUG
-	printk("ppc405_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit);
+	printk("ppc4xx_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit);
 #endif
 
 	switch (word) {
@@ -259,9 +276,21 @@ ppc405_uic_end(unsigned int irq)
 		switch (word) {
 		case 0:
 			mtdcr(DCRN_UIC_SR(UIC0), 1 << (31 - bit));
+#if (NR_UICS > 2)
+			mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC0NC);
+#endif
 			break;
 		case 1:
 			mtdcr(DCRN_UIC_SR(UIC1), 1 << (31 - bit));
+#if (NR_UICS > 2)
+			mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC1NC);
+#endif
+			break;
+		case 2:
+			mtdcr(DCRN_UIC_SR(UIC2), 1 << (31 - bit));
+#if (NR_UICS > 2)
+			mtdcr(DCRN_UIC_SR(UICB),  UICB_UIC2NC);
+#endif
 			break;
 		}
 	}
@@ -275,11 +304,14 @@ ppc405_uic_end(unsigned int irq)
 		case 1:
 			mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
 			break;
+		case 2:
+			mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[word]);
+			break;
 		}
 	}
 }
 
-static struct hw_interrupt_type ppc405_uic = {
+static struct hw_interrupt_type ppc4xx_uic = {
 #if (NR_UICS == 1)
 	"IBM UIC",
 #else
@@ -287,15 +319,15 @@ static struct hw_interrupt_type ppc405_u
 #endif
 	NULL,
 	NULL,
-	ppc405_uic_enable,
-	ppc405_uic_disable,
-	ppc405_uic_disable_and_ack,
-	ppc405_uic_end,
+	ppc4xx_uic_enable,
+	ppc4xx_uic_disable,
+	ppc4xx_uic_disable_and_ack,
+	ppc4xx_uic_end,
 	0
 };
 
 int
-ppc405_pic_get_irq(struct pt_regs *regs)
+ppc4xx_pic_get_irq(struct pt_regs *regs)
 {
 	int irq, cas_irq;
 	unsigned long bits;
@@ -305,9 +337,25 @@ ppc405_pic_get_irq(struct pt_regs *regs)
 	 * enabled.
 	 */
 
+#if (NR_UICS > 2)
+	bits = mfdcr(DCRN_UIC_MSR(UICB));
+#else
 	bits = mfdcr(DCRN_UIC_MSR(UIC0));
-
-#if (NR_UICS > 1)
+#endif
+#if (NR_UICS > 2)
+	if (bits & UICB_UIC0NC) {
+		bits = mfdcr(DCRN_UIC_MSR(UIC0));
+		irq = 32 - ffs(bits);
+	} else if (bits & UICB_UIC1NC) {
+		bits = mfdcr(DCRN_UIC_MSR(UIC1));
+		irq = 64 - ffs(bits);
+	} else if (bits & UICB_UIC2NC) {
+		bits = mfdcr(DCRN_UIC_MSR(UIC2));
+		irq = 96 - ffs(bits);
+	} else {
+		irq = -1;
+	}
+#elif (NR_UICS > 1)
 	if (bits & UIC_CASCADE_MASK) {
 		bits = mfdcr(DCRN_UIC_MSR(UIC1));
 		cas_irq = 32 - ffs(bits);
@@ -330,7 +378,7 @@ ppc405_pic_get_irq(struct pt_regs *regs)
 		irq = -1;
 
 #ifdef UIC_DEBUG
-	printk("ppc405_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
+	printk("ppc4xx_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
 #endif
 
 	return (irq);
@@ -354,8 +402,10 @@ ppc4xx_extpic_init(void)
 	unsigned long ppc_cached_pol_mask[NR_MASK_WORDS];
 	ppc_cached_sense_mask[0] = 0;
 	ppc_cached_sense_mask[1] = 0;
+	ppc_cached_sense_mask[2] = 0;
 	ppc_cached_pol_mask[0] = 0;
 	ppc_cached_pol_mask[1] = 0;
+	ppc_cached_pol_mask[2] = 0;
 
 	for (irq = 0; irq < NR_IRQS; irq++) {
 
@@ -398,6 +448,18 @@ ppc4xx_extpic_init(void)
 			mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]);
 
 			break;
+		case 2:
+#ifdef PPC4xx_PIC_DEBUG
+			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC2)));
+			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC2)));
+#endif
+			/* polarity  setting */
+			mtdcr(DCRN_UIC_PR(UIC2), ppc_cached_pol_mask[word]);
+
+			/* Level setting */
+			mtdcr(DCRN_UIC_TR(UIC2), ppc_cached_sense_mask[word]);
+
+			break;
 		}
 	}
 
@@ -405,13 +467,13 @@ ppc4xx_extpic_init(void)
 void __init
 ppc4xx_pic_init(void)
 {
-
 	/*
 	 * Disable all external interrupts until they are
 	 * explicity requested.
 	 */
 	ppc_cached_irq_mask[0] = 0;
 	ppc_cached_irq_mask[1] = 0;
+	ppc_cached_irq_mask[2] = 0;
 
 #if defined CONFIG_403
 	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
@@ -419,11 +481,21 @@ ppc4xx_pic_init(void)
 	ppc4xx_pic = &ppc403_aic;
 	ppc_md.get_irq = ppc403_pic_get_irq;
 #else
+#if  (NR_UICS > 2)
+	mtdcr(DCRN_UIC_ER(UICB), UICB_UIC0NC | UICB_UIC1NC | UICB_UIC2NC);
+	mtdcr(DCRN_UIC_CR(UICB), 0);
+
+	mtdcr(DCRN_UIC_ER(UIC2), ppc_cached_irq_mask[2]);
+	mtdcr(DCRN_UIC_CR(UIC2), 0);
+
+#endif
 #if  (NR_UICS > 1)
-	ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC);	/* enable cascading interrupt */
+#if  (NR_UICS == 2)
+	/* enable cascading interrupt */
+	ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC);
+#endif
 	mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[1]);
 	mtdcr(DCRN_UIC_CR(UIC1), 0);
-
 #endif
 	mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
 	mtdcr(DCRN_UIC_CR(UIC0), 0);
@@ -432,13 +504,16 @@ ppc4xx_pic_init(void)
 		ppc4xx_extpic_init();
 
 	/* Clear any pending interrupts */
+#if (NR_UICS > 2)
+	mtdcr(DCRN_UIC_SR(UICB), 0xffffffff);
+	mtdcr(DCRN_UIC_SR(UIC2), 0xffffffff);
+#endif
 #if (NR_UICS > 1)
 	mtdcr(DCRN_UIC_SR(UIC1), 0xffffffff);
 #endif
 	mtdcr(DCRN_UIC_SR(UIC0), 0xffffffff);
 
-	ppc4xx_pic = &ppc405_uic;
-	ppc_md.get_irq = ppc405_pic_get_irq;
+	ppc4xx_pic = &ppc4xx_uic;
+	ppc_md.get_irq = ppc4xx_pic_get_irq;
 #endif
-
 }

_
