aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2007-12-20 14:11:18 -0500
committerOlof Johansson <olof@lixom.net>2007-12-28 10:22:24 -0500
commitf365355e65ee619e3b7baeca69b46fd2c4a5ec68 (patch)
tree24133f987dc9ffe8f3a9b02355193e3d5113f8f2 /arch/powerpc/sysdev
parentc2a7dcad9f0d92d7a96e735abb8bec7b9c621536 (diff)
[POWERPC] pasemi: Implement NMI support
Some PWRficient-based boards have a NMI button that's wired up to a GPIO as interrupt source. By configuring the openpic accordingly, these get delivered as a machine check with high priority, instead of as an external interrupt. The device tree contains a property "nmi-source" in the openpic node for these systems, and it's the (hwirq) source for the input. Also, for these interrupts, the IACK is read from another register than the regular (MCACK instead), but they are EOI'd as usual. So implement said function for the mpic driver. Finally, move a couple of external function defines to include/ instead of local under sysdev. Being able to mask/unmask and eoi directly saves us from setting up a dummy irq handler that will never be called. Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/mpic.c26
-rw-r--r--arch/powerpc/sysdev/mpic.h3
2 files changed, 23 insertions, 6 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index f74fe26b787e..5a9d8c141e60 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -83,6 +83,7 @@ static u32 mpic_infos[][MPIC_IDX_END] = {
83 MPIC_CPU_WHOAMI, 83 MPIC_CPU_WHOAMI,
84 MPIC_CPU_INTACK, 84 MPIC_CPU_INTACK,
85 MPIC_CPU_EOI, 85 MPIC_CPU_EOI,
86 MPIC_CPU_MCACK,
86 87
87 MPIC_IRQ_BASE, 88 MPIC_IRQ_BASE,
88 MPIC_IRQ_STRIDE, 89 MPIC_IRQ_STRIDE,
@@ -121,6 +122,7 @@ static u32 mpic_infos[][MPIC_IDX_END] = {
121 TSI108_CPU_WHOAMI, 122 TSI108_CPU_WHOAMI,
122 TSI108_CPU_INTACK, 123 TSI108_CPU_INTACK,
123 TSI108_CPU_EOI, 124 TSI108_CPU_EOI,
125 TSI108_CPU_MCACK,
124 126
125 TSI108_IRQ_BASE, 127 TSI108_IRQ_BASE,
126 TSI108_IRQ_STRIDE, 128 TSI108_IRQ_STRIDE,
@@ -1126,6 +1128,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1126 mb(); 1128 mb();
1127 } 1129 }
1128 1130
1131 if (flags & MPIC_ENABLE_MCK)
1132 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
1133 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1134 | MPIC_GREG_GCONF_MCK);
1135
1129 /* Read feature register, calculate num CPUs and, for non-ISU 1136 /* Read feature register, calculate num CPUs and, for non-ISU
1130 * MPICs, num sources as well. On ISU MPICs, sources are counted 1137 * MPICs, num sources as well. On ISU MPICs, sources are counted
1131 * as ISUs are added 1138 * as ISUs are added
@@ -1438,13 +1445,13 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
1438 mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); 1445 mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
1439} 1446}
1440 1447
1441unsigned int mpic_get_one_irq(struct mpic *mpic) 1448static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg)
1442{ 1449{
1443 u32 src; 1450 u32 src;
1444 1451
1445 src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK); 1452 src = mpic_cpu_read(reg) & MPIC_INFO(VECPRI_VECTOR_MASK);
1446#ifdef DEBUG_LOW 1453#ifdef DEBUG_LOW
1447 DBG("%s: get_one_irq(): %d\n", mpic->name, src); 1454 DBG("%s: get_one_irq(reg 0x%x): %d\n", mpic->name, reg, src);
1448#endif 1455#endif
1449 if (unlikely(src == mpic->spurious_vec)) { 1456 if (unlikely(src == mpic->spurious_vec)) {
1450 if (mpic->flags & MPIC_SPV_EOI) 1457 if (mpic->flags & MPIC_SPV_EOI)
@@ -1462,6 +1469,11 @@ unsigned int mpic_get_one_irq(struct mpic *mpic)
1462 return irq_linear_revmap(mpic->irqhost, src); 1469 return irq_linear_revmap(mpic->irqhost, src);
1463} 1470}
1464 1471
1472unsigned int mpic_get_one_irq(struct mpic *mpic)
1473{
1474 return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_INTACK));
1475}
1476
1465unsigned int mpic_get_irq(void) 1477unsigned int mpic_get_irq(void)
1466{ 1478{
1467 struct mpic *mpic = mpic_primary; 1479 struct mpic *mpic = mpic_primary;
@@ -1471,6 +1483,14 @@ unsigned int mpic_get_irq(void)
1471 return mpic_get_one_irq(mpic); 1483 return mpic_get_one_irq(mpic);
1472} 1484}
1473 1485
1486unsigned int mpic_get_mcirq(void)
1487{
1488 struct mpic *mpic = mpic_primary;
1489
1490 BUG_ON(mpic == NULL);
1491
1492 return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_MCACK));
1493}
1474 1494
1475#ifdef CONFIG_SMP 1495#ifdef CONFIG_SMP
1476void mpic_request_ipis(void) 1496void mpic_request_ipis(void)
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index 4783c6e9f30d..fbf8a266941c 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -38,9 +38,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
38 38
39extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); 39extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
40extern void mpic_set_vector(unsigned int virq, unsigned int vector); 40extern void mpic_set_vector(unsigned int virq, unsigned int vector);
41extern void mpic_end_irq(unsigned int irq);
42extern void mpic_mask_irq(unsigned int irq);
43extern void mpic_unmask_irq(unsigned int irq);
44extern void mpic_set_affinity(unsigned int irq, cpumask_t cpumask); 41extern void mpic_set_affinity(unsigned int irq, cpumask_t cpumask);
45 42
46#endif /* _POWERPC_SYSDEV_MPIC_H */ 43#endif /* _POWERPC_SYSDEV_MPIC_H */