]> git.hungrycats.org Git - linux/commitdiff
[PATCH] PPC32: 4xx core fixes and 440gx PIC support
authorAndrew Morton <akpm@osdl.org>
Fri, 14 May 2004 12:54:10 +0000 (05:54 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Fri, 14 May 2004 12:54:10 +0000 (05:54 -0700)
From: Matt Porter <mporter@kernel.crashing.org>

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

arch/ppc/boot/simple/embed_config.c
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/syslib/ppc405_pci.c
arch/ppc/syslib/ppc4xx_pic.c

index 3c3b31c9881900e44b7e63225a4d226d7bb78386..8f40dd1a17f947996ce16d2bbfca12d6dd6928f8 100644 (file)
@@ -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;
index c245b986441541e72f7b16b42f199c6d30dfe584..3a9d1473ffe7987427b3ffff052af1a292b72fbc 100644 (file)
@@ -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)
index c7f81e7054201ac946b16a1fcc872df035d9e3a4..7f94bdf39cbeab6c979cfc84c04d635efb4232a3 100644 (file)
@@ -57,14 +57,6 @@ ppc405_pcibios_fixup_resources(struct pci_dev *dev)
                    )
                    ) {
 
-                       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;
index 5bb8c2dd2de086a4dac1e3d2508aebe30a6563c1..7155625831de386575efb594e0a2eab88909db9d 100644 (file)
@@ -142,9 +142,12 @@ ppc403_aic_disable_and_ack(unsigned int irq)
 #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 irq)
        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 irq)
        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_uic = {
 #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++) {
 
@@ -397,6 +447,18 @@ ppc4xx_extpic_init(void)
                        /* Level setting */
                        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
-
 }