#include <asm/system.h>
 #include <asm/setjmp.h>
 
+/*
+ * The primary CPU waits a while for all secondary CPUs to enter. This is to
+ * avoid sending an IPI if the secondary CPUs are entering
+ * crash_kexec_secondary on their own (eg via a system reset).
+ *
+ * The secondary timeout has to be longer than the primary. Both timeouts are
+ * in milliseconds.
+ */
+#define PRIMARY_TIMEOUT                500
+#define SECONDARY_TIMEOUT      1000
+
+#define IPI_TIMEOUT            10000
+#define REAL_MODE_TIMEOUT      10000
+
 /* This keeps a track of which one is the crashing cpu. */
 int crashing_cpu = -1;
 static cpumask_t cpus_in_crash = CPU_MASK_NONE;
         * FIXME: Until we will have the way to stop other CPUs reliably,
         * the crash CPU will send an IPI and wait for other CPUs to
         * respond.
-        * Delay of at least 10 seconds.
         */
-       msecs = 10000;
+       msecs = IPI_TIMEOUT;
        while ((cpumask_weight(&cpus_in_crash) < ncpus) && (--msecs > 0)) {
-               cpu_relax();
                mdelay(1);
        }
 
 void crash_kexec_secondary(struct pt_regs *regs)
 {
        unsigned long flags;
-       int msecs = 500;
+       int msecs = SECONDARY_TIMEOUT;
 
        local_irq_save(flags);
 
-       /* Wait 500ms for the primary crash CPU to signal its progress */
+       /* Wait for the primary crash CPU to signal its progress */
        while (crashing_cpu < 0) {
                if (--msecs < 0) {
                        /* No response, kdump image may not have been loaded */
                }
 
                mdelay(1);
-               cpu_relax();
        }
 
        crash_ipi_callback(regs);
        unsigned int msecs;
        int i;
 
-       msecs = 10000;
+       msecs = REAL_MODE_TIMEOUT;
        for (i=0; i < nr_cpu_ids && msecs > 0; i++) {
                if (i == cpu)
                        continue;
         */
        crashing_cpu = smp_processor_id();
        crash_save_cpu(regs, crashing_cpu);
+
+       /*
+        * If we came in via system reset, wait a while for the secondary
+        * CPUs to enter.
+        */
+       if (TRAP(regs) == 0x100)
+               mdelay(PRIMARY_TIMEOUT);
+
        crash_kexec_prepare_cpus(crashing_cpu);
        cpumask_set_cpu(crashing_cpu, &cpus_in_crash);
        crash_kexec_wait_realmode(crashing_cpu);