aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sh/intc.c
diff options
context:
space:
mode:
authorPawel Moll <pawel.moll@st.com>2009-08-24 06:52:38 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-08-24 06:52:38 -0400
commit05ecd5a1f76c183cca381705b3adb7d77c9a0439 (patch)
treeb10313518bb21df0290ec4d8d7088835b7fec457 /drivers/sh/intc.c
parent788e6af37a4ace8721eda72e4abe66fe0f6b49fd (diff)
sh: Simplify "multi-evt" interrupt handling.
This patch changes the way in which "multi-evt" interrups are handled. The intc_evt2irq_table and related intc_evt2irq() have been removed and the "redirecting" handler is installed for the coupled interrupts. Thanks to that the do_IRQ() function don't have to use another level of indirection for all the interrupts... Signed-off-by: Pawel Moll <pawel.moll@st.com> Signed-off-by: Stuart Menefy <stuart.menefy@st.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/sh/intc.c')
-rw-r--r--drivers/sh/intc.c54
1 files changed, 17 insertions, 37 deletions
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