aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/kernel/irq.c2
-rw-r--r--drivers/sh/intc.c54
-rw-r--r--include/linux/sh_intc.h1
3 files changed, 18 insertions, 39 deletions
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 278c68c60488..d1053392e287 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -114,7 +114,7 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
114#endif 114#endif
115 115
116 irq_enter(); 116 irq_enter();
117 irq = irq_demux(intc_evt2irq(irq)); 117 irq = irq_demux(evt2irq(irq));
118 118
119#ifdef CONFIG_IRQSTACKS 119#ifdef CONFIG_IRQSTACKS
120 curctx = (union irq_ctx *)current_thread_info(); 120 curctx = (union irq_ctx *)current_thread_info();
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 4b1ca9d28353..a9174ec72853 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -663,16 +663,9 @@ static unsigned int __init save_reg(struct intc_desc_int *d,
663 return 0; 663 return 0;
664} 664}
665 665
666static unsigned char *intc_evt2irq_table; 666static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
667
668unsigned int intc_evt2irq(unsigned int vector)
669{ 667{
670 unsigned int irq = evt2irq(vector); 668 generic_handle_irq((unsigned int)get_irq_data(irq));
671
672 if (intc_evt2irq_table && intc_evt2irq_table[irq])
673 irq = intc_evt2irq_table[irq];
674
675 return irq;
676} 669}
677 670
678void __init register_intc_controller(struct intc_desc *desc) 671void __init register_intc_controller(struct intc_desc *desc)
@@ -745,34 +738,6 @@ void __init register_intc_controller(struct intc_desc *desc)
745 738
746 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ 739 BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
747 740
748 /* keep the first vector only if same enum is used multiple times */
749 for (i = 0; i < desc->nr_vectors; i++) {
750 struct intc_vect *vect = desc->vectors + i;
751 int first_irq = evt2irq(vect->vect);
752
753 if (!vect->enum_id)
754 continue;
755
756 for (k = i + 1; k < desc->nr_vectors; k++) {
757 struct intc_vect *vect2 = desc->vectors + k;
758
759 if (vect->enum_id != vect2->enum_id)
760 continue;
761
762 vect2->enum_id = 0;
763
764 if (!intc_evt2irq_table)
765 intc_evt2irq_table = kzalloc(NR_IRQS, GFP_NOWAIT);
766
767 if (!intc_evt2irq_table) {
768 pr_warning("intc: cannot allocate evt2irq!\n");
769 continue;
770 }
771
772 intc_evt2irq_table[evt2irq(vect2->vect)] = first_irq;
773 }
774 }
775
776 /* register the vectors one by one */ 741 /* register the vectors one by one */
777 for (i = 0; i < desc->nr_vectors; i++) { 742 for (i = 0; i < desc->nr_vectors; i++) {
778 struct intc_vect *vect = desc->vectors + i; 743 struct intc_vect *vect = desc->vectors + i;
@@ -789,6 +754,21 @@ void __init register_intc_controller(struct intc_desc *desc)
789 } 754 }
790 755
791 intc_register_irq(desc, d, vect->enum_id, irq); 756 intc_register_irq(desc, d, vect->enum_id, irq);
757
758 for (k = i + 1; k < desc->nr_vectors; k++) {
759 struct intc_vect *vect2 = desc->vectors + k;
760 unsigned int irq2 = evt2irq(vect2->vect);
761
762 if (vect->enum_id != vect2->enum_id)
763 continue;
764
765 vect2->enum_id = 0;
766
767 /* redirect this interrupts to the first one */
768 set_irq_chip_and_handler_name(irq2, &d->chip,
769 intc_redirect_irq, "redirect");
770 set_irq_data(irq2, (void *)irq);
771 }
792 } 772 }
793} 773}
794 774
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index eb1423a0078d..68e212ff9dde 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -85,7 +85,6 @@ struct intc_desc symbol __initdata = { \
85} 85}
86#endif 86#endif
87 87
88unsigned int intc_evt2irq(unsigned int vector);
89void __init register_intc_controller(struct intc_desc *desc); 88void __init register_intc_controller(struct intc_desc *desc);
90int intc_set_priority(unsigned int irq, unsigned int prio); 89int intc_set_priority(unsigned int irq, unsigned int prio);
91 90