aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeador Inge <meador_inge@mentor.com>2011-03-14 06:01:06 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-03-20 20:01:32 -0400
commitdfec2202729e2460d67649a04756f0c3d8dcd8a6 (patch)
tree276d05c28bb7b1f8c170b118a6e81c37e86ea6fb
parenta99eff39c0549fe68fed150d39ec0c750e5ce1f1 (diff)
powerpc: Make MPIC honor the "pic-no-reset" device tree property
This property, defined in the Open PIC binding, tells the kernel not to use the reset bit in the global configuration register. Additionally, its presence mandates that only sources which are actually used (i.e. appear in the device tree) should have their VECPRI bits initialized. Although, "pic-no-reset" can be used for the same use cases that "protected-sources" is covering, the "protected-sources" implementation was left completely intact. This is a more pragmatic approach as there are already several existing systems which use protected sources. If "pic-no-reset" *and* "protected-sources" are both used, however, then "pic-no-reset" takes precedence in terms of the init behavior and the sanity checks done by protected sources will still take place. Signed-off-by: Meador Inge <meador_inge@mentor.com> Cc: Hollis Blanchard <hollis_blanchard@mentor.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/mpic.h4
-rw-r--r--arch/powerpc/sysdev/mpic.c66
2 files changed, 59 insertions, 11 deletions
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 946ec4947da..7005ee0b074 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -367,6 +367,10 @@ struct mpic
367#define MPIC_SINGLE_DEST_CPU 0x00001000 367#define MPIC_SINGLE_DEST_CPU 0x00001000
368/* Enable CoreInt delivery of interrupts */ 368/* Enable CoreInt delivery of interrupts */
369#define MPIC_ENABLE_COREINT 0x00002000 369#define MPIC_ENABLE_COREINT 0x00002000
370/* Disable resetting of the MPIC.
371 * NOTE: This flag trumps MPIC_WANTS_RESET.
372 */
373#define MPIC_NO_RESET 0x00004000
370 374
371/* MPIC HW modification ID */ 375/* MPIC HW modification ID */
372#define MPIC_REGSET_MASK 0xf0000000 376#define MPIC_REGSET_MASK 0xf0000000
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index eb7021815e2..3bf71035ff5 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 */