diff options
author | Marcin Nowakowski <marcin.nowakowski@imgtec.com> | 2016-11-23 14:43:52 +0100 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2017-01-03 16:34:46 +0100 |
commit | 0014dea6b71ae3e0384c3358f632b4728c3d432e (patch) | |
tree | b0a968e6be956456fb92dd208f7f460e24a962dd /arch | |
parent | 856b0f591e951a234d6642cc466023df182eb51c (diff) | |
download | linux-stable-0014dea6b71ae3e0384c3358f632b4728c3d432e.tar.gz linux-stable-0014dea6b71ae3e0384c3358f632b4728c3d432e.tar.bz2 linux-stable-0014dea6b71ae3e0384c3358f632b4728c3d432e.zip |
MIPS: generic/kexec: add support for a DTB passed in a separate buffer
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14615/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/generic/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/generic/kexec.c | 44 |
2 files changed, 45 insertions, 0 deletions
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index 7c66494151db..acb9b6d62b16 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile @@ -13,3 +13,4 @@ obj-y += irq.o obj-y += proc.o obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o +obj-$(CONFIG_KEXEC) += kexec.o diff --git a/arch/mips/generic/kexec.c b/arch/mips/generic/kexec.c new file mode 100644 index 000000000000..e9fb735299e3 --- /dev/null +++ b/arch/mips/generic/kexec.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Marcin Nowakowski <marcin.nowakowski@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/kexec.h> +#include <linux/libfdt.h> +#include <linux/uaccess.h> + +static int generic_kexec_prepare(struct kimage *image) +{ + int i; + + for (i = 0; i < image->nr_segments; i++) { + struct fdt_header fdt; + + if (image->segment[i].memsz <= sizeof(fdt)) + continue; + + if (copy_from_user(&fdt, image->segment[i].buf, sizeof(fdt))) + continue; + + if (fdt_check_header(&fdt)) + continue; + + kexec_args[0] = -2; + kexec_args[1] = (unsigned long) + phys_to_virt((unsigned long)image->segment[i].mem); + break; + } + return 0; +} + +static int __init register_generic_kexec(void) +{ + _machine_kexec_prepare = generic_kexec_prepare; + return 0; +} +arch_initcall(register_generic_kexec); |