summaryrefslogtreecommitdiff
path: root/drivers/bcma
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bcma')
-rw-r--r--drivers/bcma/bcma_private.h14
-rw-r--r--drivers/bcma/driver_gpio.c8
-rw-r--r--drivers/bcma/host_soc.c81
-rw-r--r--drivers/bcma/main.c52
-rw-r--r--drivers/bcma/scan.c8
5 files changed, 158 insertions, 5 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index b40be43c6f31..b6412b2d748d 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -88,6 +88,20 @@ extern int __init bcma_host_pci_init(void);
extern void __exit bcma_host_pci_exit(void);
#endif /* CONFIG_BCMA_HOST_PCI */
+/* host_soc.c */
+#if defined(CONFIG_BCMA_HOST_SOC) && defined(CONFIG_OF)
+extern int __init bcma_host_soc_register_driver(void);
+extern void __exit bcma_host_soc_unregister_driver(void);
+#else
+static inline int __init bcma_host_soc_register_driver(void)
+{
+ return 0;
+}
+static inline void __exit bcma_host_soc_unregister_driver(void)
+{
+}
+#endif /* CONFIG_BCMA_HOST_SOC && CONFIG_OF */
+
/* driver_pci.c */
u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index aec9f850b4a8..57ce5fe65364 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -76,7 +76,7 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
}
-#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
+#if IS_BUILTIN(CONFIG_BCM47XX)
static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
@@ -215,9 +215,13 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
chip->set = bcma_gpio_set_value;
chip->direction_input = bcma_gpio_direction_input;
chip->direction_output = bcma_gpio_direction_output;
-#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
+#if IS_BUILTIN(CONFIG_BCM47XX)
chip->to_irq = bcma_gpio_to_irq;
#endif
+#if IS_BUILTIN(CONFIG_OF)
+ if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
+ chip->of_node = cc->core->dev.of_node;
+#endif
switch (cc->core->bus->chipinfo.id) {
case BCMA_CHIP_ID_BCM5357:
case BCMA_CHIP_ID_BCM53572:
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
index 718e054dd727..335cbcfd945b 100644
--- a/drivers/bcma/host_soc.c
+++ b/drivers/bcma/host_soc.c
@@ -7,6 +7,9 @@
#include "bcma_private.h"
#include "scan.h"
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
#include <linux/bcma/bcma.h>
#include <linux/bcma/bcma_soc.h>
@@ -176,6 +179,7 @@ int __init bcma_host_soc_register(struct bcma_soc *soc)
/* Host specific */
bus->hosttype = BCMA_HOSTTYPE_SOC;
bus->ops = &bcma_host_soc_ops;
+ bus->host_pdev = NULL;
/* Initialize struct, detect chip */
bcma_init_bus(bus);
@@ -195,3 +199,80 @@ int __init bcma_host_soc_init(struct bcma_soc *soc)
return err;
}
+
+#ifdef CONFIG_OF
+static int bcma_host_soc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct bcma_bus *bus;
+ int err;
+
+ /* Alloc */
+ bus = devm_kzalloc(dev, sizeof(*bus), GFP_KERNEL);
+ if (!bus)
+ return -ENOMEM;
+
+ /* Map MMIO */
+ bus->mmio = of_iomap(np, 0);
+ if (!bus->mmio)
+ return -ENOMEM;
+
+ /* Host specific */
+ bus->hosttype = BCMA_HOSTTYPE_SOC;
+ bus->ops = &bcma_host_soc_ops;
+ bus->host_pdev = pdev;
+
+ /* Initialize struct, detect chip */
+ bcma_init_bus(bus);
+
+ /* Register */
+ err = bcma_bus_register(bus);
+ if (err)
+ goto err_unmap_mmio;
+
+ platform_set_drvdata(pdev, bus);
+
+ return err;
+
+err_unmap_mmio:
+ iounmap(bus->mmio);
+ return err;
+}
+
+static int bcma_host_soc_remove(struct platform_device *pdev)
+{
+ struct bcma_bus *bus = platform_get_drvdata(pdev);
+
+ bcma_bus_unregister(bus);
+ iounmap(bus->mmio);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id bcma_host_soc_of_match[] = {
+ { .compatible = "brcm,bus-axi", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bcma_host_soc_of_match);
+
+static struct platform_driver bcma_host_soc_driver = {
+ .driver = {
+ .name = "bcma-host-soc",
+ .of_match_table = bcma_host_soc_of_match,
+ },
+ .probe = bcma_host_soc_probe,
+ .remove = bcma_host_soc_remove,
+};
+
+int __init bcma_host_soc_register_driver(void)
+{
+ return platform_driver_register(&bcma_host_soc_driver);
+}
+
+void __exit bcma_host_soc_unregister_driver(void)
+{
+ platform_driver_unregister(&bcma_host_soc_driver);
+}
+#endif /* CONFIG_OF */
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index c421403cab43..d1656c2f70af 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -10,6 +10,7 @@
#include <linux/platform_device.h>
#include <linux/bcma/bcma.h>
#include <linux/slab.h>
+#include <linux/of_address.h>
MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
MODULE_LICENSE("GPL");
@@ -131,6 +132,43 @@ static bool bcma_is_core_needed_early(u16 core_id)
return false;
}
+#ifdef CONFIG_OF
+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 (of_translate_address(node, 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)
+ core->dev.of_node = node;
+}
+#else
+static void bcma_of_fill_device(struct platform_device *parent,
+ struct bcma_device *core)
+{
+}
+#endif /* CONFIG_OF */
+
static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
{
int err;
@@ -147,7 +185,13 @@ static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
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;
@@ -528,6 +572,11 @@ static int __init bcma_modinit(void)
if (err)
return err;
+ err = bcma_host_soc_register_driver();
+ if (err) {
+ pr_err("SoC host initialization failed\n");
+ err = 0;
+ }
#ifdef CONFIG_BCMA_HOST_PCI
err = bcma_host_pci_init();
if (err) {
@@ -545,6 +594,7 @@ static void __exit bcma_modexit(void)
#ifdef CONFIG_BCMA_HOST_PCI
bcma_host_pci_exit();
#endif
+ bcma_host_soc_unregister_driver();
bus_unregister(&bcma_bus_type);
}
module_exit(bcma_modexit)
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index b3a403c136fb..14b56561a36f 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -439,6 +439,7 @@ void bcma_init_bus(struct bcma_bus *bus)
{
s32 tmp;
struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
+ char chip_id[8];
INIT_LIST_HEAD(&bus->cores);
bus->nr_cores = 0;
@@ -449,8 +450,11 @@ void bcma_init_bus(struct bcma_bus *bus)
chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
- bcma_info(bus, "Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
- chipinfo->id, chipinfo->rev, chipinfo->pkg);
+
+ snprintf(chip_id, ARRAY_SIZE(chip_id),
+ (chipinfo->id > 0x9999) ? "%d" : "0x%04X", chipinfo->id);
+ bcma_info(bus, "Found chip with id %s, rev 0x%02X and package 0x%02X\n",
+ chip_id, chipinfo->rev, chipinfo->pkg);
}
int bcma_bus_scan(struct bcma_bus *bus)