Right now just the kexec crash pathway turns turns off the interrupts.
Pull that out and make a generic version for use elsewhere
Signed-off-by: Matthew McClintock <msm@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
extern void crash_kexec_secondary(struct pt_regs *regs);
extern int overlaps_crashkernel(unsigned long start, unsigned long size);
extern void reserve_crashkernel(void);
+extern void machine_kexec_mask_interrupts(void);
#else /* !CONFIG_KEXEC */
static inline int kexec_sr_activated(int cpu) { return 0; }
crash_kexec_wait_realmode(crashing_cpu);
#endif
- for_each_irq(i) {
- struct irq_desc *desc = irq_to_desc(i);
-
- if (!desc || !desc->chip || !desc->chip->eoi)
- continue;
-
- if (desc->status & IRQ_INPROGRESS)
- desc->chip->eoi(i);
-
- if (!(desc->status & IRQ_DISABLED))
- desc->chip->shutdown(i);
- }
+ machine_kexec_mask_interrupts();
/*
* Call registered shutdown routines savely. Swap out
#include <linux/threads.h>
#include <linux/memblock.h>
#include <linux/of.h>
+#include <linux/irq.h>
+
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/sections.h>
+void machine_kexec_mask_interrupts(void) {
+ unsigned int i;
+
+ for_each_irq(i) {
+ struct irq_desc *desc = irq_to_desc(i);
+
+ if (!desc || !desc->chip)
+ continue;
+
+ if (desc->chip->eoi &&
+ desc->status & IRQ_INPROGRESS)
+ desc->chip->eoi(i);
+
+ if (desc->chip->mask)
+ desc->chip->mask(i);
+
+ if (desc->chip->disable &&
+ !(desc->status & IRQ_DISABLED))
+ desc->chip->disable(i);
+ }
+}
+
void machine_crash_shutdown(struct pt_regs *regs)
{
if (ppc_md.machine_crash_shutdown)
/* Interrupts aren't acceptable while we reboot */
local_irq_disable();
+ /* mask each interrupt so we are in a more sane state for the
+ * kexec kernel */
+ machine_kexec_mask_interrupts();
+
page_list = image->head;
/* we need both effective and real address here */