openrisc: implement irqdomains
authorJonas Bonn <jonas@southpole.se>
Fri, 6 Apr 2012 10:52:54 +0000 (12:52 +0200)
committerJonas Bonn <jonas@southpole.se>
Tue, 8 May 2012 09:42:55 +0000 (11:42 +0200)
This moves OpenRISC to using the irqdomain infrastructure.  This doesn't
fundamentally change anything other than that it will be easier to have
multiple interrupt controllers in the future.

Signed-off-by: Jonas Bonn <jonas@southpole.se>
arch/openrisc/Kconfig
arch/openrisc/kernel/irq.c

index a4787197d8fe3ea39b28c646ecfed383263ea0f1..7589051e79e07c53197c29d3504bdc241fdc43ad 100644 (file)
@@ -7,6 +7,7 @@ config OPENRISC
        def_bool y
        select OF
        select OF_EARLY_FLATTREE
+       select IRQ_DOMAIN
        select HAVE_MEMBLOCK
        select ARCH_WANT_OPTIONAL_GPIOLIB
         select HAVE_ARCH_TRACEHOOK
index 4bfead220956e2be70146f6a209a1c6cebd1b125..15c5ea3e98d4e7d65c064c3d4ab104606411e4c4 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/seq_file.h>
 #include <linux/kernel_stat.h>
 #include <linux/export.h>
-
+#include <linux/irqdomain.h>
 #include <linux/irqflags.h>
 
 /* read interrupt enabled status */
@@ -98,6 +98,7 @@ static void or1k_pic_mask_ack(struct irq_data *data)
 #endif
 }
 
+#if 0
 static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type)
 {
        /* There's nothing to do in the PIC configuration when changing
@@ -107,43 +108,64 @@ static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type)
 
        return irq_setup_alt_chip(data, flow_type);
 }
+#endif
+
+static struct irq_chip or1k_dev = {
+       .name = "or1k-PIC",
+       .irq_unmask = or1k_pic_unmask,
+       .irq_mask = or1k_pic_mask,
+       .irq_ack = or1k_pic_ack,
+       .irq_mask_ack = or1k_pic_mask_ack,
+};
+
+static struct irq_domain *root_domain;
 
 static inline int pic_get_irq(int first)
 {
-       int irq;
+       int hwirq;
 
-       irq = ffs(mfspr(SPR_PICSR) >> first);
+       hwirq = ffs(mfspr(SPR_PICSR) >> first);
+       if (!hwirq)
+               return NO_IRQ;
+       else
+               hwirq = hwirq + first -1;
 
-       return irq ? irq + first - 1 : NO_IRQ;
+       return irq_find_mapping(root_domain, hwirq);
 }
 
-static void __init or1k_irq_init(void)
+
+static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 {
-       struct irq_chip_generic *gc;
-       struct irq_chip_type *ct;
+       irq_set_chip_and_handler_name(irq, &or1k_dev,
+                                     handle_level_irq, "level");
+       irq_set_status_flags(irq, IRQ_LEVEL | IRQ_NOPROBE);
 
-       /* Disable all interrupts until explicitly requested */
-       mtspr(SPR_PICMR, (0UL));
+       return 0;
+}
 
-       gc = irq_alloc_generic_chip("or1k-PIC", 1, 0, 0, handle_level_irq);
-       ct = gc->chip_types;
+static const struct irq_domain_ops or1k_irq_domain_ops = {
+       .xlate = irq_domain_xlate_onecell,
+       .map = or1k_map,
+};
 
-       ct->chip.irq_unmask = or1k_pic_unmask;
-       ct->chip.irq_mask = or1k_pic_mask;
-       ct->chip.irq_ack = or1k_pic_ack;
-       ct->chip.irq_mask_ack = or1k_pic_mask_ack;
-       ct->chip.irq_set_type = or1k_pic_set_type;
+/*
+ * This sets up the IRQ domain for the PIC built in to the OpenRISC
+ * 1000 CPU.  This is the "root" domain as these are the interrupts
+ * that directly trigger an exception in the CPU.
+ */
+static void __init or1k_irq_init(void)
+{
+       struct device_node *intc = NULL;
 
-       /* The OR1K PIC can handle both level and edge trigged
-        * interrupts in roughly the same manner
-        */
-#if 0
-       /* FIXME: chip.type??? */
-       ct->chip.type = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_MASK;
-#endif
+       /* The interrupt controller device node is mandatory */
+       intc = of_find_compatible_node(NULL, NULL, "opencores,or1k-pic");
+       BUG_ON(!intc);
 
-       irq_setup_generic_chip(gc, IRQ_MSK(NR_IRQS), 0,
-                              IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
+       /* Disable all interrupts until explicitly requested */
+       mtspr(SPR_PICMR, (0UL));
+
+       root_domain = irq_domain_add_linear(intc, 32,
+                                           &or1k_irq_domain_ops, NULL);
 }
 
 void __init init_IRQ(void)
@@ -164,10 +186,3 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
        irq_exit();
        set_irq_regs(old_regs);
 }
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
-                                  const u32 *intspec, unsigned int intsize)
-{
-       return intspec[0];
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
This page took 0.028457 seconds and 5 git commands to generate.