aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/mpic.c32
-rw-r--r--include/asm-powerpc/mpic.h3
2 files changed, 35 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 75aad38179f0..74c64c0d3b71 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -877,6 +877,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
877 877
878 if (hw == mpic->spurious_vec) 878 if (hw == mpic->spurious_vec)
879 return -EINVAL; 879 return -EINVAL;
880 if (mpic->protected && test_bit(hw, mpic->protected))
881 return -EINVAL;
880 882
881#ifdef CONFIG_SMP 883#ifdef CONFIG_SMP
882 else if (hw >= mpic->ipi_vecs[0]) { 884 else if (hw >= mpic->ipi_vecs[0]) {
@@ -1034,6 +1036,25 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1034 if (node && of_get_property(node, "big-endian", NULL) != NULL) 1036 if (node && of_get_property(node, "big-endian", NULL) != NULL)
1035 mpic->flags |= MPIC_BIG_ENDIAN; 1037 mpic->flags |= MPIC_BIG_ENDIAN;
1036 1038
1039 /* Look for protected sources */
1040 if (node) {
1041 unsigned int psize, bits, mapsize;
1042 const u32 *psrc =
1043 of_get_property(node, "protected-sources", &psize);
1044 if (psrc) {
1045 psize /= 4;
1046 bits = intvec_top + 1;
1047 mapsize = BITS_TO_LONGS(bits) * sizeof(unsigned long);
1048 mpic->protected = alloc_bootmem(mapsize);
1049 BUG_ON(mpic->protected == NULL);
1050 memset(mpic->protected, 0, mapsize);
1051 for (i = 0; i < psize; i++) {
1052 if (psrc[i] > intvec_top)
1053 continue;
1054 __set_bit(psrc[i], mpic->protected);
1055 }
1056 }
1057 }
1037 1058
1038#ifdef CONFIG_MPIC_WEIRD 1059#ifdef CONFIG_MPIC_WEIRD
1039 mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; 1060 mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)];
@@ -1213,6 +1234,9 @@ void __init mpic_init(struct mpic *mpic)
1213 u32 vecpri = MPIC_VECPRI_MASK | i | 1234 u32 vecpri = MPIC_VECPRI_MASK | i |
1214 (8 << MPIC_VECPRI_PRIORITY_SHIFT); 1235 (8 << MPIC_VECPRI_PRIORITY_SHIFT);
1215 1236
1237 /* check if protected */
1238 if (mpic->protected && test_bit(i, mpic->protected))
1239 continue;
1216 /* init hw */ 1240 /* init hw */
1217 mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); 1241 mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
1218 mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1242 mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
@@ -1407,6 +1431,14 @@ unsigned int mpic_get_one_irq(struct mpic *mpic)
1407 mpic_eoi(mpic); 1431 mpic_eoi(mpic);
1408 return NO_IRQ; 1432 return NO_IRQ;
1409 } 1433 }
1434 if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
1435 if (printk_ratelimit())
1436 printk(KERN_WARNING "%s: Got protected source %d !\n",
1437 mpic->name, (int)src);
1438 mpic_eoi(mpic);
1439 return NO_IRQ;
1440 }
1441
1410 return irq_linear_revmap(mpic->irqhost, src); 1442 return irq_linear_revmap(mpic->irqhost, src);
1411} 1443}
1412 1444
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index 2ffb06abe881..262db6b8da73 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -296,6 +296,9 @@ struct mpic
296 unsigned int dcr_base; 296 unsigned int dcr_base;
297#endif 297#endif
298 298
299 /* Protected sources */
300 unsigned long *protected;
301
299#ifdef CONFIG_MPIC_WEIRD 302#ifdef CONFIG_MPIC_WEIRD
300 /* Pointer to HW info array */ 303 /* Pointer to HW info array */
301 u32 *hw_set; 304 u32 *hw_set;