Merge branches 'irq/sparseirq' and 'linus' into irq/core
[safe/jmp/linux-2.6] / arch / powerpc / kernel / setup_32.c
index cd870a8..9e1ca74 100644 (file)
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/initrd.h>
-#if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE)
-#include <linux/ide.h>
-#endif
 #include <linux/tty.h>
 #include <linux/bootmem.h>
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
 #include <linux/console.h>
+#include <linux/lmb.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/time.h>
 #include <asm/serial.h>
 #include <asm/udbg.h>
+#include <asm/mmu_context.h>
 
 #include "setup.h"
 
 #define DBG(fmt...)
 
-#if defined CONFIG_KGDB
-#include <asm/kgdb.h>
-#endif
-
 extern void bootx_init(unsigned long r4, unsigned long phys);
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-struct ide_machdep_calls ppc_ide_md;
-EXPORT_SYMBOL(ppc_ide_md);
-#endif
-
 int boot_cpuid;
 EXPORT_SYMBOL_GPL(boot_cpuid);
 int boot_cpuid_phys;
 
+int smp_hw_index[NR_CPUS];
+
 unsigned long ISA_DMA_THRESHOLD;
 unsigned int DMA_MODE_READ;
 unsigned int DMA_MODE_WRITE;
 
-int have_of = 1;
-
 #ifdef CONFIG_VGA_CONSOLE
 unsigned long vgacon_remap_base;
 EXPORT_SYMBOL(vgacon_remap_base);
@@ -88,7 +78,7 @@ int ucache_bsize;
  * from the address that it was linked at, so we must use RELOC/PTRRELOC
  * to access static data (including strings).  -- paulus
  */
-unsigned long __init early_init(unsigned long dt_ptr)
+notrace unsigned long __init early_init(unsigned long dt_ptr)
 {
        unsigned long offset = reloc_offset();
        struct cpu_spec *spec;
@@ -108,6 +98,14 @@ unsigned long __init early_init(unsigned long dt_ptr)
                          PTRRELOC(&__start___ftr_fixup),
                          PTRRELOC(&__stop___ftr_fixup));
 
+       do_feature_fixups(spec->mmu_features,
+                         PTRRELOC(&__start___mmu_ftr_fixup),
+                         PTRRELOC(&__stop___mmu_ftr_fixup));
+
+       do_lwsync_fixups(spec->cpu_features,
+                        PTRRELOC(&__start___lwsync_fixup),
+                        PTRRELOC(&__stop___lwsync_fixup));
+
        return KERNELBASE + offset;
 }
 
@@ -118,7 +116,7 @@ unsigned long __init early_init(unsigned long dt_ptr)
  * This is called very early on the boot process, after a minimal
  * MMU environment has been set up but before MMU_init is called.
  */
-void __init machine_init(unsigned long dt_ptr, unsigned long phys)
+notrace void __init machine_init(unsigned long dt_ptr)
 {
        /* Enable early debugging if any specified (see udbg.h) */
        udbg_early_init();
@@ -128,19 +126,26 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys)
 
        probe_machine();
 
+       setup_kdump_trampoline();
+
 #ifdef CONFIG_6xx
        if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
            cpu_has_feature(CPU_FTR_CAN_NAP))
                ppc_md.power_save = ppc6xx_idle;
 #endif
 
+#ifdef CONFIG_E500
+       if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
+           cpu_has_feature(CPU_FTR_CAN_NAP))
+               ppc_md.power_save = e500_idle;
+#endif
        if (ppc_md.progress)
                ppc_md.progress("id mach(): done", 0x200);
 }
 
 #ifdef CONFIG_BOOKE_WDT
 /* Checks wdt=x and wdt_period=xx command-line option */
-int __init early_parse_wdt(char *p)
+notrace int __init early_parse_wdt(char *p)
 {
        if (p && strncmp(p, "0", 1) != 0)
               booke_wdt_enabled = 1;
@@ -172,6 +177,18 @@ int __init ppc_setup_l2cr(char *str)
 }
 __setup("l2cr=", ppc_setup_l2cr);
 
+/* Checks "l3cr=xxxx" command-line option */
+int __init ppc_setup_l3cr(char *str)
+{
+       if (cpu_has_feature(CPU_FTR_L3CR)) {
+               unsigned long val = simple_strtoul(str, NULL, 0);
+               printk(KERN_INFO "l3cr set to %lx\n", val);
+               _set_L3CR(val);         /* and enable it */
+       }
+       return 1;
+}
+__setup("l3cr=", ppc_setup_l3cr);
+
 #ifdef CONFIG_GENERIC_NVRAM
 
 /* Generic nvram hooks used by drivers/char/gen_nvram.c */
@@ -199,23 +216,12 @@ EXPORT_SYMBOL(nvram_sync);
 
 #endif /* CONFIG_NVRAM */
 
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
 int __init ppc_init(void)
 {
-       int cpu;
-
        /* clear the progress line */
        if (ppc_md.progress)
                ppc_md.progress("             ", 0xffff);
 
-       /* register CPU devices */
-       for_each_possible_cpu(cpu) {
-               struct cpu *c = &per_cpu(cpu_devices, cpu);
-               c->hotpluggable = 1;
-               register_cpu(c, cpu);
-       }
-
        /* call platform init */
        if (ppc_md.init != NULL) {
                ppc_md.init();
@@ -225,6 +231,46 @@ int __init ppc_init(void)
 
 arch_initcall(ppc_init);
 
+#ifdef CONFIG_IRQSTACKS
+static void __init irqstack_early_init(void)
+{
+       unsigned int i;
+
+       /* interrupt stacks must be in lowmem, we get that for free on ppc32
+        * as the lmb is limited to lowmem by LMB_REAL_LIMIT */
+       for_each_possible_cpu(i) {
+               softirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+               hardirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+       }
+}
+#else
+#define irqstack_early_init()
+#endif
+
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+static void __init exc_lvl_early_init(void)
+{
+       unsigned int i;
+
+       /* interrupt stacks must be in lowmem, we get that for free on ppc32
+        * as the lmb is limited to lowmem by LMB_REAL_LIMIT */
+       for_each_possible_cpu(i) {
+               critirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+#ifdef CONFIG_BOOKE
+               dbgirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+               mcheckirq_ctx[i] = (struct thread_info *)
+                       __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+#endif
+       }
+}
+#else
+#define exc_lvl_early_init()
+#endif
+
 /* Warning, IO base is not yet inited */
 void __init setup_arch(char **cmdline_p)
 {
@@ -248,18 +294,6 @@ void __init setup_arch(char **cmdline_p)
 
        xmon_setup();
 
-#if defined(CONFIG_KGDB)
-       if (ppc_md.kgdb_map_scc)
-               ppc_md.kgdb_map_scc();
-       set_debug_traps();
-       if (strstr(cmd_line, "gdb")) {
-               if (ppc_md.progress)
-                       ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
-               printk("kgdb breakpoint activated\n");
-               breakpoint();
-       }
-#endif
-
        /*
         * Set cache line size based on type of cpu as a default.
         * Systems with OF can look in the properties on the cpu node(s)
@@ -277,11 +311,15 @@ void __init setup_arch(char **cmdline_p)
        if (ppc_md.panic)
                setup_panic();
 
-       init_mm.start_code = PAGE_OFFSET;
+       init_mm.start_code = (unsigned long)_stext;
        init_mm.end_code = (unsigned long) _etext;
        init_mm.end_data = (unsigned long) _edata;
        init_mm.brk = klimit;
 
+       exc_lvl_early_init();
+
+       irqstack_early_init();
+
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
        if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
@@ -295,4 +333,8 @@ void __init setup_arch(char **cmdline_p)
        if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
        paging_init();
+
+       /* Initialize the MMU context management stuff */
+       mmu_context_init();
+
 }