summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Moll <pawel.moll@st.com>2009-08-24 19:52:38 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-08-24 19:52:38 +0900
commit05ecd5a1f76c183cca381705b3adb7d77c9a0439 (patch)
treeb10313518bb21df0290ec4d8d7088835b7fec457
parent788e6af37a4ace8721eda72e4abe66fe0f6b49fd (diff)
downloadlinux-3.10-05ecd5a1f76c183cca381705b3adb7d77c9a0439.tar.gz
linux-3.10-05ecd5a1f76c183cca381705b3adb7d77c9a0439.tar.bz2
linux-3.10-05ecd5a1f76c183cca381705b3adb7d77c9a0439.zip
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>
-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 278c68c6048..d1053392e28 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)
#endif
irq_enter();
- irq = irq_demux(intc_evt2irq(irq));
+ irq = irq_demux(evt2irq(irq));
#ifdef CONFIG_IRQSTACKS
curctx = (union irq_ctx *)current_thread_info();
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 4b1ca9d2835..a9174ec7285 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,
return 0;
}
-static unsigned char *intc_evt2irq_table;
-
-unsigned int intc_evt2irq(unsigned int vector)
+static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
{
- unsigned int irq = evt2irq(vector);
-
- if (intc_evt2irq_table && intc_evt2irq_table[irq])
- irq = intc_evt2irq_table[irq];
-
- return irq;
+ generic_handle_irq((unsigned int)get_irq_data(irq));
}
void __init register_intc_controller(struct intc_desc *desc)
@@ -745,34 +738,6 @@ void __init register_intc_controller(struct intc_desc *desc)
BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
- /* keep the first vector only if same enum is used multiple times */
- for (i = 0; i < desc->nr_vectors; i++) {
- struct intc_vect *vect = desc->vectors + i;
- int first_irq = evt2irq(vect->vect);
-
- if (!vect->enum_id)
- continue;
-
- for (k = i + 1; k < desc->nr_vectors; k++) {
- struct intc_vect *vect2 = desc->vectors + k;
-
- if (vect->enum_id != vect2->enum_id)
- continue;
-
- vect2->enum_id = 0;
-
- if (!intc_evt2irq_table)
- intc_evt2irq_table = kzalloc(NR_IRQS, GFP_NOWAIT);
-
- if (!intc_evt2irq_table) {
- pr_warning("intc: cannot allocate evt2irq!\n");
- continue;
- }
-
- intc_evt2irq_table[evt2irq(vect2->vect)] = first_irq;
- }
- }
-
/* register the vectors one by one */
for (i = 0; i < desc->nr_vectors; i++) {
struct intc_vect *vect = desc->vectors + i;
@@ -789,6 +754,21 @@ void __init register_intc_controller(struct intc_desc *desc)
}
intc_register_irq(desc, d, vect->enum_id, irq);
+
+ for (k = i + 1; k < desc->nr_vectors; k++) {
+ struct intc_vect *vect2 = desc->vectors + k;
+ unsigned int irq2 = evt2irq(vect2->vect);
+
+ if (vect->enum_id != vect2->enum_id)
+ continue;
+
+ vect2->enum_id = 0;
+
+ /* redirect this interrupts to the first one */
+ set_irq_chip_and_handler_name(irq2, &d->chip,
+ intc_redirect_irq, "redirect");
+ set_irq_data(irq2, (void *)irq);
+ }
}
}
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index eb1423a0078..68e212ff9dd 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -85,7 +85,6 @@ struct intc_desc symbol __initdata = { \
}
#endif
-unsigned int intc_evt2irq(unsigned int vector);
void __init register_intc_controller(struct intc_desc *desc);
int intc_set_priority(unsigned int irq, unsigned int prio);