Commit 7fd72186 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Paul Mackerras

[POWERPC] MPIC protected sources

Some HW platforms, such as the new cell blades, requires some MPIC sources
to be left alone by the operating system. This implements support for
a "protected-sources" property in the mpic controller node containing a list
of source numbers to be protected against operating system interference.

For those interested in the gory details, the MPIC on the southbridge of
those blades has some of the processor outputs routed to the cell, and
at least one routed as a GPIO to the service processor. It will be used
in the GA product for routing some of the southbridge error interrupts
to the service processor which implements some of the RAS stuff, such
as checkstopping when fatal errors occurs before they can propagate.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 34f329db
...@@ -877,6 +877,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, ...@@ -877,6 +877,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
if (hw == mpic->spurious_vec) if (hw == mpic->spurious_vec)
return -EINVAL; return -EINVAL;
if (mpic->protected && test_bit(hw, mpic->protected))
return -EINVAL;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
else if (hw >= mpic->ipi_vecs[0]) { else if (hw >= mpic->ipi_vecs[0]) {
...@@ -1034,6 +1036,25 @@ struct mpic * __init mpic_alloc(struct device_node *node, ...@@ -1034,6 +1036,25 @@ struct mpic * __init mpic_alloc(struct device_node *node,
if (node && of_get_property(node, "big-endian", NULL) != NULL) if (node && of_get_property(node, "big-endian", NULL) != NULL)
mpic->flags |= MPIC_BIG_ENDIAN; mpic->flags |= MPIC_BIG_ENDIAN;
/* Look for protected sources */
if (node) {
unsigned int psize, bits, mapsize;
const u32 *psrc =
of_get_property(node, "protected-sources", &psize);
if (psrc) {
psize /= 4;
bits = intvec_top + 1;
mapsize = BITS_TO_LONGS(bits) * sizeof(unsigned long);
mpic->protected = alloc_bootmem(mapsize);
BUG_ON(mpic->protected == NULL);
memset(mpic->protected, 0, mapsize);
for (i = 0; i < psize; i++) {
if (psrc[i] > intvec_top)
continue;
__set_bit(psrc[i], mpic->protected);
}
}
}
#ifdef CONFIG_MPIC_WEIRD #ifdef CONFIG_MPIC_WEIRD
mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)];
...@@ -1213,6 +1234,9 @@ void __init mpic_init(struct mpic *mpic) ...@@ -1213,6 +1234,9 @@ void __init mpic_init(struct mpic *mpic)
u32 vecpri = MPIC_VECPRI_MASK | i | u32 vecpri = MPIC_VECPRI_MASK | i |
(8 << MPIC_VECPRI_PRIORITY_SHIFT); (8 << MPIC_VECPRI_PRIORITY_SHIFT);
/* check if protected */
if (mpic->protected && test_bit(i, mpic->protected))
continue;
/* init hw */ /* init hw */
mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
...@@ -1407,6 +1431,14 @@ unsigned int mpic_get_one_irq(struct mpic *mpic) ...@@ -1407,6 +1431,14 @@ unsigned int mpic_get_one_irq(struct mpic *mpic)
mpic_eoi(mpic); mpic_eoi(mpic);
return NO_IRQ; return NO_IRQ;
} }
if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
if (printk_ratelimit())
printk(KERN_WARNING "%s: Got protected source %d !\n",
mpic->name, (int)src);
mpic_eoi(mpic);
return NO_IRQ;
}
return irq_linear_revmap(mpic->irqhost, src); return irq_linear_revmap(mpic->irqhost, src);
} }
......
...@@ -296,6 +296,9 @@ struct mpic ...@@ -296,6 +296,9 @@ struct mpic
unsigned int dcr_base; unsigned int dcr_base;
#endif #endif
/* Protected sources */
unsigned long *protected;
#ifdef CONFIG_MPIC_WEIRD #ifdef CONFIG_MPIC_WEIRD
/* Pointer to HW info array */ /* Pointer to HW info array */
u32 *hw_set; u32 *hw_set;
......
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