mpic.c (6548698f929814375fa5d62ae1db96959b0418c1) mpic.c (40d50cf7ca956183f3a573bc21082e1c7d04fa7b)
1/*
2 * arch/powerpc/kernel/mpic.c
3 *
4 * Driver for interrupt controllers following the OpenPIC standard, the
5 * common implementation beeing IBM's MPIC. This driver also can deal
6 * with various broken implementations of this HW.
7 *
8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.

--- 558 unchanged lines hidden (view full) ---

567#endif /* CONFIG_MPIC_U3_HT_IRQS */
568
569#ifdef CONFIG_SMP
570static int irq_choose_cpu(unsigned int virt_irq)
571{
572 cpumask_t mask;
573 int cpuid;
574
1/*
2 * arch/powerpc/kernel/mpic.c
3 *
4 * Driver for interrupt controllers following the OpenPIC standard, the
5 * common implementation beeing IBM's MPIC. This driver also can deal
6 * with various broken implementations of this HW.
7 *
8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.

--- 558 unchanged lines hidden (view full) ---

567#endif /* CONFIG_MPIC_U3_HT_IRQS */
568
569#ifdef CONFIG_SMP
570static int irq_choose_cpu(unsigned int virt_irq)
571{
572 cpumask_t mask;
573 int cpuid;
574
575 cpumask_copy(&mask, irq_desc[virt_irq].affinity);
575 cpumask_copy(&mask, irq_to_desc(virt_irq)->affinity);
576 if (cpus_equal(mask, CPU_MASK_ALL)) {
577 static int irq_rover;
578 static DEFINE_SPINLOCK(irq_rover_lock);
579 unsigned long flags;
580
581 /* Round-robin distribution... */
582 do_round_robin:
583 spin_lock_irqsave(&irq_rover_lock, flags);

--- 32 unchanged lines hidden (view full) ---

616#define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
617
618/* Find an mpic associated with a given linux interrupt */
619static struct mpic *mpic_find(unsigned int irq)
620{
621 if (irq < NUM_ISA_INTERRUPTS)
622 return NULL;
623
576 if (cpus_equal(mask, CPU_MASK_ALL)) {
577 static int irq_rover;
578 static DEFINE_SPINLOCK(irq_rover_lock);
579 unsigned long flags;
580
581 /* Round-robin distribution... */
582 do_round_robin:
583 spin_lock_irqsave(&irq_rover_lock, flags);

--- 32 unchanged lines hidden (view full) ---

616#define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
617
618/* Find an mpic associated with a given linux interrupt */
619static struct mpic *mpic_find(unsigned int irq)
620{
621 if (irq < NUM_ISA_INTERRUPTS)
622 return NULL;
623
624 return irq_desc[irq].chip_data;
624 return irq_to_desc(irq)->chip_data;
625}
626
627/* Determine if the linux irq is an IPI */
628static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq)
629{
630 unsigned int src = mpic_irq_to_hw(irq);
631
632 return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);

--- 10 unchanged lines hidden (view full) ---

643 mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
644 return mask;
645}
646
647#ifdef CONFIG_SMP
648/* Get the mpic structure from the IPI number */
649static inline struct mpic * mpic_from_ipi(unsigned int ipi)
650{
625}
626
627/* Determine if the linux irq is an IPI */
628static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq)
629{
630 unsigned int src = mpic_irq_to_hw(irq);
631
632 return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);

--- 10 unchanged lines hidden (view full) ---

643 mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
644 return mask;
645}
646
647#ifdef CONFIG_SMP
648/* Get the mpic structure from the IPI number */
649static inline struct mpic * mpic_from_ipi(unsigned int ipi)
650{
651 return irq_desc[ipi].chip_data;
651 return irq_to_desc(ipi)->chip_data;
652}
653#endif
654
655/* Get the mpic structure from the irq number */
656static inline struct mpic * mpic_from_irq(unsigned int irq)
657{
652}
653#endif
654
655/* Get the mpic structure from the irq number */
656static inline struct mpic * mpic_from_irq(unsigned int irq)
657{
658 return irq_desc[irq].chip_data;
658 return irq_to_desc(irq)->chip_data;
659}
660
661/* Send an EOI */
662static inline void mpic_eoi(struct mpic *mpic)
663{
664 mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
665 (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
666}

--- 63 unchanged lines hidden (view full) ---

730
731static void mpic_unmask_ht_irq(unsigned int irq)
732{
733 struct mpic *mpic = mpic_from_irq(irq);
734 unsigned int src = mpic_irq_to_hw(irq);
735
736 mpic_unmask_irq(irq);
737
659}
660
661/* Send an EOI */
662static inline void mpic_eoi(struct mpic *mpic)
663{
664 mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
665 (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
666}

--- 63 unchanged lines hidden (view full) ---

730
731static void mpic_unmask_ht_irq(unsigned int irq)
732{
733 struct mpic *mpic = mpic_from_irq(irq);
734 unsigned int src = mpic_irq_to_hw(irq);
735
736 mpic_unmask_irq(irq);
737
738 if (irq_desc[irq].status & IRQ_LEVEL)
738 if (irq_to_desc(irq)->status & IRQ_LEVEL)
739 mpic_ht_end_irq(mpic, src);
740}
741
742static unsigned int mpic_startup_ht_irq(unsigned int irq)
743{
744 struct mpic *mpic = mpic_from_irq(irq);
745 unsigned int src = mpic_irq_to_hw(irq);
746
747 mpic_unmask_irq(irq);
739 mpic_ht_end_irq(mpic, src);
740}
741
742static unsigned int mpic_startup_ht_irq(unsigned int irq)
743{
744 struct mpic *mpic = mpic_from_irq(irq);
745 unsigned int src = mpic_irq_to_hw(irq);
746
747 mpic_unmask_irq(irq);
748 mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status);
748 mpic_startup_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
749
750 return 0;
751}
752
753static void mpic_shutdown_ht_irq(unsigned int irq)
754{
755 struct mpic *mpic = mpic_from_irq(irq);
756 unsigned int src = mpic_irq_to_hw(irq);
757
749
750 return 0;
751}
752
753static void mpic_shutdown_ht_irq(unsigned int irq)
754{
755 struct mpic *mpic = mpic_from_irq(irq);
756 unsigned int src = mpic_irq_to_hw(irq);
757
758 mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status);
758 mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(irq)->status);
759 mpic_mask_irq(irq);
760}
761
762static void mpic_end_ht_irq(unsigned int irq)
763{
764 struct mpic *mpic = mpic_from_irq(irq);
765 unsigned int src = mpic_irq_to_hw(irq);
766
767#ifdef DEBUG_IRQ
768 DBG("%s: end_irq: %d\n", mpic->name, irq);
769#endif
770 /* We always EOI on end_irq() even for edge interrupts since that
771 * should only lower the priority, the MPIC should have properly
772 * latched another edge interrupt coming in anyway
773 */
774
759 mpic_mask_irq(irq);
760}
761
762static void mpic_end_ht_irq(unsigned int irq)
763{
764 struct mpic *mpic = mpic_from_irq(irq);
765 unsigned int src = mpic_irq_to_hw(irq);
766
767#ifdef DEBUG_IRQ
768 DBG("%s: end_irq: %d\n", mpic->name, irq);
769#endif
770 /* We always EOI on end_irq() even for edge interrupts since that
771 * should only lower the priority, the MPIC should have properly
772 * latched another edge interrupt coming in anyway
773 */
774
775 if (irq_desc[irq].status & IRQ_LEVEL)
775 if (irq_to_desc(irq)->status & IRQ_LEVEL)
776 mpic_ht_end_irq(mpic, src);
777 mpic_eoi(mpic);
778}
779#endif /* !CONFIG_MPIC_U3_HT_IRQS */
780
781#ifdef CONFIG_SMP
782
783static void mpic_unmask_ipi(unsigned int irq)

--- 67 unchanged lines hidden (view full) ---

851 MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
852 }
853}
854
855int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
856{
857 struct mpic *mpic = mpic_from_irq(virq);
858 unsigned int src = mpic_irq_to_hw(virq);
776 mpic_ht_end_irq(mpic, src);
777 mpic_eoi(mpic);
778}
779#endif /* !CONFIG_MPIC_U3_HT_IRQS */
780
781#ifdef CONFIG_SMP
782
783static void mpic_unmask_ipi(unsigned int irq)

--- 67 unchanged lines hidden (view full) ---

851 MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
852 }
853}
854
855int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
856{
857 struct mpic *mpic = mpic_from_irq(virq);
858 unsigned int src = mpic_irq_to_hw(virq);
859 struct irq_desc *desc = get_irq_desc(virq);
859 struct irq_desc *desc = irq_to_desc(virq);
860 unsigned int vecpri, vold, vnew;
861
862 DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
863 mpic, virq, src, flow_type);
864
865 if (src >= mpic->irq_count)
866 return -EINVAL;
867

--- 121 unchanged lines hidden (view full) ---

989
990 /* Set default irq type */
991 set_irq_type(virq, IRQ_TYPE_NONE);
992
993 return 0;
994}
995
996static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
860 unsigned int vecpri, vold, vnew;
861
862 DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
863 mpic, virq, src, flow_type);
864
865 if (src >= mpic->irq_count)
866 return -EINVAL;
867

--- 121 unchanged lines hidden (view full) ---

989
990 /* Set default irq type */
991 set_irq_type(virq, IRQ_TYPE_NONE);
992
993 return 0;
994}
995
996static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
997 u32 *intspec, unsigned int intsize,
997 const u32 *intspec, unsigned int intsize,
998 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
999
1000{
1001 static unsigned char map_mpic_senses[4] = {
1002 IRQ_TYPE_EDGE_RISING,
1003 IRQ_TYPE_LEVEL_LOW,
1004 IRQ_TYPE_LEVEL_HIGH,
1005 IRQ_TYPE_EDGE_FALLING,

--- 51 unchanged lines hidden (view full) ---

1057
1058 mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
1059 if (mpic == NULL)
1060 return NULL;
1061
1062 mpic->name = name;
1063
1064 mpic->hc_irq = mpic_irq_chip;
998 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
999
1000{
1001 static unsigned char map_mpic_senses[4] = {
1002 IRQ_TYPE_EDGE_RISING,
1003 IRQ_TYPE_LEVEL_LOW,
1004 IRQ_TYPE_LEVEL_HIGH,
1005 IRQ_TYPE_EDGE_FALLING,

--- 51 unchanged lines hidden (view full) ---

1057
1058 mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL);
1059 if (mpic == NULL)
1060 return NULL;
1061
1062 mpic->name = name;
1063
1064 mpic->hc_irq = mpic_irq_chip;
1065 mpic->hc_irq.typename = name;
1065 mpic->hc_irq.name = name;
1066 if (flags & MPIC_PRIMARY)
1067 mpic->hc_irq.set_affinity = mpic_set_affinity;
1068#ifdef CONFIG_MPIC_U3_HT_IRQS
1069 mpic->hc_ht_irq = mpic_irq_ht_chip;
1066 if (flags & MPIC_PRIMARY)
1067 mpic->hc_irq.set_affinity = mpic_set_affinity;
1068#ifdef CONFIG_MPIC_U3_HT_IRQS
1069 mpic->hc_ht_irq = mpic_irq_ht_chip;
1070 mpic->hc_ht_irq.typename = name;
1070 mpic->hc_ht_irq.name = name;
1071 if (flags & MPIC_PRIMARY)
1072 mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
1073#endif /* CONFIG_MPIC_U3_HT_IRQS */
1074
1075#ifdef CONFIG_SMP
1076 mpic->hc_ipi = mpic_ipi_chip;
1071 if (flags & MPIC_PRIMARY)
1072 mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
1073#endif /* CONFIG_MPIC_U3_HT_IRQS */
1074
1075#ifdef CONFIG_SMP
1076 mpic->hc_ipi = mpic_ipi_chip;
1077 mpic->hc_ipi.typename = name;
1077 mpic->hc_ipi.name = name;
1078#endif /* CONFIG_SMP */
1079
1080 mpic->flags = flags;
1081 mpic->isu_size = isu_size;
1082 mpic->irq_count = irq_count;
1083 mpic->num_sources = 0; /* so far */
1084
1085 if (flags & MPIC_LARGE_VECTORS)

--- 630 unchanged lines hidden ---
1078#endif /* CONFIG_SMP */
1079
1080 mpic->flags = flags;
1081 mpic->isu_size = isu_size;
1082 mpic->irq_count = irq_count;
1083 mpic->num_sources = 0; /* so far */
1084
1085 if (flags & MPIC_LARGE_VECTORS)

--- 630 unchanged lines hidden ---