summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2008-10-10 03:56:35 +0200
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-13 07:24:18 +0200
commit1a57c926b6da56b4f904a0d8117ac362724f8c66 (patch)
tree2143c7220c43b45de7401811edbe8c486956a276
parentpowerpc/xics: Factor out cpu joining/unjoining the GIQ (diff)
downloadlinux-1a57c926b6da56b4f904a0d8117ac362724f8c66.tar.xz
linux-1a57c926b6da56b4f904a0d8117ac362724f8c66.zip
powerpc/xics: EOI xics ipi by hand in kexec
EOI normally has the side effect of returning the cpu to the base priority to recieve the next interrupt. This is actually controlled by the top byte of the xirr register. When we are exiting the kernel in kexec we must eoi the ipi for the next kernel because we never return from the handler, but we want to leave interrupt delivery blocked until the next kernel takes action. Since the hardware ipi vector is fixed, its easiest to just do the eoi explicitly. Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/platforms/pseries/xics.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 0bb553331f4f..165234d25991 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -757,25 +757,21 @@ void xics_teardown_cpu(void)
void xics_kexec_teardown_cpu(int secondary)
{
- unsigned int ipi;
- struct irq_desc *desc;
-
xics_teardown_cpu();
/*
- * we need to EOI the IPI
+ * we take the ipi irq but and never return so we
+ * need to EOI the IPI, but want to leave our priority 0
*
- * probably need to check all the other interrupts too
+ * should we check all the other interrupts too?
* should we be flagging idle loop instead?
* or creating some task to be scheduled?
*/
- ipi = irq_find_mapping(xics_host, XICS_IPI);
- if (ipi == XICS_IRQ_SPURIOUS)
- return;
- desc = get_irq_desc(ipi);
- if (desc->chip && desc->chip->eoi)
- desc->chip->eoi(ipi);
+ if (firmware_has_feature(FW_FEATURE_LPAR))
+ lpar_xirr_info_set((0x00 << 24) | XICS_IPI);
+ else
+ direct_xirr_info_set((0x00 << 24) | XICS_IPI);
/*
* Some machines need to have at least one cpu in the GIQ,