Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / arch / powerpc / platforms / chrp / setup.c
index 9c08ff3..18d89f3 100644 (file)
@@ -8,6 +8,7 @@
  * bootup setup stuff..
  */
 
+#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -24,7 +25,7 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/utsrelease.h>
+#include <linux/version.h>
 #include <linux/adb.h>
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -59,7 +60,7 @@ void rtas_indicator_progress(char *, unsigned short);
 int _chrp_type;
 EXPORT_SYMBOL(_chrp_type);
 
-static struct mpic *chrp_mpic;
+struct mpic *chrp_mpic;
 
 /* Used for doing CHRP event-scans */
 DEFINE_PER_CPU(struct timer_list, heartbeat_timer);
@@ -291,6 +292,10 @@ void __init chrp_setup_arch(void)
 
        pci_create_OF_bus_map();
 
+#ifdef CONFIG_SMP
+       smp_ops = &chrp_smp_ops;
+#endif /* CONFIG_SMP */
+
        /*
         * Print the banner, then scroll down so boot progress
         * can be printed.  -- Cort
@@ -311,32 +316,24 @@ chrp_event_scan(unsigned long unused)
                  jiffies + event_scan_interval);
 }
 
-static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc,
-                             struct pt_regs *regs)
-{
-       unsigned int cascade_irq = i8259_irq(regs);
-       if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq, regs);
-       desc->chip->eoi(irq);
-}
-
 /*
  * Finds the open-pic node and sets up the mpic driver.
  */
 static void __init chrp_find_openpic(void)
 {
        struct device_node *np, *root;
-       int len, i, j;
+       int len, i, j, irq_count;
        int isu_size, idu_size;
        unsigned int *iranges, *opprop = NULL;
        int oplen = 0;
        unsigned long opaddr;
        int na = 1;
+       unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
 
-       np = of_find_node_by_type(NULL, "open-pic");
+       np = find_type_devices("open-pic");
        if (np == NULL)
                return;
-       root = of_find_node_by_path("/");
+       root = find_path_device("/");
        if (root) {
                opprop = (unsigned int *) get_property
                        (root, "platform-open-pic", &oplen);
@@ -347,15 +344,19 @@ static void __init chrp_find_openpic(void)
                oplen /= na * sizeof(unsigned int);
        } else {
                struct resource r;
-               if (of_address_to_resource(np, 0, &r)) {
-                       goto bail;
-               }
+               if (of_address_to_resource(np, 0, &r))
+                       return;
                opaddr = r.start;
                oplen = 0;
        }
 
        printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
 
+       irq_count = NR_IRQS - NUM_ISA_INTERRUPTS - 4; /* leave room for IPIs */
+       prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS - 4);
+       /* i8259 cascade is always positive level */
+       init_senses[0] = IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE;
+
        iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
        if (iranges == NULL)
                len = 0;        /* non-distributed mpic */
@@ -382,12 +383,15 @@ static void __init chrp_find_openpic(void)
        if (len > 1)
                isu_size = iranges[3];
 
-       chrp_mpic = mpic_alloc(np, opaddr, MPIC_PRIMARY,
-                              isu_size, 0, " MPIC    ");
+       chrp_mpic = mpic_alloc(opaddr, MPIC_PRIMARY,
+                              isu_size, NUM_ISA_INTERRUPTS, irq_count,
+                              NR_IRQS - 4, init_senses, irq_count,
+                              " MPIC    ");
        if (chrp_mpic == NULL) {
                printk(KERN_ERR "Failed to allocate MPIC structure\n");
-               goto bail;
+               return;
        }
+
        j = na - 1;
        for (i = 1; i < len; ++i) {
                iranges += 2;
@@ -399,10 +403,7 @@ static void __init chrp_find_openpic(void)
        }
 
        mpic_init(chrp_mpic);
-       ppc_md.get_irq = mpic_get_irq;
- bail:
-       of_node_put(root);
-       of_node_put(np);
+       mpic_setup_cascade(NUM_ISA_INTERRUPTS, i8259_irq_cascade, NULL);
 }
 
 #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
@@ -413,34 +414,14 @@ static struct irqaction xmon_irqaction = {
 };
 #endif
 
-static void __init chrp_find_8259(void)
+void __init chrp_init_IRQ(void)
 {
-       struct device_node *np, *pic = NULL;
+       struct device_node *np;
        unsigned long chrp_int_ack = 0;
-       unsigned int cascade_irq;
-
-       /* Look for cascade */
-       for_each_node_by_type(np, "interrupt-controller")
-               if (device_is_compatible(np, "chrp,iic")) {
-                       pic = np;
-                       break;
-               }
-       /* Ok, 8259 wasn't found. We need to handle the case where
-        * we have a pegasos that claims to be chrp but doesn't have
-        * a proper interrupt tree
-        */
-       if (pic == NULL && chrp_mpic != NULL) {
-               printk(KERN_ERR "i8259: Not found in device-tree"
-                      " assuming no legacy interrupts\n");
-               return;
-       }
+#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
+       struct device_node *kbd;
+#endif
 
-       /* Look for intack. In a perfect world, we would look for it on
-        * the ISA bus that holds the 8259 but heh... Works that way. If
-        * we ever see a problem, we can try to re-use the pSeries code here.
-        * Also, Pegasos-type platforms don't have a proper node to start
-        * from anyway
-        */
        for (np = find_devices("pci"); np != NULL; np = np->next) {
                unsigned int *addrp = (unsigned int *)
                        get_property(np, "8259-interrupt-acknowledge", NULL);
@@ -451,37 +432,11 @@ static void __init chrp_find_8259(void)
                break;
        }
        if (np == NULL)
-               printk(KERN_WARNING "Cannot find PCI interrupt acknowledge"
-                      " address, polling\n");
-
-       i8259_init(pic, chrp_int_ack);
-       if (ppc_md.get_irq == NULL)
-               ppc_md.get_irq = i8259_irq;
-       if (chrp_mpic != NULL) {
-               cascade_irq = irq_of_parse_and_map(pic, 0);
-               if (cascade_irq == NO_IRQ)
-                       printk(KERN_ERR "i8259: failed to map cascade irq\n");
-               else
-                       set_irq_chained_handler(cascade_irq,
-                                               chrp_8259_cascade);
-       }
-}
+               printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n");
 
-void __init chrp_init_IRQ(void)
-{
-#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
-       struct device_node *kbd;
-#endif
        chrp_find_openpic();
-       chrp_find_8259();
 
-#ifdef CONFIG_SMP
-       /* Pegasos has no MPIC, those ops would make it crash. It might be an
-        * option to move setting them to after we probe the PIC though
-        */
-       if (chrp_mpic != NULL)
-               smp_ops = &chrp_smp_ops;
-#endif /* CONFIG_SMP */
+       i8259_init(chrp_int_ack, 0);
 
        if (_chrp_type == _CHRP_Pegasos)
                ppc_md.get_irq        = i8259_irq;
@@ -566,6 +521,10 @@ static int __init chrp_probe(void)
        DMA_MODE_READ = 0x44;
        DMA_MODE_WRITE = 0x48;
        isa_io_base = CHRP_ISA_IO_BASE;         /* default value */
+       ppc_do_canonicalize_irqs = 1;
+
+       /* Assume we have an 8259... */
+       __irq_offset_value = NUM_ISA_INTERRUPTS;
 
        return 1;
 }
@@ -577,6 +536,7 @@ define_machine(chrp) {
        .init                   = chrp_init2,
        .show_cpuinfo           = chrp_show_cpuinfo,
        .init_IRQ               = chrp_init_IRQ,
+       .get_irq                = mpic_get_irq,
        .pcibios_fixup          = chrp_pcibios_fixup,
        .restart                = rtas_restart,
        .power_off              = rtas_power_off,