diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2007-02-08 02:33:55 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-02-13 19:50:03 -0500 |
commit | dce623e0827e8d0ad60ce7f385c3394bf1b0bae0 (patch) | |
tree | 5fc868fc1f365a40a949614dfc3982fc02f9219c /arch/powerpc | |
parent | 8feaeca23ab8f520e7af2a862fd6ea8e7bfd8854 (diff) |
[POWERPC] Cleanup pseries kexec code
Move all the pseries kexec code into one file, platforms/pseries/kexec.c
Provide helpers for setting up ppc_md.kexec_cpu_down, so that we don't
have to have #ifdef CONFIG_KEXEC in setup.c
Move the initialisation of the ppc_md kexec callbacks into an init routine.
This is well and truly early enough to cause no change in behaviour, we
can't kexec until userspace has given us a kernel to kexec into.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/pseries/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/kexec.c | 72 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pseries.h | 8 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 50 |
4 files changed, 83 insertions, 48 deletions
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 69590fbf83da..dc0583bdbc63 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_SMP) += smp.o | |||
9 | obj-$(CONFIG_XICS) += xics.o | 9 | obj-$(CONFIG_XICS) += xics.o |
10 | obj-$(CONFIG_SCANLOG) += scanlog.o | 10 | obj-$(CONFIG_SCANLOG) += scanlog.o |
11 | obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o | 11 | obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o |
12 | obj-$(CONFIG_KEXEC) += kexec.o | ||
12 | 13 | ||
13 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o | 14 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o |
14 | 15 | ||
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c new file mode 100644 index 000000000000..af2685607458 --- /dev/null +++ b/arch/powerpc/platforms/pseries/kexec.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Copyright 2006 Michael Ellerman, IBM Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <asm/machdep.h> | ||
11 | #include <asm/page.h> | ||
12 | #include <asm/firmware.h> | ||
13 | #include <asm/kexec.h> | ||
14 | #include <asm/mpic.h> | ||
15 | |||
16 | #include "pseries.h" | ||
17 | #include "xics.h" | ||
18 | #include "plpar_wrappers.h" | ||
19 | |||
20 | static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) | ||
21 | { | ||
22 | /* Don't risk a hypervisor call if we're crashing */ | ||
23 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { | ||
24 | unsigned long addr; | ||
25 | |||
26 | addr = __pa(get_slb_shadow()); | ||
27 | if (unregister_slb_shadow(hard_smp_processor_id(), addr)) | ||
28 | printk("SLB shadow buffer deregistration of " | ||
29 | "cpu %u (hw_cpu_id %d) failed\n", | ||
30 | smp_processor_id(), | ||
31 | hard_smp_processor_id()); | ||
32 | |||
33 | addr = __pa(get_lppaca()); | ||
34 | if (unregister_vpa(hard_smp_processor_id(), addr)) { | ||
35 | printk("VPA deregistration of cpu %u (hw_cpu_id %d) " | ||
36 | "failed\n", smp_processor_id(), | ||
37 | hard_smp_processor_id()); | ||
38 | } | ||
39 | } | ||
40 | } | ||
41 | |||
42 | static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary) | ||
43 | { | ||
44 | pseries_kexec_cpu_down(crash_shutdown, secondary); | ||
45 | mpic_teardown_this_cpu(secondary); | ||
46 | } | ||
47 | |||
48 | void __init setup_kexec_cpu_down_mpic(void) | ||
49 | { | ||
50 | ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_mpic; | ||
51 | } | ||
52 | |||
53 | static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary) | ||
54 | { | ||
55 | pseries_kexec_cpu_down(crash_shutdown, secondary); | ||
56 | xics_teardown_cpu(secondary); | ||
57 | } | ||
58 | |||
59 | void __init setup_kexec_cpu_down_xics(void) | ||
60 | { | ||
61 | ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_xics; | ||
62 | } | ||
63 | |||
64 | static int __init pseries_kexec_setup(void) | ||
65 | { | ||
66 | ppc_md.machine_kexec = default_machine_kexec; | ||
67 | ppc_md.machine_kexec_prepare = default_machine_kexec_prepare; | ||
68 | ppc_md.machine_crash_shutdown = default_machine_crash_shutdown; | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | __initcall(pseries_kexec_setup); | ||
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 36c791572682..b43f1397a5b6 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -25,4 +25,12 @@ static inline smp_init_pseries_mpic(void) { }; | |||
25 | static inline smp_init_pseries_xics(void) { }; | 25 | static inline smp_init_pseries_xics(void) { }; |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #ifdef CONFIG_KEXEC | ||
29 | extern void setup_kexec_cpu_down_xics(void); | ||
30 | extern void setup_kexec_cpu_down_mpic(void); | ||
31 | #else | ||
32 | static inline setup_kexec_cpu_down_xics(void) { }; | ||
33 | static inline setup_kexec_cpu_down_mpic(void) { }; | ||
34 | #endif | ||
35 | |||
28 | #endif /* _PSERIES_PSERIES_H */ | 36 | #endif /* _PSERIES_PSERIES_H */ |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 769815680be1..435a04596526 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -55,7 +55,6 @@ | |||
55 | #include <asm/dma.h> | 55 | #include <asm/dma.h> |
56 | #include <asm/machdep.h> | 56 | #include <asm/machdep.h> |
57 | #include <asm/irq.h> | 57 | #include <asm/irq.h> |
58 | #include <asm/kexec.h> | ||
59 | #include <asm/time.h> | 58 | #include <asm/time.h> |
60 | #include <asm/nvram.h> | 59 | #include <asm/nvram.h> |
61 | #include "xics.h" | 60 | #include "xics.h" |
@@ -219,42 +218,6 @@ static void pseries_lpar_enable_pmcs(void) | |||
219 | get_lppaca()->pmcregs_in_use = 1; | 218 | get_lppaca()->pmcregs_in_use = 1; |
220 | } | 219 | } |
221 | 220 | ||
222 | #ifdef CONFIG_KEXEC | ||
223 | static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) | ||
224 | { | ||
225 | /* Don't risk a hypervisor call if we're crashing */ | ||
226 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { | ||
227 | unsigned long addr; | ||
228 | |||
229 | addr = __pa(get_slb_shadow()); | ||
230 | if (unregister_slb_shadow(hard_smp_processor_id(), addr)) | ||
231 | printk("SLB shadow buffer deregistration of " | ||
232 | "cpu %u (hw_cpu_id %d) failed\n", | ||
233 | smp_processor_id(), | ||
234 | hard_smp_processor_id()); | ||
235 | |||
236 | addr = __pa(get_lppaca()); | ||
237 | if (unregister_vpa(hard_smp_processor_id(), addr)) { | ||
238 | printk("VPA deregistration of cpu %u (hw_cpu_id %d) " | ||
239 | "failed\n", smp_processor_id(), | ||
240 | hard_smp_processor_id()); | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | |||
245 | static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary) | ||
246 | { | ||
247 | pseries_kexec_cpu_down(crash_shutdown, secondary); | ||
248 | mpic_teardown_this_cpu(secondary); | ||
249 | } | ||
250 | |||
251 | static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary) | ||
252 | { | ||
253 | pseries_kexec_cpu_down(crash_shutdown, secondary); | ||
254 | xics_teardown_cpu(secondary); | ||
255 | } | ||
256 | #endif /* CONFIG_KEXEC */ | ||
257 | |||
258 | static void __init pseries_discover_pic(void) | 221 | static void __init pseries_discover_pic(void) |
259 | { | 222 | { |
260 | struct device_node *np; | 223 | struct device_node *np; |
@@ -267,16 +230,12 @@ static void __init pseries_discover_pic(void) | |||
267 | pSeries_mpic_node = of_node_get(np); | 230 | pSeries_mpic_node = of_node_get(np); |
268 | ppc_md.init_IRQ = pseries_mpic_init_IRQ; | 231 | ppc_md.init_IRQ = pseries_mpic_init_IRQ; |
269 | ppc_md.get_irq = mpic_get_irq; | 232 | ppc_md.get_irq = mpic_get_irq; |
270 | #ifdef CONFIG_KEXEC | 233 | setup_kexec_cpu_down_mpic(); |
271 | ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_mpic; | ||
272 | #endif | ||
273 | smp_init_pseries_mpic(); | 234 | smp_init_pseries_mpic(); |
274 | return; | 235 | return; |
275 | } else if (strstr(typep, "ppc-xicp")) { | 236 | } else if (strstr(typep, "ppc-xicp")) { |
276 | ppc_md.init_IRQ = xics_init_IRQ; | 237 | ppc_md.init_IRQ = xics_init_IRQ; |
277 | #ifdef CONFIG_KEXEC | 238 | setup_kexec_cpu_down_xics(); |
278 | ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_xics; | ||
279 | #endif | ||
280 | smp_init_pseries_xics(); | 239 | smp_init_pseries_xics(); |
281 | return; | 240 | return; |
282 | } | 241 | } |
@@ -548,9 +507,4 @@ define_machine(pseries) { | |||
548 | .check_legacy_ioport = pSeries_check_legacy_ioport, | 507 | .check_legacy_ioport = pSeries_check_legacy_ioport, |
549 | .system_reset_exception = pSeries_system_reset_exception, | 508 | .system_reset_exception = pSeries_system_reset_exception, |
550 | .machine_check_exception = pSeries_machine_check_exception, | 509 | .machine_check_exception = pSeries_machine_check_exception, |
551 | #ifdef CONFIG_KEXEC | ||
552 | .machine_kexec = default_machine_kexec, | ||
553 | .machine_kexec_prepare = default_machine_kexec_prepare, | ||
554 | .machine_crash_shutdown = default_machine_crash_shutdown, | ||
555 | #endif | ||
556 | }; | 510 | }; |