Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / arch / powerpc / kernel / machine_kexec.c
index a81ca1b..c0c8e8c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/reboot.h>
 #include <linux/threads.h>
 #include <asm/machdep.h>
+#include <asm/lmb.h>
 
 void machine_crash_shutdown(struct pt_regs *regs)
 {
@@ -59,3 +60,58 @@ NORET_TYPE void machine_kexec(struct kimage *image)
        }
        for(;;);
 }
+
+void __init reserve_crashkernel(void)
+{
+       unsigned long long crash_size, crash_base;
+       int ret;
+
+       /* this is necessary because of lmb_phys_mem_size() */
+       lmb_analyze();
+
+       /* use common parsing */
+       ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
+                       &crash_size, &crash_base);
+       if (ret == 0 && crash_size > 0) {
+               if (crash_base == 0)
+                       crash_base = KDUMP_KERNELBASE;
+               crashk_res.start = crash_base;
+       } else {
+               /* handle the device tree */
+               crash_size = crashk_res.end - crashk_res.start + 1;
+       }
+
+       if (crash_size == 0)
+               return;
+
+       /* We might have got these values via the command line or the
+        * device tree, either way sanitise them now. */
+
+       if (crashk_res.start != KDUMP_KERNELBASE)
+               printk("Crash kernel location must be 0x%x\n",
+                               KDUMP_KERNELBASE);
+
+       crashk_res.start = KDUMP_KERNELBASE;
+       crash_size = PAGE_ALIGN(crash_size);
+       crashk_res.end = crashk_res.start + crash_size - 1;
+
+       /* Crash kernel trumps memory limit */
+       if (memory_limit && memory_limit <= crashk_res.end) {
+               memory_limit = crashk_res.end + 1;
+               printk("Adjusted memory limit for crashkernel, now 0x%lx\n",
+                               memory_limit);
+       }
+
+       printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+                       "for crashkernel (System RAM: %ldMB)\n",
+                       (unsigned long)(crash_size >> 20),
+                       (unsigned long)(crashk_res.start >> 20),
+                       (unsigned long)(lmb_phys_mem_size() >> 20));
+
+       lmb_reserve(crashk_res.start, crash_size);
+}
+
+int overlaps_crashkernel(unsigned long start, unsigned long size)
+{
+       return (start + size) > crashk_res.start && start <= crashk_res.end;
+}