mpic.c (e2eb63927bfcb54232163bfec32440246fd44457) mpic.c (6cfef5b27e49e826125f12637ee0d7210a896044)
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.

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

299 r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
300
301 if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
302 printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
303 mpic->flags |= MPIC_BROKEN_IPI;
304 }
305}
306
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.

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

299 r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
300
301 if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
302 printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
303 mpic->flags |= MPIC_BROKEN_IPI;
304 }
305}
306
307#ifdef CONFIG_MPIC_BROKEN_U3
307#ifdef CONFIG_MPIC_U3_HT_IRQS
308
309/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
310 * to force the edge setting on the MPIC and do the ack workaround.
311 */
312static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
313{
314 if (source >= 128 || !mpic->fixups)
315 return 0;

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

471
472 next:
473 /* next device, if function 0 */
474 if (PCI_FUNC(devfn) == 0 && (hdr_type & 0x80) == 0)
475 devfn += 7;
476 }
477}
478
308
309/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
310 * to force the edge setting on the MPIC and do the ack workaround.
311 */
312static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
313{
314 if (source >= 128 || !mpic->fixups)
315 return 0;

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

471
472 next:
473 /* next device, if function 0 */
474 if (PCI_FUNC(devfn) == 0 && (hdr_type & 0x80) == 0)
475 devfn += 7;
476 }
477}
478
479#else /* CONFIG_MPIC_BROKEN_U3 */
479#else /* CONFIG_MPIC_U3_HT_IRQS */
480
481static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
482{
483 return 0;
484}
485
486static void __init mpic_scan_ht_pics(struct mpic *mpic)
487{
488}
489
480
481static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
482{
483 return 0;
484}
485
486static void __init mpic_scan_ht_pics(struct mpic *mpic)
487{
488}
489
490#endif /* CONFIG_MPIC_BROKEN_U3 */
490#endif /* CONFIG_MPIC_U3_HT_IRQS */
491
492
493#define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
494
495/* Find an mpic associated with a given linux interrupt */
496static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
497{
498 unsigned int src = mpic_irq_to_hw(irq);

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

610 /* We always EOI on end_irq() even for edge interrupts since that
611 * should only lower the priority, the MPIC should have properly
612 * latched another edge interrupt coming in anyway
613 */
614
615 mpic_eoi(mpic);
616}
617
491
492
493#define mpic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
494
495/* Find an mpic associated with a given linux interrupt */
496static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
497{
498 unsigned int src = mpic_irq_to_hw(irq);

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

610 /* We always EOI on end_irq() even for edge interrupts since that
611 * should only lower the priority, the MPIC should have properly
612 * latched another edge interrupt coming in anyway
613 */
614
615 mpic_eoi(mpic);
616}
617
618#ifdef CONFIG_MPIC_BROKEN_U3
618#ifdef CONFIG_MPIC_U3_HT_IRQS
619
620static void mpic_unmask_ht_irq(unsigned int irq)
621{
622 struct mpic *mpic = mpic_from_irq(irq);
623 unsigned int src = mpic_irq_to_hw(irq);
624
625 mpic_unmask_irq(irq);
626

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

660 * should only lower the priority, the MPIC should have properly
661 * latched another edge interrupt coming in anyway
662 */
663
664 if (irq_desc[irq].status & IRQ_LEVEL)
665 mpic_ht_end_irq(mpic, src);
666 mpic_eoi(mpic);
667}
619
620static void mpic_unmask_ht_irq(unsigned int irq)
621{
622 struct mpic *mpic = mpic_from_irq(irq);
623 unsigned int src = mpic_irq_to_hw(irq);
624
625 mpic_unmask_irq(irq);
626

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

660 * should only lower the priority, the MPIC should have properly
661 * latched another edge interrupt coming in anyway
662 */
663
664 if (irq_desc[irq].status & IRQ_LEVEL)
665 mpic_ht_end_irq(mpic, src);
666 mpic_eoi(mpic);
667}
668#endif /* !CONFIG_MPIC_BROKEN_U3 */
668#endif /* !CONFIG_MPIC_U3_HT_IRQS */
669
670#ifdef CONFIG_SMP
671
672static void mpic_unmask_ipi(unsigned int irq)
673{
674 struct mpic *mpic = mpic_from_ipi(irq);
675 unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
676

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

783#ifdef CONFIG_SMP
784static struct irq_chip mpic_ipi_chip = {
785 .mask = mpic_mask_ipi,
786 .unmask = mpic_unmask_ipi,
787 .eoi = mpic_end_ipi,
788};
789#endif /* CONFIG_SMP */
790
669
670#ifdef CONFIG_SMP
671
672static void mpic_unmask_ipi(unsigned int irq)
673{
674 struct mpic *mpic = mpic_from_ipi(irq);
675 unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
676

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

783#ifdef CONFIG_SMP
784static struct irq_chip mpic_ipi_chip = {
785 .mask = mpic_mask_ipi,
786 .unmask = mpic_unmask_ipi,
787 .eoi = mpic_end_ipi,
788};
789#endif /* CONFIG_SMP */
790
791#ifdef CONFIG_MPIC_BROKEN_U3
791#ifdef CONFIG_MPIC_U3_HT_IRQS
792static struct irq_chip mpic_irq_ht_chip = {
793 .startup = mpic_startup_ht_irq,
794 .shutdown = mpic_shutdown_ht_irq,
795 .mask = mpic_mask_irq,
796 .unmask = mpic_unmask_ht_irq,
797 .eoi = mpic_end_ht_irq,
798 .set_type = mpic_set_irq_type,
799};
792static struct irq_chip mpic_irq_ht_chip = {
793 .startup = mpic_startup_ht_irq,
794 .shutdown = mpic_shutdown_ht_irq,
795 .mask = mpic_mask_irq,
796 .unmask = mpic_unmask_ht_irq,
797 .eoi = mpic_end_ht_irq,
798 .set_type = mpic_set_irq_type,
799};
800#endif /* CONFIG_MPIC_BROKEN_U3 */
800#endif /* CONFIG_MPIC_U3_HT_IRQS */
801
802
803static int mpic_host_match(struct irq_host *h, struct device_node *node)
804{
805 struct mpic *mpic = h->host_data;
806
807 /* Exact match, unless mpic node is NULL */
808 return mpic->of_node == NULL || mpic->of_node == node;

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

832#endif /* CONFIG_SMP */
833
834 if (hw >= mpic->irq_count)
835 return -EINVAL;
836
837 /* Default chip */
838 chip = &mpic->hc_irq;
839
801
802
803static int mpic_host_match(struct irq_host *h, struct device_node *node)
804{
805 struct mpic *mpic = h->host_data;
806
807 /* Exact match, unless mpic node is NULL */
808 return mpic->of_node == NULL || mpic->of_node == node;

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

832#endif /* CONFIG_SMP */
833
834 if (hw >= mpic->irq_count)
835 return -EINVAL;
836
837 /* Default chip */
838 chip = &mpic->hc_irq;
839
840#ifdef CONFIG_MPIC_BROKEN_U3
840#ifdef CONFIG_MPIC_U3_HT_IRQS
841 /* Check for HT interrupts, override vecpri */
842 if (mpic_is_ht_interrupt(mpic, hw))
843 chip = &mpic->hc_ht_irq;
841 /* Check for HT interrupts, override vecpri */
842 if (mpic_is_ht_interrupt(mpic, hw))
843 chip = &mpic->hc_ht_irq;
844#endif /* CONFIG_MPIC_BROKEN_U3 */
844#endif /* CONFIG_MPIC_U3_HT_IRQS */
845
846 DBG("mpic: mapping to irq chip @%p\n", chip);
847
848 set_irq_chip_data(virq, mpic);
849 set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);
850
851 /* Set default irq type */
852 set_irq_type(virq, IRQ_TYPE_NONE);

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

932 return NULL;
933 }
934
935 mpic->irqhost->host_data = mpic;
936 mpic->hc_irq = mpic_irq_chip;
937 mpic->hc_irq.typename = name;
938 if (flags & MPIC_PRIMARY)
939 mpic->hc_irq.set_affinity = mpic_set_affinity;
845
846 DBG("mpic: mapping to irq chip @%p\n", chip);
847
848 set_irq_chip_data(virq, mpic);
849 set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);
850
851 /* Set default irq type */
852 set_irq_type(virq, IRQ_TYPE_NONE);

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

932 return NULL;
933 }
934
935 mpic->irqhost->host_data = mpic;
936 mpic->hc_irq = mpic_irq_chip;
937 mpic->hc_irq.typename = name;
938 if (flags & MPIC_PRIMARY)
939 mpic->hc_irq.set_affinity = mpic_set_affinity;
940#ifdef CONFIG_MPIC_BROKEN_U3
940#ifdef CONFIG_MPIC_U3_HT_IRQS
941 mpic->hc_ht_irq = mpic_irq_ht_chip;
942 mpic->hc_ht_irq.typename = name;
943 if (flags & MPIC_PRIMARY)
944 mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
941 mpic->hc_ht_irq = mpic_irq_ht_chip;
942 mpic->hc_ht_irq.typename = name;
943 if (flags & MPIC_PRIMARY)
944 mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
945#endif /* CONFIG_MPIC_BROKEN_U3 */
945#endif /* CONFIG_MPIC_U3_HT_IRQS */
946
947#ifdef CONFIG_SMP
948 mpic->hc_ipi = mpic_ipi_chip;
949 mpic->hc_ipi.typename = name;
950#endif /* CONFIG_SMP */
951
952 mpic->flags = flags;
953 mpic->isu_size = isu_size;

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

1137 }
1138
1139 /* Initialize interrupt sources */
1140 if (mpic->irq_count == 0)
1141 mpic->irq_count = mpic->num_sources;
1142
1143 /* Do the HT PIC fixups on U3 broken mpic */
1144 DBG("MPIC flags: %x\n", mpic->flags);
946
947#ifdef CONFIG_SMP
948 mpic->hc_ipi = mpic_ipi_chip;
949 mpic->hc_ipi.typename = name;
950#endif /* CONFIG_SMP */
951
952 mpic->flags = flags;
953 mpic->isu_size = isu_size;

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

1137 }
1138
1139 /* Initialize interrupt sources */
1140 if (mpic->irq_count == 0)
1141 mpic->irq_count = mpic->num_sources;
1142
1143 /* Do the HT PIC fixups on U3 broken mpic */
1144 DBG("MPIC flags: %x\n", mpic->flags);
1145 if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
1145 if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY))
1146 mpic_scan_ht_pics(mpic);
1147
1148 for (i = 0; i < mpic->num_sources; i++) {
1149 /* start with vector = source number, and masked */
1150 u32 vecpri = MPIC_VECPRI_MASK | i |
1151 (8 << MPIC_VECPRI_PRIORITY_SHIFT);
1152
1153 /* init hw */

--- 266 unchanged lines hidden ---
1146 mpic_scan_ht_pics(mpic);
1147
1148 for (i = 0; i < mpic->num_sources; i++) {
1149 /* start with vector = source number, and masked */
1150 u32 vecpri = MPIC_VECPRI_MASK | i |
1151 (8 << MPIC_VECPRI_PRIORITY_SHIFT);
1152
1153 /* init hw */

--- 266 unchanged lines hidden ---