linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / ppc / platforms / chrp_setup.c
index 57f29ab..48996b7 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
-#include <linux/irq.h>
 #include <linux/console.h>
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
@@ -54,6 +53,7 @@
 #include <asm/i8259.h>
 #include <asm/open_pic.h>
 #include <asm/xmon.h>
+#include "mem_pieces.h"
 
 unsigned long chrp_get_rtc_time(void);
 int chrp_set_rtc_time(unsigned long nowtime);
@@ -66,7 +66,6 @@ void rtas_display_progress(char *, unsigned short);
 void rtas_indicator_progress(char *, unsigned short);
 void btext_progress(char *, unsigned short);
 
-extern unsigned long pmac_find_end_of_memory(void);
 extern int of_show_percpuinfo(struct seq_file *, int);
 
 int _chrp_type;
@@ -105,7 +104,7 @@ static const char *gg2_cachemodes[4] = {
        "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
 };
 
-int __chrp
+int
 chrp_show_cpuinfo(struct seq_file *m)
 {
        int i, sdramen;
@@ -303,7 +302,7 @@ void __init chrp_setup_arch(void)
        pci_create_OF_bus_map();
 }
 
-void __chrp
+void
 chrp_event_scan(void)
 {
        unsigned char log[1024];
@@ -314,7 +313,7 @@ chrp_event_scan(void)
        ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
 }
 
-void __chrp
+void
 chrp_restart(char *cmd)
 {
        printk("RTAS system-reboot returned %d\n",
@@ -322,7 +321,7 @@ chrp_restart(char *cmd)
        for (;;);
 }
 
-void __chrp
+void
 chrp_power_off(void)
 {
        /* allow power on only with power button press */
@@ -331,20 +330,12 @@ chrp_power_off(void)
        for (;;);
 }
 
-void __chrp
+void
 chrp_halt(void)
 {
        chrp_power_off();
 }
 
-u_int __chrp
-chrp_irq_canonicalize(u_int irq)
-{
-       if (irq == 2)
-               return 9;
-       return irq;
-}
-
 /*
  * Finds the open-pic node and sets OpenPIC_Addr based on its reg property.
  * Then checks if it has an interrupt-ranges property.  If it does then
@@ -413,7 +404,6 @@ static struct irqaction xmon_irqaction = {
 void __init chrp_init_IRQ(void)
 {
        struct device_node *np;
-       int i;
        unsigned long chrp_int_ack = 0;
        unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
 #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
@@ -445,9 +435,7 @@ void __init chrp_init_IRQ(void)
                                       i8259_irq);
 
        }
-       for (i = 0; i < NUM_8259_INTERRUPTS; i++)
-               irq_desc[i].handler = &i8259_pic;
-       i8259_init(chrp_int_ack);
+       i8259_init(chrp_int_ack, 0);
 
 #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
        /* see if there is a keyboard in the device tree
@@ -465,8 +453,7 @@ void __init
 chrp_init2(void)
 {
 #ifdef CONFIG_NVRAM
-// XX replace this in a more saner way
-//     pmac_nvram_init();
+       chrp_nvram_init();
 #endif
 
        request_region(0x20,0x20,"pic1");
@@ -480,6 +467,75 @@ chrp_init2(void)
                ppc_md.progress("  Have fun!    ", 0x7777);
 }
 
+static struct device_node *memory_node;
+
+static int __init get_mem_prop(char *name, struct mem_pieces *mp)
+{
+       struct reg_property *rp;
+       int i, s;
+       unsigned int *ip;
+       int nac = prom_n_addr_cells(memory_node);
+       int nsc = prom_n_size_cells(memory_node);
+
+       ip = (unsigned int *) get_property(memory_node, name, &s);
+       if (ip == NULL) {
+               printk(KERN_ERR "error: couldn't get %s property on /memory\n",
+                      name);
+               return 0;
+       }
+       s /= (nsc + nac) * 4;
+       rp = mp->regions;
+       for (i = 0; i < s; ++i, ip += nac+nsc) {
+               if (nac >= 2 && ip[nac-2] != 0)
+                       continue;
+               rp->address = ip[nac-1];
+               if (nsc >= 2 && ip[nac+nsc-2] != 0)
+                       rp->size = ~0U;
+               else
+                       rp->size = ip[nac+nsc-1];
+               ++rp;
+       }
+       mp->n_regions = rp - mp->regions;
+
+       /* Make sure the pieces are sorted. */
+       mem_pieces_sort(mp);
+       mem_pieces_coalesce(mp);
+       return 1;
+}
+
+static unsigned long __init chrp_find_end_of_memory(void)
+{
+       unsigned long a, total;
+       struct mem_pieces phys_mem;
+
+       /*
+        * Find out where physical memory is, and check that it
+        * starts at 0 and is contiguous.  It seems that RAM is
+        * always physically contiguous on Power Macintoshes.
+        *
+        * Supporting discontiguous physical memory isn't hard,
+        * it just makes the virtual <-> physical mapping functions
+        * more complicated (or else you end up wasting space
+        * in mem_map).
+        */
+       memory_node = find_devices("memory");
+       if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
+           || phys_mem.n_regions == 0)
+               panic("No RAM??");
+       a = phys_mem.regions[0].address;
+       if (a != 0)
+               panic("RAM doesn't start at physical address 0");
+       total = phys_mem.regions[0].size;
+
+       if (phys_mem.n_regions > 1) {
+               printk("RAM starting at 0x%x is not contiguous\n",
+                      phys_mem.regions[1].address);
+               printk("Using RAM from 0 to 0x%lx\n", total-1);
+       }
+
+       return total;
+}
+
 void __init
 chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
          unsigned long r6, unsigned long r7)
@@ -500,6 +556,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
        DMA_MODE_READ = 0x44;
        DMA_MODE_WRITE = 0x48;
        isa_io_base = CHRP_ISA_IO_BASE;         /* default value */
+       ppc_do_canonicalize_irqs = 1;
 
        if (root)
                machine = get_property(root, "model", NULL);
@@ -518,7 +575,6 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
        ppc_md.show_percpuinfo = of_show_percpuinfo;
        ppc_md.show_cpuinfo   = chrp_show_cpuinfo;
 
-       ppc_md.irq_canonicalize = chrp_irq_canonicalize;
        ppc_md.init_IRQ       = chrp_init_IRQ;
        if (_chrp_type == _CHRP_Pegasos)
                ppc_md.get_irq        = i8259_irq;
@@ -538,7 +594,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
        ppc_md.get_rtc_time   = chrp_get_rtc_time;
        ppc_md.calibrate_decr = chrp_calibrate_decr;
 
-       ppc_md.find_end_of_memory = pmac_find_end_of_memory;
+       ppc_md.find_end_of_memory = chrp_find_end_of_memory;
 
        if (rtas_data) {
                struct device_node *rtas;
@@ -562,7 +618,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #endif
 
 #ifdef CONFIG_SMP
-       ppc_md.smp_ops = &chrp_smp_ops;
+       smp_ops = &chrp_smp_ops;
 #endif /* CONFIG_SMP */
 
        /*
@@ -572,7 +628,7 @@ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
        if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
 }
 
-void __chrp
+void
 rtas_display_progress(char *s, unsigned short hex)
 {
        int width;
@@ -599,7 +655,7 @@ rtas_display_progress(char *s, unsigned short hex)
        call_rtas( "display-character", 1, 1, NULL, ' ' );
 }
 
-void __chrp
+void
 rtas_indicator_progress(char *s, unsigned short hex)
 {
        call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);