diff options
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
| -rw-r--r-- | arch/powerpc/sysdev/mpic.c | 32 |
1 files changed, 32 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 | ||
