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 --- |