aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/mpic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r--arch/powerpc/sysdev/mpic.c66
1 files changed, 55 insertions, 11 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index eb7021815e2d..3bf71035ff50 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -913,6 +913,20 @@ void mpic_set_vector(unsigned int virq, unsigned int vector)
913 mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); 913 mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
914} 914}
915 915
916void mpic_set_destination(unsigned int virq, unsigned int cpuid)
917{
918 struct mpic *mpic = mpic_from_irq(virq);
919 unsigned int src = mpic_irq_to_hw(virq);
920
921 DBG("mpic: set_destination(mpic:@%p,virq:%d,src:%d,cpuid:0x%x)\n",
922 mpic, virq, src, cpuid);
923
924 if (src >= mpic->irq_count)
925 return;
926
927 mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
928}
929
916static struct irq_chip mpic_irq_chip = { 930static struct irq_chip mpic_irq_chip = {
917 .irq_mask = mpic_mask_irq, 931 .irq_mask = mpic_mask_irq,
918 .irq_unmask = mpic_unmask_irq, 932 .irq_unmask = mpic_unmask_irq,
@@ -993,6 +1007,21 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
993 /* Set default irq type */ 1007 /* Set default irq type */
994 set_irq_type(virq, IRQ_TYPE_NONE); 1008 set_irq_type(virq, IRQ_TYPE_NONE);
995 1009
1010 /* If the MPIC was reset, then all vectors have already been
1011 * initialized. Otherwise, a per source lazy initialization
1012 * is done here.
1013 */
1014 if (!mpic_is_ipi(mpic, hw) && (mpic->flags & MPIC_NO_RESET)) {
1015 unsigned int cpu = 0;
1016
1017 if (mpic->flags & MPIC_PRIMARY)
1018 cpu = hard_smp_processor_id();
1019
1020 mpic_set_vector(virq, hw);
1021 mpic_set_destination(virq, cpu);
1022 mpic_irq_set_priority(virq, 8);
1023 }
1024
996 return 0; 1025 return 0;
997} 1026}
998 1027
@@ -1040,6 +1069,11 @@ static struct irq_host_ops mpic_host_ops = {
1040 .xlate = mpic_host_xlate, 1069 .xlate = mpic_host_xlate,
1041}; 1070};
1042 1071
1072static int mpic_reset_prohibited(struct device_node *node)
1073{
1074 return node && of_get_property(node, "pic-no-reset", NULL);
1075}
1076
1043/* 1077/*
1044 * Exported functions 1078 * Exported functions
1045 */ 1079 */
@@ -1160,7 +1194,15 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1160 mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); 1194 mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
1161 1195
1162 /* Reset */ 1196 /* Reset */
1163 if (flags & MPIC_WANTS_RESET) { 1197
1198 /* When using a device-node, reset requests are only honored if the MPIC
1199 * is allowed to reset.
1200 */
1201 if (mpic_reset_prohibited(node))
1202 mpic->flags |= MPIC_NO_RESET;
1203
1204 if ((flags & MPIC_WANTS_RESET) && !(mpic->flags & MPIC_NO_RESET)) {
1205 printk(KERN_DEBUG "mpic: Resetting\n");
1164 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), 1206 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
1165 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1207 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1166 | MPIC_GREG_GCONF_RESET); 1208 | MPIC_GREG_GCONF_RESET);
@@ -1325,17 +1367,19 @@ void __init mpic_init(struct mpic *mpic)
1325 else 1367 else
1326 cpu = 0; 1368 cpu = 0;
1327 1369
1328 for (i = 0; i < mpic->num_sources; i++) { 1370 if (!(mpic->flags & MPIC_NO_RESET)) {
1329 /* start with vector = source number, and masked */ 1371 for (i = 0; i < mpic->num_sources; i++) {
1330 u32 vecpri = MPIC_VECPRI_MASK | i | 1372 /* start with vector = source number, and masked */
1331 (8 << MPIC_VECPRI_PRIORITY_SHIFT); 1373 u32 vecpri = MPIC_VECPRI_MASK | i |
1374 (8 << MPIC_VECPRI_PRIORITY_SHIFT);
1332 1375
1333 /* check if protected */ 1376 /* check if protected */
1334 if (mpic->protected && test_bit(i, mpic->protected)) 1377 if (mpic->protected && test_bit(i, mpic->protected))
1335 continue; 1378 continue;
1336 /* init hw */ 1379 /* init hw */
1337 mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); 1380 mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
1338 mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << cpu); 1381 mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << cpu);
1382 }
1339 } 1383 }
1340 1384
1341 /* Init spurious vector */ 1385 /* Init spurious vector */