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.c70
1 files changed, 57 insertions, 13 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 212a94f5d34b..6ffdda244bb1 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,
@@ -265,7 +267,7 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
265 */ 267 */
266 268
267 269
268static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr, 270static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr,
269 struct mpic_reg_bank *rb, unsigned int offset, 271 struct mpic_reg_bank *rb, unsigned int offset,
270 unsigned int size) 272 unsigned int size)
271{ 273{
@@ -285,7 +287,7 @@ static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
285 BUG_ON(!DCR_MAP_OK(rb->dhost)); 287 BUG_ON(!DCR_MAP_OK(rb->dhost));
286} 288}
287 289
288static inline void mpic_map(struct mpic *mpic, unsigned long phys_addr, 290static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr,
289 struct mpic_reg_bank *rb, unsigned int offset, 291 struct mpic_reg_bank *rb, unsigned int offset,
290 unsigned int size) 292 unsigned int size)
291{ 293{
@@ -612,12 +614,11 @@ static inline void mpic_eoi(struct mpic *mpic)
612} 614}
613 615
614#ifdef CONFIG_SMP 616#ifdef CONFIG_SMP
615static irqreturn_t mpic_ipi_action(int irq, void *dev_id) 617static irqreturn_t mpic_ipi_action(int irq, void *data)
616{ 618{
617 struct mpic *mpic; 619 long ipi = (long)data;
618 620
619 mpic = mpic_find(irq, NULL); 621 smp_message_recv(ipi);
620 smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]);
621 622
622 return IRQ_HANDLED; 623 return IRQ_HANDLED;
623} 624}
@@ -842,6 +843,24 @@ int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
842 return 0; 843 return 0;
843} 844}
844 845
846void mpic_set_vector(unsigned int virq, unsigned int vector)
847{
848 struct mpic *mpic = mpic_from_irq(virq);
849 unsigned int src = mpic_irq_to_hw(virq);
850 unsigned int vecpri;
851
852 DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n",
853 mpic, virq, src, vector);
854
855 if (src >= mpic->irq_count)
856 return;
857
858 vecpri = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
859 vecpri = vecpri & ~MPIC_INFO(VECPRI_VECTOR_MASK);
860 vecpri |= vector;
861 mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
862}
863
845static struct irq_chip mpic_irq_chip = { 864static struct irq_chip mpic_irq_chip = {
846 .mask = mpic_mask_irq, 865 .mask = mpic_mask_irq,
847 .unmask = mpic_unmask_irq, 866 .unmask = mpic_unmask_irq,
@@ -1109,6 +1128,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1109 mb(); 1128 mb();
1110 } 1129 }
1111 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
1112 /* Read feature register, calculate num CPUs and, for non-ISU 1136 /* Read feature register, calculate num CPUs and, for non-ISU
1113 * MPICs, num sources as well. On ISU MPICs, sources are counted 1137 * MPICs, num sources as well. On ISU MPICs, sources are counted
1114 * as ISUs are added 1138 * as ISUs are added
@@ -1230,6 +1254,8 @@ void __init mpic_init(struct mpic *mpic)
1230 mpic_u3msi_init(mpic); 1254 mpic_u3msi_init(mpic);
1231 } 1255 }
1232 1256
1257 mpic_pasemi_msi_init(mpic);
1258
1233 for (i = 0; i < mpic->num_sources; i++) { 1259 for (i = 0; i < mpic->num_sources; i++) {
1234 /* start with vector = source number, and masked */ 1260 /* start with vector = source number, and masked */
1235 u32 vecpri = MPIC_VECPRI_MASK | i | 1261 u32 vecpri = MPIC_VECPRI_MASK | i |
@@ -1253,6 +1279,11 @@ void __init mpic_init(struct mpic *mpic)
1253 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) 1279 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1254 | MPIC_GREG_GCONF_8259_PTHROU_DIS); 1280 | MPIC_GREG_GCONF_8259_PTHROU_DIS);
1255 1281
1282 if (mpic->flags & MPIC_NO_BIAS)
1283 mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
1284 mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
1285 | MPIC_GREG_GCONF_NO_BIAS);
1286
1256 /* Set current processor priority to 0 */ 1287 /* Set current processor priority to 0 */
1257 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); 1288 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
1258 1289
@@ -1419,13 +1450,13 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
1419 mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); 1450 mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
1420} 1451}
1421 1452
1422unsigned int mpic_get_one_irq(struct mpic *mpic) 1453static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg)
1423{ 1454{
1424 u32 src; 1455 u32 src;
1425 1456
1426 src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK); 1457 src = mpic_cpu_read(reg) & MPIC_INFO(VECPRI_VECTOR_MASK);
1427#ifdef DEBUG_LOW 1458#ifdef DEBUG_LOW
1428 DBG("%s: get_one_irq(): %d\n", mpic->name, src); 1459 DBG("%s: get_one_irq(reg 0x%x): %d\n", mpic->name, reg, src);
1429#endif 1460#endif
1430 if (unlikely(src == mpic->spurious_vec)) { 1461 if (unlikely(src == mpic->spurious_vec)) {
1431 if (mpic->flags & MPIC_SPV_EOI) 1462 if (mpic->flags & MPIC_SPV_EOI)
@@ -1443,6 +1474,11 @@ unsigned int mpic_get_one_irq(struct mpic *mpic)
1443 return irq_linear_revmap(mpic->irqhost, src); 1474 return irq_linear_revmap(mpic->irqhost, src);
1444} 1475}
1445 1476
1477unsigned int mpic_get_one_irq(struct mpic *mpic)
1478{
1479 return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_INTACK));
1480}
1481
1446unsigned int mpic_get_irq(void) 1482unsigned int mpic_get_irq(void)
1447{ 1483{
1448 struct mpic *mpic = mpic_primary; 1484 struct mpic *mpic = mpic_primary;
@@ -1452,12 +1488,20 @@ unsigned int mpic_get_irq(void)
1452 return mpic_get_one_irq(mpic); 1488 return mpic_get_one_irq(mpic);
1453} 1489}
1454 1490
1491unsigned int mpic_get_mcirq(void)
1492{
1493 struct mpic *mpic = mpic_primary;
1494
1495 BUG_ON(mpic == NULL);
1496
1497 return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_MCACK));
1498}
1455 1499
1456#ifdef CONFIG_SMP 1500#ifdef CONFIG_SMP
1457void mpic_request_ipis(void) 1501void mpic_request_ipis(void)
1458{ 1502{
1459 struct mpic *mpic = mpic_primary; 1503 struct mpic *mpic = mpic_primary;
1460 int i, err; 1504 long i, err;
1461 static char *ipi_names[] = { 1505 static char *ipi_names[] = {
1462 "IPI0 (call function)", 1506 "IPI0 (call function)",
1463 "IPI1 (reschedule)", 1507 "IPI1 (reschedule)",
@@ -1472,14 +1516,14 @@ void mpic_request_ipis(void)
1472 unsigned int vipi = irq_create_mapping(mpic->irqhost, 1516 unsigned int vipi = irq_create_mapping(mpic->irqhost,
1473 mpic->ipi_vecs[0] + i); 1517 mpic->ipi_vecs[0] + i);
1474 if (vipi == NO_IRQ) { 1518 if (vipi == NO_IRQ) {
1475 printk(KERN_ERR "Failed to map IPI %d\n", i); 1519 printk(KERN_ERR "Failed to map IPI %ld\n", i);
1476 break; 1520 break;
1477 } 1521 }
1478 err = request_irq(vipi, mpic_ipi_action, 1522 err = request_irq(vipi, mpic_ipi_action,
1479 IRQF_DISABLED|IRQF_PERCPU, 1523 IRQF_DISABLED|IRQF_PERCPU,
1480 ipi_names[i], mpic); 1524 ipi_names[i], (void *)i);
1481 if (err) { 1525 if (err) {
1482 printk(KERN_ERR "Request of irq %d for IPI %d failed\n", 1526 printk(KERN_ERR "Request of irq %d for IPI %ld failed\n",
1483 vipi, i); 1527 vipi, i);
1484 break; 1528 break;
1485 } 1529 }