bcma: get IRQ numbers from dt

It is not possible to auto detect the irq numbers used by the cores on
an arm SoC. If bcma was registered with device tree it will search for
some device tree nodes with the irq number and add it to the core
configuration.

Signed-off-by: Hauke Mehrtens <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
This commit is contained in:
Hauke Mehrtens 2014-11-01 16:54:56 +01:00 • committed by John W. Linville
commit 71783576b5
2 changed files with 72 additions and 1 deletions

View 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;
}