Commit 8b1af56b authored by Paul Mackerras's avatar Paul Mackerras

powerpc: Fix i8259 cascade on pSeries with XICS interrupt controller

It turns out that commit f9bd170a
broke the cascade from XICS to i8259 on pSeries machines; specifically
we ended up not ever doing the EOI on the XICS for the cascade.  The
result was that interrupts from the serial ports (and presumably any
other devices using ISA interrupts) didn't get through.  This fixes
it and also simplifies the code, by doing the EOI on the XICS in the
xics_get_irq routine after reading and acking the interrupt on the
i8259.
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent d5ea4e26
...@@ -48,11 +48,6 @@ static struct hw_interrupt_type xics_pic = { ...@@ -48,11 +48,6 @@ static struct hw_interrupt_type xics_pic = {
.set_affinity = xics_set_affinity .set_affinity = xics_set_affinity
}; };
static struct hw_interrupt_type xics_8259_pic = {
.typename = " XICS/8259",
.ack = xics_mask_and_ack_irq,
};
/* This is used to map real irq numbers to virtual */ /* This is used to map real irq numbers to virtual */
static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC); static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC);
...@@ -367,12 +362,7 @@ int xics_get_irq(struct pt_regs *regs) ...@@ -367,12 +362,7 @@ int xics_get_irq(struct pt_regs *regs)
/* for sanity, this had better be < NR_IRQS - 16 */ /* for sanity, this had better be < NR_IRQS - 16 */
if (vec == xics_irq_8259_cascade_real) { if (vec == xics_irq_8259_cascade_real) {
irq = i8259_irq(regs); irq = i8259_irq(regs);
if (irq == -1) { xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
/* Spurious cascaded interrupt. Still must ack xics */
xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
irq = -1;
}
} else if (vec == XICS_IRQ_SPURIOUS) { } else if (vec == XICS_IRQ_SPURIOUS) {
irq = -1; irq = -1;
} else { } else {
...@@ -542,6 +532,7 @@ void xics_init_IRQ(void) ...@@ -542,6 +532,7 @@ void xics_init_IRQ(void)
xics_irq_8259_cascade_real = *ireg; xics_irq_8259_cascade_real = *ireg;
xics_irq_8259_cascade xics_irq_8259_cascade
= virt_irq_create_mapping(xics_irq_8259_cascade_real); = virt_irq_create_mapping(xics_irq_8259_cascade_real);
i8259_init(0, 0);
of_node_put(np); of_node_put(np);
} }
...@@ -565,12 +556,7 @@ void xics_init_IRQ(void) ...@@ -565,12 +556,7 @@ void xics_init_IRQ(void)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
} }
xics_8259_pic.enable = i8259_pic.enable; for (i = irq_offset_value(); i < NR_IRQS; ++i)
xics_8259_pic.disable = i8259_pic.disable;
xics_8259_pic.end = i8259_pic.end;
for (i = 0; i < 16; ++i)
get_irq_desc(i)->handler = &xics_8259_pic;
for (; i < NR_IRQS; ++i)
get_irq_desc(i)->handler = &xics_pic; get_irq_desc(i)->handler = &xics_pic;
xics_setup_cpu(); xics_setup_cpu();
...@@ -590,7 +576,6 @@ static int __init xics_setup_i8259(void) ...@@ -590,7 +576,6 @@ static int __init xics_setup_i8259(void)
no_action, 0, "8259 cascade", NULL)) no_action, 0, "8259 cascade", NULL))
printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 " printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 "
"cascade\n"); "cascade\n");
i8259_init(0, 0);
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment