MIPS: add irqdomain support for the CPU IRQ controller
authorGabor Juhos <juhosg@openwrt.org>
Thu, 31 Jan 2013 12:20:43 +0000 (12:20 +0000)
committerJohn Crispin <blogic@openwrt.org>
Sun, 17 Feb 2013 00:25:34 +0000 (01:25 +0100)
Add code to load a irq_domain for the MIPS IRQ controller from a devicetree
file.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: John Crispin <blogic@openwrt.org>
Acked-by: David Daney <david.daney@cavium.com>
Patchwork: http://patchwork.linux-mips.org/patch/4902/

arch/mips/include/asm/irq_cpu.h
arch/mips/kernel/irq_cpu.c

index ef6a07cddb231d0b142fd94eeab0eb34d311a9e4..3f11fdb3ed8cf117346a58b6f5387c93cd26738c 100644 (file)
@@ -17,4 +17,10 @@ extern void mips_cpu_irq_init(void);
 extern void rm7k_cpu_irq_init(void);
 extern void rm9k_cpu_irq_init(void);
 
+#ifdef CONFIG_IRQ_DOMAIN
+struct device_node;
+extern int mips_cpu_intc_init(struct device_node *of_node,
+                             struct device_node *parent);
+#endif
+
 #endif /* _ASM_IRQ_CPU_H */
index 972263bcf403fca9491cd36628651e06f00c279a..49bc9caaddf8dfba3d467d4390a740e01f861b1a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 
 #include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
@@ -113,3 +114,44 @@ void __init mips_cpu_irq_init(void)
                irq_set_chip_and_handler(i, &mips_cpu_irq_controller,
                                         handle_percpu_irq);
 }
+
+#ifdef CONFIG_IRQ_DOMAIN
+static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
+                            irq_hw_number_t hw)
+{
+       static struct irq_chip *chip;
+
+       if (hw < 2 && cpu_has_mipsmt) {
+               /* Software interrupts are used for MT/CMT IPI */
+               chip = &mips_mt_cpu_irq_controller;
+       } else {
+               chip = &mips_cpu_irq_controller;
+       }
+
+       irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
+
+       return 0;
+}
+
+static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
+       .map = mips_cpu_intc_map,
+       .xlate = irq_domain_xlate_onecell,
+};
+
+int __init mips_cpu_intc_init(struct device_node *of_node,
+                             struct device_node *parent)
+{
+       struct irq_domain *domain;
+
+       /* Mask interrupts. */
+       clear_c0_status(ST0_IM);
+       clear_c0_cause(CAUSEF_IP);
+
+       domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
+                                      &mips_cpu_intc_irq_domain_ops, NULL);
+       if (!domain)
+               panic("Failed to add irqdomain for MIPS CPU\n");
+
+       return 0;
+}
+#endif /* CONFIG_IRQ_DOMAIN */