summary refs log tree commit diff
path: root/arch/sh/kernel/machine_kexec.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-05-07 14:54:55 +0900
committerPaul Mundt <lethal@linux-sh.org>2010-05-07 14:54:55 +0900
commita5ec39507129a086d8838228ac1ca0a2eab38f91 (patch)
tree01c3cfa2f80aa3144b16c87e2cf769b605c7c889 /arch/sh/kernel/machine_kexec.c
parent9b7a37853a8cd69829eb1d9715a6c09aae01eeec (diff)
downloadlinux-a5ec39507129a086d8838228ac1ca0a2eab38f91.tar.gz
sh: convert kexec crash kernel management to LMB.
This migrates the crash kernel handling off of bootmem and over to LMB.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/machine_kexec.c')
-rw-r--r--arch/sh/kernel/machine_kexec.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 7672141c841b..f0f049caa6e2 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -8,7 +8,6 @@
  * This source code is licensed under the GNU General Public License,
  * Version 2.  See the file COPYING for more details.
  */
-
 #include <linux/mm.h>
 #include <linux/kexec.h>
 #include <linux/delay.h>
@@ -16,6 +15,7 @@
 #include <linux/numa.h>
 #include <linux/ftrace.h>
 #include <linux/suspend.h>
+#include <linux/lmb.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -148,3 +148,52 @@ void arch_crash_save_vmcoreinfo(void)
 	VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
 #endif
 }
+
+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();
+
+	ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
+			&crash_size, &crash_base);
+	if (ret == 0 && crash_size > 0) {
+		crashk_res.start = crash_base;
+		crashk_res.end = crash_base + crash_size - 1;
+	}
+
+	if (crashk_res.end == crashk_res.start)
+		goto disable;
+
+	crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1);
+	if (!crashk_res.start) {
+		crashk_res.start = lmb_alloc(crash_size, PAGE_SIZE);
+		if (!crashk_res.start) {
+			pr_err("crashkernel allocation failed\n");
+			goto disable;
+		}
+	} else {
+		ret = lmb_reserve(crashk_res.start, crash_size);
+		if (unlikely(ret < 0)) {
+			pr_err("crashkernel reservation failed - "
+			       "memory is in use\n");
+			goto disable;
+		}
+	}
+
+	pr_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));
+
+	crashk_res.end = crashk_res.start + crash_size - 1;
+	insert_resource(&iomem_resource, &crashk_res);
+
+	return;
+
+disable:
+	crashk_res.start = crashk_res.end = 0;
+}