diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
index 5c40bb6788df599c9b9c2d910ce2c647483b8334..4775f12a013c5b1a728b5f4ef57f81ef4f07e0be 100644
--- a/arch/ppc64/kernel/machine_kexec.c
+++ b/arch/ppc64/kernel/machine_kexec.c
@@ -185,7 +185,7 @@ void kexec_copy_flush(struct kimage *image)
 void kexec_smp_down(void *arg)
 {
 	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down();
+		ppc_md.cpu_irq_down(1);
 
 	local_irq_disable();
 	kexec_smp_wait();
@@ -232,7 +232,7 @@ static void kexec_prepare_cpus(void)
 
 	/* after we tell the others to go down */
 	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down();
+		ppc_md.cpu_irq_down(0);
 
 	put_cpu();
 
@@ -255,7 +255,7 @@ static void kexec_prepare_cpus(void)
 	 */
 	smp_release_cpus();
 	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down();
+		ppc_md.cpu_irq_down(0);
 	local_irq_disable();
 }
 
diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c
index e8fbab1df37f842cda79e59f8eb077228b93c6d9..cc262a05ddb4558499d649cf9c46d7610230f31f 100644
--- a/arch/ppc64/kernel/mpic.c
+++ b/arch/ppc64/kernel/mpic.c
@@ -794,10 +794,10 @@ void mpic_setup_this_cpu(void)
 
 /*
  * XXX: someone who knows mpic should check this.
- * do we need to eoi the ipi here (see xics comments)?
+ * do we need to eoi the ipi including for kexec cpu here (see xics comments)?
  * or can we reset the mpic in the new kernel?
  */
-void mpic_teardown_this_cpu(void)
+void mpic_teardown_this_cpu(int secondary)
 {
 	struct mpic *mpic = mpic_primary;
 	unsigned long flags;
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h
index 99fbbc9a084c46bec6e37789aca5987233177dd0..ca78a7f1052867de98d5fb06dbdbef4ec3b693e9 100644
--- a/arch/ppc64/kernel/mpic.h
+++ b/arch/ppc64/kernel/mpic.h
@@ -256,7 +256,7 @@ extern unsigned int mpic_irq_get_priority(unsigned int irq);
 extern void mpic_setup_this_cpu(void);
 
 /* Clean up for kexec (or cpu offline or ...) */
-extern void mpic_teardown_this_cpu(void);
+extern void mpic_teardown_this_cpu(int secondary);
 
 /* Request IPIs on primary mpic */
 extern void mpic_request_ipis(void);
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
index 677c4450984a85c3b53161f7409895309f907ce8..d9dc6f28d050050281ccc99e19e2d940de850abd 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -647,29 +647,30 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
 	}
 }
 
-void xics_teardown_cpu(void)
+void xics_teardown_cpu(int secondary)
 {
 	int cpu = smp_processor_id();
-	int status;
 
 	ops->cppr_info(cpu, 0x00);
 	iosync();
 
 	/*
-	 * we need to EOI the IPI if we got here from kexec down IPI
-	 *
-	 * xics doesn't care if we duplicate an EOI as long as we
-	 * don't EOI and raise priority.
-	 *
-	 * probably need to check all the other interrupts too
-	 * should we be flagging idle loop instead?
-	 * or creating some task to be scheduled?
+	 * Some machines need to have at least one cpu in the GIQ,
+	 * so leave the master cpu in the group.
 	 */
-	ops->xirr_info_set(cpu, XICS_IPI);
-
-	status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
-		(1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
-	WARN_ON(status != 0);
+	if (secondary) {
+		/*
+		 * we need to EOI the IPI if we got here from kexec down IPI
+		 *
+		 * probably need to check all the other interrupts too
+		 * should we be flagging idle loop instead?
+		 * or creating some task to be scheduled?
+		 */
+		ops->xirr_info_set(cpu, XICS_IPI);
+		rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+			(1UL << interrupt_server_size) - 1 -
+			default_distrib_server, 0);
+	}
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
index f0c1d2d926722aa2b4da7422aa5c033b8c0d3c51..f0ef06375947bbb86b634338a215575a3fb143c9 100644
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-ppc64/machdep.h
@@ -84,7 +84,7 @@ struct machdep_calls {
 
 	void		(*init_IRQ)(void);
 	int		(*get_irq)(struct pt_regs *);
-	void		(*cpu_irq_down)(void);
+	void		(*cpu_irq_down)(int secondary);
 
 	/* PCI stuff */
 	void		(*pcibios_fixup)(void);
diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h
index 0c45e14e26ca66d219035da90519703b7dbdac09..1092af55d7071a46f49fe11bbd501d2015496221 100644
--- a/include/asm-ppc64/xics.h
+++ b/include/asm-ppc64/xics.h
@@ -17,7 +17,7 @@
 void xics_init_IRQ(void);
 int xics_get_irq(struct pt_regs *);
 void xics_setup_cpu(void);
-void xics_teardown_cpu(void);
+void xics_teardown_cpu(int secondary);
 void xics_cause_IPI(int cpu);
 void xics_request_IPIs(void);
 void xics_migrate_irqs_away(void);