]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/bcma/main.c
bcma: get IRQ numbers from dt
[karo-tx-linux.git] / drivers / bcma / main.c
index 6d1cf57014521d73c3d66657d8aeb30a2c504b95..122086ef9fe1b78accfeffecb97ccbbcd35e4751 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/bcma/bcma.h>
 #include <linux/slab.h>
 #include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
 MODULE_LICENSE("GPL");
@@ -153,6 +154,46 @@ static struct device_node *bcma_of_find_child_device(struct platform_device *par
        return NULL;
 }
 
+static int bcma_of_irq_parse(struct platform_device *parent,
+                            struct bcma_device *core,
+                            struct of_phandle_args *out_irq, int num)
+{
+       __be32 laddr[1];
+       int rc;
+
+       if (core->dev.of_node) {
+               rc = of_irq_parse_one(core->dev.of_node, num, out_irq);
+               if (!rc)
+                       return rc;
+       }
+
+       out_irq->np = parent->dev.of_node;
+       out_irq->args_count = 1;
+       out_irq->args[0] = num;
+
+       laddr[0] = cpu_to_be32(core->addr);
+       return of_irq_parse_raw(laddr, out_irq);
+}
+
+static unsigned int bcma_of_get_irq(struct platform_device *parent,
+                                   struct bcma_device *core, int num)
+{
+       struct of_phandle_args out_irq;
+       int ret;
+
+       if (!parent || !parent->dev.of_node)
+               return 0;
+
+       ret = bcma_of_irq_parse(parent, core, &out_irq, num);
+       if (ret) {
+               bcma_debug(core->bus, "bcma_of_get_irq() failed with rc=%d\n",
+                          ret);
+               return 0;
+       }
+
+       return irq_create_of_mapping(&out_irq);
+}
+
 static void bcma_of_fill_device(struct platform_device *parent,
                                struct bcma_device *core)
 {
@@ -161,12 +202,19 @@ static void bcma_of_fill_device(struct platform_device *parent,
        node = bcma_of_find_child_device(parent, core);
        if (node)
                core->dev.of_node = node;
+
+       core->irq = bcma_of_get_irq(parent, core, 0);
 }
 #else
 static void bcma_of_fill_device(struct platform_device *parent,
                                struct bcma_device *core)
 {
 }
+static inline unsigned int bcma_of_get_irq(struct platform_device *parent,
+                                          struct bcma_device *core, int num)
+{
+       return 0;
+}
 #endif /* CONFIG_OF */
 
 unsigned int bcma_core_irq(struct bcma_device *core, int num)
@@ -182,7 +230,9 @@ unsigned int bcma_core_irq(struct bcma_device *core, int num)
                        mips_irq = bcma_core_mips_irq(core);
                        return mips_irq <= 4 ? mips_irq + 2 : 0;
                }
-               break;
+               if (bus->host_pdev)
+                       return bcma_of_get_irq(bus->host_pdev, core, num);
+               return 0;
        case BCMA_HOSTTYPE_SDIO:
                return 0;
        }