|
@@ -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,
|
|
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)
|
|
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)
|
|
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);
|
|
}
|
|
}
|
|
|
|
|