diff options
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index e47938899a92..f74fe26b787e 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -612,12 +612,11 @@ static inline void mpic_eoi(struct mpic *mpic) | |||
612 | } | 612 | } |
613 | 613 | ||
614 | #ifdef CONFIG_SMP | 614 | #ifdef CONFIG_SMP |
615 | static irqreturn_t mpic_ipi_action(int irq, void *dev_id) | 615 | static irqreturn_t mpic_ipi_action(int irq, void *data) |
616 | { | 616 | { |
617 | struct mpic *mpic; | 617 | long ipi = (long)data; |
618 | 618 | ||
619 | mpic = mpic_find(irq, NULL); | 619 | smp_message_recv(ipi); |
620 | smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]); | ||
621 | 620 | ||
622 | return IRQ_HANDLED; | 621 | return IRQ_HANDLED; |
623 | } | 622 | } |
@@ -842,6 +841,24 @@ int mpic_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
842 | return 0; | 841 | return 0; |
843 | } | 842 | } |
844 | 843 | ||
844 | void mpic_set_vector(unsigned int virq, unsigned int vector) | ||
845 | { | ||
846 | struct mpic *mpic = mpic_from_irq(virq); | ||
847 | unsigned int src = mpic_irq_to_hw(virq); | ||
848 | unsigned int vecpri; | ||
849 | |||
850 | DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n", | ||
851 | mpic, virq, src, vector); | ||
852 | |||
853 | if (src >= mpic->irq_count) | ||
854 | return; | ||
855 | |||
856 | vecpri = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); | ||
857 | vecpri = vecpri & ~MPIC_INFO(VECPRI_VECTOR_MASK); | ||
858 | vecpri |= vector; | ||
859 | mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); | ||
860 | } | ||
861 | |||
845 | static struct irq_chip mpic_irq_chip = { | 862 | static struct irq_chip mpic_irq_chip = { |
846 | .mask = mpic_mask_irq, | 863 | .mask = mpic_mask_irq, |
847 | .unmask = mpic_unmask_irq, | 864 | .unmask = mpic_unmask_irq, |
@@ -1230,6 +1247,8 @@ void __init mpic_init(struct mpic *mpic) | |||
1230 | mpic_u3msi_init(mpic); | 1247 | mpic_u3msi_init(mpic); |
1231 | } | 1248 | } |
1232 | 1249 | ||
1250 | mpic_pasemi_msi_init(mpic); | ||
1251 | |||
1233 | for (i = 0; i < mpic->num_sources; i++) { | 1252 | for (i = 0; i < mpic->num_sources; i++) { |
1234 | /* start with vector = source number, and masked */ | 1253 | /* start with vector = source number, and masked */ |
1235 | u32 vecpri = MPIC_VECPRI_MASK | i | | 1254 | u32 vecpri = MPIC_VECPRI_MASK | i | |
@@ -1457,7 +1476,7 @@ unsigned int mpic_get_irq(void) | |||
1457 | void mpic_request_ipis(void) | 1476 | void mpic_request_ipis(void) |
1458 | { | 1477 | { |
1459 | struct mpic *mpic = mpic_primary; | 1478 | struct mpic *mpic = mpic_primary; |
1460 | int i, err; | 1479 | long i, err; |
1461 | static char *ipi_names[] = { | 1480 | static char *ipi_names[] = { |
1462 | "IPI0 (call function)", | 1481 | "IPI0 (call function)", |
1463 | "IPI1 (reschedule)", | 1482 | "IPI1 (reschedule)", |
@@ -1472,14 +1491,14 @@ void mpic_request_ipis(void) | |||
1472 | unsigned int vipi = irq_create_mapping(mpic->irqhost, | 1491 | unsigned int vipi = irq_create_mapping(mpic->irqhost, |
1473 | mpic->ipi_vecs[0] + i); | 1492 | mpic->ipi_vecs[0] + i); |
1474 | if (vipi == NO_IRQ) { | 1493 | if (vipi == NO_IRQ) { |
1475 | printk(KERN_ERR "Failed to map IPI %d\n", i); | 1494 | printk(KERN_ERR "Failed to map IPI %ld\n", i); |
1476 | break; | 1495 | break; |
1477 | } | 1496 | } |
1478 | err = request_irq(vipi, mpic_ipi_action, | 1497 | err = request_irq(vipi, mpic_ipi_action, |
1479 | IRQF_DISABLED|IRQF_PERCPU, | 1498 | IRQF_DISABLED|IRQF_PERCPU, |
1480 | ipi_names[i], mpic); | 1499 | ipi_names[i], (void *)i); |
1481 | if (err) { | 1500 | if (err) { |
1482 | printk(KERN_ERR "Request of irq %d for IPI %d failed\n", | 1501 | printk(KERN_ERR "Request of irq %d for IPI %ld failed\n", |
1483 | vipi, i); | 1502 | vipi, i); |
1484 | break; | 1503 | break; |
1485 | } | 1504 | } |