You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openwrt/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.p...

81 lines
2.2 KiB
Diff

From eaf1943a2c49cbc6eb0ffafa7b6ced45f2d328da Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 9 Jan 2014 19:40:14 +0100
Subject: [PATCH 05/17] 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 <hauke@hauke-m.de>
---
drivers/bcma/main.c | 42 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -10,6 +10,8 @@
#include <linux/platform_device.h>
#include <linux/bcma/bcma.h>
#include <linux/slab.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
MODULE_LICENSE("GPL");
@@ -131,6 +133,38 @@ static bool bcma_is_core_needed_early(u1
return false;
}
+static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
+ struct bcma_device *core)
+{
+ struct device_node *node;
+ u64 size;
+ const __be32 *reg;
+
+ if (!parent || !parent->dev.of_node)
+ return NULL;
+
+ for_each_child_of_node(parent->dev.of_node, node) {
+ reg = of_get_address(node, 0, &size, NULL);
+ if (!reg)
+ continue;
+ if (be32_to_cpup(reg) == core->addr)
+ return node;
+ }
+ return NULL;
+}
+
+static void bcma_of_fill_device(struct platform_device *parent,
+ struct bcma_device *core)
+{
+ struct device_node *node;
+
+ node = bcma_of_find_child_device(parent, core);
+ if (!node)
+ return;
+ core->dev.of_node = node;
+ core->irq = irq_of_parse_and_map(node, 0);
+}
+
static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
{
int err;
@@ -147,7 +181,13 @@ static void bcma_register_core(struct bc
break;
case BCMA_HOSTTYPE_SOC:
core->dev.dma_mask = &core->dev.coherent_dma_mask;
- core->dma_dev = &core->dev;
+ if (bus->host_pdev) {
+ core->dma_dev = &bus->host_pdev->dev;
+ core->dev.parent = &bus->host_pdev->dev;
+ bcma_of_fill_device(bus->host_pdev, core);
+ } else {
+ core->dma_dev = &core->dev;
+ }
break;
case BCMA_HOSTTYPE_SDIO:
break;