aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/crash.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index cca7c8fafc1c..8c066d6a8e4b 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -162,6 +162,32 @@ static void crash_kexec_prepare_cpus(int cpu)
162 /* Leave the IPI callback set */ 162 /* Leave the IPI callback set */
163} 163}
164 164
165/* wait for all the CPUs to hit real mode but timeout if they don't come in */
166static void crash_kexec_wait_realmode(int cpu)
167{
168 unsigned int msecs;
169 int i;
170
171 msecs = 10000;
172 for (i=0; i < NR_CPUS && msecs > 0; i++) {
173 if (i == cpu)
174 continue;
175
176 while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
177 barrier();
178 if (!cpu_possible(i)) {
179 break;
180 }
181 if (!cpu_online(i)) {
182 break;
183 }
184 msecs--;
185 mdelay(1);
186 }
187 }
188 mb();
189}
190
165/* 191/*
166 * This function will be called by secondary cpus or by kexec cpu 192 * This function will be called by secondary cpus or by kexec cpu
167 * if soft-reset is activated to stop some CPUs. 193 * if soft-reset is activated to stop some CPUs.
@@ -419,6 +445,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
419 crash_kexec_prepare_cpus(crashing_cpu); 445 crash_kexec_prepare_cpus(crashing_cpu);
420 cpu_set(crashing_cpu, cpus_in_crash); 446 cpu_set(crashing_cpu, cpus_in_crash);
421 crash_kexec_stop_spus(); 447 crash_kexec_stop_spus();
448 crash_kexec_wait_realmode(crashing_cpu);
422 if (ppc_md.kexec_cpu_down) 449 if (ppc_md.kexec_cpu_down)
423 ppc_md.kexec_cpu_down(1, 0); 450 ppc_md.kexec_cpu_down(1, 0);
424} 451}