Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / arch / s390 / kernel / setup.c
index b1b9a93..863c8d0 100644 (file)
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/pfn.h>
+#include <linux/ctype.h>
 #include <linux/reboot.h>
 
+#include <asm/ipl.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/smp.h>
@@ -50,6 +52,7 @@
 #include <asm/page.h>
 #include <asm/ptrace.h>
 #include <asm/sections.h>
+#include <asm/ebcdic.h>
 #include <asm/compat.h>
 
 long psw_kernel_bits   = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
@@ -104,7 +107,7 @@ void __devinit cpu_init (void)
         /*
          * Store processor id in lowcore (used e.g. in timer_interrupt)
          */
-       asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id));
+       get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
         S390_lowcore.cpu_data.cpu_addr = addr;
 
         /*
@@ -127,7 +130,7 @@ char vmhalt_cmd[128] = "";
 char vmpoff_cmd[128] = "";
 static char vmpanic_cmd[128] = "";
 
-static inline void strncpy_skip_quote(char *dst, char *src, int n)
+static void strncpy_skip_quote(char *dst, char *src, int n)
 {
         int sx, dx;
 
@@ -394,8 +397,8 @@ early_param("ipldelay", early_parse_ipldelay);
 unsigned int switch_amode = 0;
 EXPORT_SYMBOL_GPL(switch_amode);
 
-static inline void set_amode_and_uaccess(unsigned long user_amode,
-                                        unsigned long user32_amode)
+static void set_amode_and_uaccess(unsigned long user_amode,
+                                 unsigned long user32_amode)
 {
        psw_user_bits = PSW_BASE_BITS | PSW_MASK_DAT | user_amode |
                        PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
@@ -523,7 +526,7 @@ setup_lowcore(void)
 static void __init
 setup_resources(void)
 {
-       struct resource *res;
+       struct resource *res, *sub_res;
        int i;
 
        code_resource.start = (unsigned long) &_text;
@@ -548,8 +551,38 @@ setup_resources(void)
                res->start = memory_chunk[i].addr;
                res->end = memory_chunk[i].addr +  memory_chunk[i].size - 1;
                request_resource(&iomem_resource, res);
-               request_resource(res, &code_resource);
-               request_resource(res, &data_resource);
+
+               if (code_resource.start >= res->start  &&
+                       code_resource.start <= res->end &&
+                       code_resource.end > res->end) {
+                       sub_res = alloc_bootmem_low(sizeof(struct resource));
+                       memcpy(sub_res, &code_resource,
+                               sizeof(struct resource));
+                       sub_res->end = res->end;
+                       code_resource.start = res->end + 1;
+                       request_resource(res, sub_res);
+               }
+
+               if (code_resource.start >= res->start &&
+                       code_resource.start <= res->end &&
+                       code_resource.end <= res->end)
+                       request_resource(res, &code_resource);
+
+               if (data_resource.start >= res->start &&
+                       data_resource.start <= res->end &&
+                       data_resource.end > res->end) {
+                       sub_res = alloc_bootmem_low(sizeof(struct resource));
+                       memcpy(sub_res, &data_resource,
+                               sizeof(struct resource));
+                       sub_res->end = res->end;
+                       data_resource.start = res->end + 1;
+                       request_resource(res, sub_res);
+               }
+
+               if (data_resource.start >= res->start &&
+                       data_resource.start <= res->end &&
+                       data_resource.end <= res->end)
+                       request_resource(res, &data_resource);
        }
 }
 
@@ -585,7 +618,7 @@ static void __init
 setup_memory(void)
 {
         unsigned long bootmap_size;
-       unsigned long start_pfn, end_pfn, init_pfn;
+       unsigned long start_pfn, end_pfn;
        int i;
 
        /*
@@ -595,10 +628,6 @@ setup_memory(void)
        start_pfn = PFN_UP(__pa(&_end));
        end_pfn = max_pfn = PFN_DOWN(memory_end);
 
-       /* Initialize storage key for kernel pages */
-       for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
-               page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
-
 #ifdef CONFIG_BLK_DEV_INITRD
        /*
         * Move the initrd in case the bitmap of the bootmem allocater
@@ -661,8 +690,13 @@ setup_memory(void)
        psw_set_key(PAGE_DEFAULT_KEY);
 
        free_bootmem_with_active_regions(0, max_pfn);
-       reserve_bootmem(0, PFN_PHYS(start_pfn));
 
+       /*
+        * Reserve memory used for lowcore/command line/kernel image.
+        */
+       reserve_bootmem(0, (unsigned long)_ehead);
+       reserve_bootmem((unsigned long)_stext,
+                       PFN_PHYS(start_pfn) - (unsigned long)_stext);
        /*
         * Reserve the bootmem bitmap itself as well. We do this in two
         * steps (first step was init_bootmem()) because this catches
@@ -712,7 +746,7 @@ setup_arch(char **cmdline_p)
 #endif /* CONFIG_64BIT */
 
        /* Save unparsed command line copy for /proc/cmdline */
-       strlcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
+       strlcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
 
        *cmdline_p = COMMAND_LINE;
        *(*cmdline_p + COMMAND_LINE_SIZE - 1) = '\0';
@@ -776,6 +810,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
         struct cpuinfo_S390 *cpuinfo;
        unsigned long n = (unsigned long) v - 1;
 
+       s390_adjust_jiffies();
        preempt_disable();
        if (!n) {
                seq_printf(m, "vendor_id       : IBM/S390\n"