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.c84
1 files changed, 39 insertions, 45 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 30c44e6b0413..260295b10557 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -26,6 +26,7 @@
26#include <linux/bootmem.h> 26#include <linux/bootmem.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <linux/slab.h>
29 30
30#include <asm/ptrace.h> 31#include <asm/ptrace.h>
31#include <asm/signal.h> 32#include <asm/signal.h>
@@ -46,7 +47,7 @@
46 47
47static struct mpic *mpics; 48static struct mpic *mpics;
48static struct mpic *mpic_primary; 49static struct mpic *mpic_primary;
49static DEFINE_SPINLOCK(mpic_lock); 50static DEFINE_RAW_SPINLOCK(mpic_lock);
50 51
51#ifdef CONFIG_PPC32 /* XXX for now */ 52#ifdef CONFIG_PPC32 /* XXX for now */
52#ifdef CONFIG_IRQ_ALL_CPUS 53#ifdef CONFIG_IRQ_ALL_CPUS
@@ -347,10 +348,10 @@ static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
347 unsigned int mask = 1U << (fixup->index & 0x1f); 348 unsigned int mask = 1U << (fixup->index & 0x1f);
348 writel(mask, fixup->applebase + soff); 349 writel(mask, fixup->applebase + soff);
349 } else { 350 } else {
350 spin_lock(&mpic->fixup_lock); 351 raw_spin_lock(&mpic->fixup_lock);
351 writeb(0x11 + 2 * fixup->index, fixup->base + 2); 352 writeb(0x11 + 2 * fixup->index, fixup->base + 2);
352 writel(fixup->data, fixup->base + 4); 353 writel(fixup->data, fixup->base + 4);
353 spin_unlock(&mpic->fixup_lock); 354 raw_spin_unlock(&mpic->fixup_lock);
354 } 355 }
355} 356}
356 357
@@ -366,7 +367,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
366 367
367 DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n", 368 DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n",
368 source, irqflags, fixup->index); 369 source, irqflags, fixup->index);
369 spin_lock_irqsave(&mpic->fixup_lock, flags); 370 raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
370 /* Enable and configure */ 371 /* Enable and configure */
371 writeb(0x10 + 2 * fixup->index, fixup->base + 2); 372 writeb(0x10 + 2 * fixup->index, fixup->base + 2);
372 tmp = readl(fixup->base + 4); 373 tmp = readl(fixup->base + 4);
@@ -374,7 +375,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
374 if (irqflags & IRQ_LEVEL) 375 if (irqflags & IRQ_LEVEL)
375 tmp |= 0x22; 376 tmp |= 0x22;
376 writel(tmp, fixup->base + 4); 377 writel(tmp, fixup->base + 4);
377 spin_unlock_irqrestore(&mpic->fixup_lock, flags); 378 raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
378 379
379#ifdef CONFIG_PM 380#ifdef CONFIG_PM
380 /* use the lowest bit inverted to the actual HW, 381 /* use the lowest bit inverted to the actual HW,
@@ -396,12 +397,12 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
396 DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags); 397 DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags);
397 398
398 /* Disable */ 399 /* Disable */
399 spin_lock_irqsave(&mpic->fixup_lock, flags); 400 raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
400 writeb(0x10 + 2 * fixup->index, fixup->base + 2); 401 writeb(0x10 + 2 * fixup->index, fixup->base + 2);
401 tmp = readl(fixup->base + 4); 402 tmp = readl(fixup->base + 4);
402 tmp |= 1; 403 tmp |= 1;
403 writel(tmp, fixup->base + 4); 404 writel(tmp, fixup->base + 4);
404 spin_unlock_irqrestore(&mpic->fixup_lock, flags); 405 raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
405 406
406#ifdef CONFIG_PM 407#ifdef CONFIG_PM
407 /* use the lowest bit inverted to the actual HW, 408 /* use the lowest bit inverted to the actual HW,
@@ -515,7 +516,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
515 BUG_ON(mpic->fixups == NULL); 516 BUG_ON(mpic->fixups == NULL);
516 517
517 /* Init spinlock */ 518 /* Init spinlock */
518 spin_lock_init(&mpic->fixup_lock); 519 raw_spin_lock_init(&mpic->fixup_lock);
519 520
520 /* Map U3 config space. We assume all IO-APICs are on the primary bus 521 /* Map U3 config space. We assume all IO-APICs are on the primary bus
521 * so we only need to map 64kB. 522 * so we only need to map 64kB.
@@ -567,20 +568,18 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
567#endif /* CONFIG_MPIC_U3_HT_IRQS */ 568#endif /* CONFIG_MPIC_U3_HT_IRQS */
568 569
569#ifdef CONFIG_SMP 570#ifdef CONFIG_SMP
570static int irq_choose_cpu(unsigned int virt_irq) 571static int irq_choose_cpu(const cpumask_t *mask)
571{ 572{
572 cpumask_t mask;
573 int cpuid; 573 int cpuid;
574 574
575 cpumask_copy(&mask, irq_desc[virt_irq].affinity); 575 if (cpumask_equal(mask, cpu_all_mask)) {
576 if (cpus_equal(mask, CPU_MASK_ALL)) {
577 static int irq_rover; 576 static int irq_rover;
578 static DEFINE_SPINLOCK(irq_rover_lock); 577 static DEFINE_RAW_SPINLOCK(irq_rover_lock);
579 unsigned long flags; 578 unsigned long flags;
580 579
581 /* Round-robin distribution... */ 580 /* Round-robin distribution... */
582 do_round_robin: 581 do_round_robin:
583 spin_lock_irqsave(&irq_rover_lock, flags); 582 raw_spin_lock_irqsave(&irq_rover_lock, flags);
584 583
585 while (!cpu_online(irq_rover)) { 584 while (!cpu_online(irq_rover)) {
586 if (++irq_rover >= NR_CPUS) 585 if (++irq_rover >= NR_CPUS)
@@ -592,22 +591,17 @@ static int irq_choose_cpu(unsigned int virt_irq)
592 irq_rover = 0; 591 irq_rover = 0;
593 } while (!cpu_online(irq_rover)); 592 } while (!cpu_online(irq_rover));
594 593
595 spin_unlock_irqrestore(&irq_rover_lock, flags); 594 raw_spin_unlock_irqrestore(&irq_rover_lock, flags);
596 } else { 595 } else {
597 cpumask_t tmp; 596 cpuid = cpumask_first_and(mask, cpu_online_mask);
598 597 if (cpuid >= nr_cpu_ids)
599 cpus_and(tmp, cpu_online_map, mask);
600
601 if (cpus_empty(tmp))
602 goto do_round_robin; 598 goto do_round_robin;
603
604 cpuid = first_cpu(tmp);
605 } 599 }
606 600
607 return get_hard_smp_processor_id(cpuid); 601 return get_hard_smp_processor_id(cpuid);
608} 602}
609#else 603#else
610static int irq_choose_cpu(unsigned int virt_irq) 604static int irq_choose_cpu(const cpumask_t *mask)
611{ 605{
612 return hard_smp_processor_id(); 606 return hard_smp_processor_id();
613} 607}
@@ -621,7 +615,7 @@ static struct mpic *mpic_find(unsigned int irq)
621 if (irq < NUM_ISA_INTERRUPTS) 615 if (irq < NUM_ISA_INTERRUPTS)
622 return NULL; 616 return NULL;
623 617
624 return irq_desc[irq].chip_data; 618 return irq_to_desc(irq)->chip_data;
625} 619}
626 620
627/* Determine if the linux irq is an IPI */ 621/* Determine if the linux irq is an IPI */
@@ -648,14 +642,14 @@ static inline u32 mpic_physmask(u32 cpumask)
648/* Get the mpic structure from the IPI number */ 642/* Get the mpic structure from the IPI number */
649static inline struct mpic * mpic_from_ipi(unsigned int ipi) 643static inline struct mpic * mpic_from_ipi(unsigned int ipi)
650{ 644{
651 return irq_desc[ipi].chip_data; 645 return irq_to_desc(ipi)->chip_data;
652} 646}
653#endif 647#endif
654 648
655/* Get the mpic structure from the irq number */ 649/* Get the mpic structure from the irq number */
656static inline struct mpic * mpic_from_irq(unsigned int irq) 650static inline struct mpic * mpic_from_irq(unsigned int irq)
657{ 651{
658 return irq_desc[irq].chip_data; 652 return irq_to_desc(irq)->chip_data;
659} 653}
660 654
661/* Send an EOI */ 655/* Send an EOI */
@@ -735,7 +729,7 @@ static void mpic_unmask_ht_irq(unsigned int irq)
735 729
736 mpic_unmask_irq(irq); 730 mpic_unmask_irq(irq);
737 731
738 if (irq_desc[irq].status & IRQ_LEVEL) 732 if (irq_to_desc(irq)->status & IRQ_LEVEL)
739 mpic_ht_end_irq(mpic, src); 733 mpic_ht_end_irq(mpic, src);
740} 734}
741 735
@@ -745,7 +739,7 @@ static unsigned int mpic_startup_ht_irq(unsigned int irq)
745 unsigned int src = mpic_irq_to_hw(irq); 739 unsigned int src = mpic_irq_to_hw(irq);
746 740
747 mpic_unmask_irq(irq); 741 mpic_unmask_irq(irq);
748 mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status); 742 mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
749 743
750 return 0; 744 return 0;
751} 745}
@@ -755,7 +749,7 @@ static void mpic_shutdown_ht_irq(unsigned int irq)
755 struct mpic *mpic = mpic_from_irq(irq); 749 struct mpic *mpic = mpic_from_irq(irq);
756 unsigned int src = mpic_irq_to_hw(irq); 750 unsigned int src = mpic_irq_to_hw(irq);
757 751
758 mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status); 752 mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
759 mpic_mask_irq(irq); 753 mpic_mask_irq(irq);
760} 754}
761 755
@@ -772,7 +766,7 @@ static void mpic_end_ht_irq(unsigned int irq)
772 * latched another edge interrupt coming in anyway 766 * latched another edge interrupt coming in anyway
773 */ 767 */
774 768
775 if (irq_desc[irq].status & IRQ_LEVEL) 769 if (irq_to_desc(irq)->status & IRQ_LEVEL)
776 mpic_ht_end_irq(mpic, src); 770 mpic_ht_end_irq(mpic, src);
777 mpic_eoi(mpic); 771 mpic_eoi(mpic);
778} 772}
@@ -816,7 +810,7 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
816 unsigned int src = mpic_irq_to_hw(irq); 810 unsigned int src = mpic_irq_to_hw(irq);
817 811
818 if (mpic->flags & MPIC_SINGLE_DEST_CPU) { 812 if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
819 int cpuid = irq_choose_cpu(irq); 813 int cpuid = irq_choose_cpu(cpumask);
820 814
821 mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid); 815 mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
822 } else { 816 } else {
@@ -856,7 +850,7 @@ int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
856{ 850{
857 struct mpic *mpic = mpic_from_irq(virq); 851 struct mpic *mpic = mpic_from_irq(virq);
858 unsigned int src = mpic_irq_to_hw(virq); 852 unsigned int src = mpic_irq_to_hw(virq);
859 struct irq_desc *desc = get_irq_desc(virq); 853 struct irq_desc *desc = irq_to_desc(virq);
860 unsigned int vecpri, vold, vnew; 854 unsigned int vecpri, vold, vnew;
861 855
862 DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n", 856 DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
@@ -994,7 +988,7 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
994} 988}
995 989
996static int mpic_host_xlate(struct irq_host *h, struct device_node *ct, 990static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
997 u32 *intspec, unsigned int intsize, 991 const u32 *intspec, unsigned int intsize,
998 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 992 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
999 993
1000{ 994{
@@ -1062,19 +1056,19 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1062 mpic->name = name; 1056 mpic->name = name;
1063 1057
1064 mpic->hc_irq = mpic_irq_chip; 1058 mpic->hc_irq = mpic_irq_chip;
1065 mpic->hc_irq.typename = name; 1059 mpic->hc_irq.name = name;
1066 if (flags & MPIC_PRIMARY) 1060 if (flags & MPIC_PRIMARY)
1067 mpic->hc_irq.set_affinity = mpic_set_affinity; 1061 mpic->hc_irq.set_affinity = mpic_set_affinity;
1068#ifdef CONFIG_MPIC_U3_HT_IRQS 1062#ifdef CONFIG_MPIC_U3_HT_IRQS
1069 mpic->hc_ht_irq = mpic_irq_ht_chip; 1063 mpic->hc_ht_irq = mpic_irq_ht_chip;
1070 mpic->hc_ht_irq.typename = name; 1064 mpic->hc_ht_irq.name = name;
1071 if (flags & MPIC_PRIMARY) 1065 if (flags & MPIC_PRIMARY)
1072 mpic->hc_ht_irq.set_affinity = mpic_set_affinity; 1066 mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
1073#endif /* CONFIG_MPIC_U3_HT_IRQS */ 1067#endif /* CONFIG_MPIC_U3_HT_IRQS */
1074 1068
1075#ifdef CONFIG_SMP 1069#ifdef CONFIG_SMP
1076 mpic->hc_ipi = mpic_ipi_chip; 1070 mpic->hc_ipi = mpic_ipi_chip;
1077 mpic->hc_ipi.typename = name; 1071 mpic->hc_ipi.name = name;
1078#endif /* CONFIG_SMP */ 1072#endif /* CONFIG_SMP */
1079 1073
1080 mpic->flags = flags; 1074 mpic->flags = flags;
@@ -1375,14 +1369,14 @@ void __init mpic_set_serial_int(struct mpic *mpic, int enable)
1375 unsigned long flags; 1369 unsigned long flags;
1376 u32 v; 1370 u32 v;
1377 1371
1378 spin_lock_irqsave(&mpic_lock, flags); 1372 raw_spin_lock_irqsave(&mpic_lock, flags);
1379 v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); 1373 v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1);
1380 if (enable) 1374 if (enable)
1381 v |= MPIC_GREG_GLOBAL_CONF_1_SIE; 1375 v |= MPIC_GREG_GLOBAL_CONF_1_SIE;
1382 else 1376 else
1383 v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE; 1377 v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE;
1384 mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); 1378 mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v);
1385 spin_unlock_irqrestore(&mpic_lock, flags); 1379 raw_spin_unlock_irqrestore(&mpic_lock, flags);
1386} 1380}
1387 1381
1388void mpic_irq_set_priority(unsigned int irq, unsigned int pri) 1382void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
@@ -1395,7 +1389,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
1395 if (!mpic) 1389 if (!mpic)
1396 return; 1390 return;
1397 1391
1398 spin_lock_irqsave(&mpic_lock, flags); 1392 raw_spin_lock_irqsave(&mpic_lock, flags);
1399 if (mpic_is_ipi(mpic, irq)) { 1393 if (mpic_is_ipi(mpic, irq)) {
1400 reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & 1394 reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
1401 ~MPIC_VECPRI_PRIORITY_MASK; 1395 ~MPIC_VECPRI_PRIORITY_MASK;
@@ -1407,7 +1401,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
1407 mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), 1401 mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
1408 reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); 1402 reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
1409 } 1403 }
1410 spin_unlock_irqrestore(&mpic_lock, flags); 1404 raw_spin_unlock_irqrestore(&mpic_lock, flags);
1411} 1405}
1412 1406
1413void mpic_setup_this_cpu(void) 1407void mpic_setup_this_cpu(void)
@@ -1422,7 +1416,7 @@ void mpic_setup_this_cpu(void)
1422 1416
1423 DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); 1417 DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
1424 1418
1425 spin_lock_irqsave(&mpic_lock, flags); 1419 raw_spin_lock_irqsave(&mpic_lock, flags);
1426 1420
1427 /* let the mpic know we want intrs. default affinity is 0xffffffff 1421 /* let the mpic know we want intrs. default affinity is 0xffffffff
1428 * until changed via /proc. That's how it's done on x86. If we want 1422 * until changed via /proc. That's how it's done on x86. If we want
@@ -1438,7 +1432,7 @@ void mpic_setup_this_cpu(void)
1438 /* Set current processor priority to 0 */ 1432 /* Set current processor priority to 0 */
1439 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); 1433 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
1440 1434
1441 spin_unlock_irqrestore(&mpic_lock, flags); 1435 raw_spin_unlock_irqrestore(&mpic_lock, flags);
1442#endif /* CONFIG_SMP */ 1436#endif /* CONFIG_SMP */
1443} 1437}
1444 1438
@@ -1467,7 +1461,7 @@ void mpic_teardown_this_cpu(int secondary)
1467 BUG_ON(mpic == NULL); 1461 BUG_ON(mpic == NULL);
1468 1462
1469 DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id()); 1463 DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
1470 spin_lock_irqsave(&mpic_lock, flags); 1464 raw_spin_lock_irqsave(&mpic_lock, flags);
1471 1465
1472 /* let the mpic know we don't want intrs. */ 1466 /* let the mpic know we don't want intrs. */
1473 for (i = 0; i < mpic->num_sources ; i++) 1467 for (i = 0; i < mpic->num_sources ; i++)
@@ -1481,7 +1475,7 @@ void mpic_teardown_this_cpu(int secondary)
1481 */ 1475 */
1482 mpic_eoi(mpic); 1476 mpic_eoi(mpic);
1483 1477
1484 spin_unlock_irqrestore(&mpic_lock, flags); 1478 raw_spin_unlock_irqrestore(&mpic_lock, flags);
1485} 1479}
1486 1480
1487 1481
@@ -1582,7 +1576,7 @@ void mpic_request_ipis(void)
1582 int i; 1576 int i;
1583 BUG_ON(mpic == NULL); 1577 BUG_ON(mpic == NULL);
1584 1578
1585 printk(KERN_INFO "mpic: requesting IPIs ... \n"); 1579 printk(KERN_INFO "mpic: requesting IPIs...\n");
1586 1580
1587 for (i = 0; i < 4; i++) { 1581 for (i = 0; i < 4; i++) {
1588 unsigned int vipi = irq_create_mapping(mpic->irqhost, 1582 unsigned int vipi = irq_create_mapping(mpic->irqhost,