diff options
author | Dengcheng Zhu <dzhu@wavecomp.com> | 2018-09-11 17:49:24 -0400 |
---|---|---|
committer | Paul Burton <paul.burton@mips.com> | 2018-09-22 13:32:34 -0400 |
commit | 2fe8ea39c9a8489799cf86bb377fc80492b5b3bf (patch) | |
tree | a43f02b1275771b5cf99d1f1d784392e118bf069 | |
parent | a6da4d6fdf8bd512c98d3ac7f1d16bc4bb282919 (diff) |
MIPS: kexec: Use prepare method from Generic for UHI platforms
Out-of-tree platforms may not be based on Generic as shown in customer
communication. Share the prepare method with all using UHI boot protocol,
and put into machine_kexec.c.
The benefit is that, when having kexec_args related problems, developers
will naturally look into machine_kexec.c, where "CONFIG_UHI_BOOT" will be
found, prompting them to add "select UHI_BOOT" to the platform Kconfig. It
would otherwise require a lot debugging or online searching to be aware
that the solution is in Generic code.
Tested-by: Rachel Mozes <rachel.mozes@intel.com>
Reported-by: Rachel Mozes <rachel.mozes@intel.com>
Signed-off-by: Dengcheng Zhu <dzhu@wavecomp.com>
Signed-off-by: Paul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/20569/
Cc: pburton@wavecomp.com
Cc: ralf@linux-mips.org
Cc: linux-mips@linux-mips.org
-rw-r--r-- | arch/mips/Kconfig | 4 | ||||
-rw-r--r-- | arch/mips/generic/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/generic/kexec.c | 44 | ||||
-rw-r--r-- | arch/mips/kernel/machine_kexec.c | 42 |
4 files changed, 45 insertions, 46 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f744d25f7423..ce55c3c2d10d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -133,6 +133,7 @@ config MIPS_GENERIC | |||
133 | select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN | 133 | select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN |
134 | select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN | 134 | select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN |
135 | select USE_OF | 135 | select USE_OF |
136 | select UHI_BOOT | ||
136 | help | 137 | help |
137 | Select this to build a kernel which aims to support multiple boards, | 138 | Select this to build a kernel which aims to support multiple boards, |
138 | generally using a flattened device tree passed from the bootloader | 139 | generally using a flattened device tree passed from the bootloader |
@@ -2899,6 +2900,9 @@ config USE_OF | |||
2899 | select OF_EARLY_FLATTREE | 2900 | select OF_EARLY_FLATTREE |
2900 | select IRQ_DOMAIN | 2901 | select IRQ_DOMAIN |
2901 | 2902 | ||
2903 | config UHI_BOOT | ||
2904 | bool | ||
2905 | |||
2902 | config BUILTIN_DTB | 2906 | config BUILTIN_DTB |
2903 | bool | 2907 | bool |
2904 | 2908 | ||
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index d03a36f869a4..181aa1335419 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile | |||
@@ -15,5 +15,4 @@ obj-y += proc.o | |||
15 | obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o | 15 | obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o |
16 | obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o | 16 | obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o |
17 | obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o | 17 | obj-$(CONFIG_LEGACY_BOARD_OCELOT) += board-ocelot.o |
18 | obj-$(CONFIG_KEXEC) += kexec.o | ||
19 | obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o | 18 | obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o |
diff --git a/arch/mips/generic/kexec.c b/arch/mips/generic/kexec.c deleted file mode 100644 index 1ca409f58929..000000000000 --- a/arch/mips/generic/kexec.c +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Imagination Technologies | ||
3 | * Author: Marcin Nowakowski <marcin.nowakowski@mips.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kexec.h> | ||
12 | #include <linux/libfdt.h> | ||
13 | #include <linux/uaccess.h> | ||
14 | |||
15 | static int generic_kexec_prepare(struct kimage *image) | ||
16 | { | ||
17 | int i; | ||
18 | |||
19 | for (i = 0; i < image->nr_segments; i++) { | ||
20 | struct fdt_header fdt; | ||
21 | |||
22 | if (image->segment[i].memsz <= sizeof(fdt)) | ||
23 | continue; | ||
24 | |||
25 | if (copy_from_user(&fdt, image->segment[i].buf, sizeof(fdt))) | ||
26 | continue; | ||
27 | |||
28 | if (fdt_check_header(&fdt)) | ||
29 | continue; | ||
30 | |||
31 | kexec_args[0] = -2; | ||
32 | kexec_args[1] = (unsigned long) | ||
33 | phys_to_virt((unsigned long)image->segment[i].mem); | ||
34 | break; | ||
35 | } | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static int __init register_generic_kexec(void) | ||
40 | { | ||
41 | _machine_kexec_prepare = generic_kexec_prepare; | ||
42 | return 0; | ||
43 | } | ||
44 | arch_initcall(register_generic_kexec); | ||
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c index 14ced77c5ef6..35175eb2e8b0 100644 --- a/arch/mips/kernel/machine_kexec.c +++ b/arch/mips/kernel/machine_kexec.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/kexec.h> | 9 | #include <linux/kexec.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/libfdt.h> | ||
12 | 13 | ||
13 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
14 | #include <asm/page.h> | 15 | #include <asm/page.h> |
@@ -28,7 +29,6 @@ atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0); | |||
28 | void (*_crash_smp_send_stop)(void) = NULL; | 29 | void (*_crash_smp_send_stop)(void) = NULL; |
29 | #endif | 30 | #endif |
30 | 31 | ||
31 | int (*_machine_kexec_prepare)(struct kimage *) = NULL; | ||
32 | void (*_machine_kexec_shutdown)(void) = NULL; | 32 | void (*_machine_kexec_shutdown)(void) = NULL; |
33 | void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; | 33 | void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; |
34 | 34 | ||
@@ -52,6 +52,46 @@ static void kexec_image_info(const struct kimage *kimage) | |||
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | #ifdef CONFIG_UHI_BOOT | ||
56 | |||
57 | static int uhi_machine_kexec_prepare(struct kimage *kimage) | ||
58 | { | ||
59 | int i; | ||
60 | |||
61 | /* | ||
62 | * In case DTB file is not passed to the new kernel, a flat device | ||
63 | * tree will be created by kexec tool. It holds modified command | ||
64 | * line for the new kernel. | ||
65 | */ | ||
66 | for (i = 0; i < kimage->nr_segments; i++) { | ||
67 | struct fdt_header fdt; | ||
68 | |||
69 | if (kimage->segment[i].memsz <= sizeof(fdt)) | ||
70 | continue; | ||
71 | |||
72 | if (copy_from_user(&fdt, kimage->segment[i].buf, sizeof(fdt))) | ||
73 | continue; | ||
74 | |||
75 | if (fdt_check_header(&fdt)) | ||
76 | continue; | ||
77 | |||
78 | kexec_args[0] = -2; | ||
79 | kexec_args[1] = (unsigned long) | ||
80 | phys_to_virt((unsigned long)kimage->segment[i].mem); | ||
81 | break; | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | int (*_machine_kexec_prepare)(struct kimage *) = uhi_machine_kexec_prepare; | ||
88 | |||
89 | #else | ||
90 | |||
91 | int (*_machine_kexec_prepare)(struct kimage *) = NULL; | ||
92 | |||
93 | #endif /* CONFIG_UHI_BOOT */ | ||
94 | |||
55 | int | 95 | int |
56 | machine_kexec_prepare(struct kimage *kimage) | 96 | machine_kexec_prepare(struct kimage *kimage) |
57 | { | 97 | { |