kernel: update bcma to the tag master-2014-09-30 (wireless-next)
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 42710
This commit is contained in:
parent
26e85084b5
commit
59b965194d
5 changed files with 505 additions and 309 deletions
|
@ -1,219 +0,0 @@
|
||||||
From ef8bdd6f383d3b43a96cdaa990b5412e40dbf238 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
|
||||||
Date: Mon, 6 Jan 2014 23:29:15 +0100
|
|
||||||
Subject: [PATCH v3 1/2] bcma: register bcma as device tree driver
|
|
||||||
|
|
||||||
This driver is used by the bcm53xx ARM SoC code. Now it is possible to
|
|
||||||
give the address of the chipcommon core in device tree and bcma will
|
|
||||||
search for all the other cores.
|
|
||||||
|
|
||||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
|
||||||
---
|
|
||||||
Documentation/devicetree/bindings/bus/bcma.txt | 39 ++++++++++++
|
|
||||||
drivers/bcma/bcma_private.h | 14 +++++
|
|
||||||
drivers/bcma/host_soc.c | 82 ++++++++++++++++++++++++++
|
|
||||||
drivers/bcma/main.c | 6 ++
|
|
||||||
include/linux/bcma/bcma.h | 2 +
|
|
||||||
5 files changed, 143 insertions(+)
|
|
||||||
create mode 100644 Documentation/devicetree/bindings/bus/bcma.txt
|
|
||||||
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/Documentation/devicetree/bindings/bus/bcma.txt
|
|
||||||
@@ -0,0 +1,39 @@
|
|
||||||
+Driver for ARM AXI Bus with Broadcom Plugins (bcma)
|
|
||||||
+
|
|
||||||
+Required properties:
|
|
||||||
+
|
|
||||||
+- compatible : brcm,bus-axi
|
|
||||||
+
|
|
||||||
+- reg : iomem address range of chipcommon core
|
|
||||||
+
|
|
||||||
+The cores on the AXI bus are automatically detected by bcma with the
|
|
||||||
+memory ranges they are using and they get registered afterwards.
|
|
||||||
+Automatic detection of the IRQ number is not reliable on
|
|
||||||
+BCM47xx/BCM53xx ARM SoCs. To assign IRQ numbers to the cores, provide
|
|
||||||
+them manually through device tree. The IRQ number and the device tree
|
|
||||||
+child entry will get assigned to the core with the matching reg address.
|
|
||||||
+
|
|
||||||
+Example:
|
|
||||||
+
|
|
||||||
+ axi@18000000 {
|
|
||||||
+ compatible = "brcm,bus-axi";
|
|
||||||
+ reg = <0x18000000 0x1000>;
|
|
||||||
+ ranges = <0x00000000 0x18000000 0x00100000>;
|
|
||||||
+ #address-cells = <1>;
|
|
||||||
+ #size-cells = <1>;
|
|
||||||
+
|
|
||||||
+ pcie@12000 {
|
|
||||||
+ reg = <0x00012000 0x1000>;
|
|
||||||
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ ethernet@24000 {
|
|
||||||
+ reg = <0x00024000 0x1000>;
|
|
||||||
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ ethernet@25000 {
|
|
||||||
+ reg = <0x00025000 0x1000>;
|
|
||||||
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
--- a/drivers/bcma/bcma_private.h
|
|
||||||
+++ b/drivers/bcma/bcma_private.h
|
|
||||||
@@ -88,6 +88,20 @@ extern int __init bcma_host_pci_init(voi
|
|
||||||
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);
|
|
||||||
|
|
||||||
--- 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
|
|
||||||
/* 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,81 @@ int __init bcma_host_soc_init(struct bcm
|
|
||||||
|
|
||||||
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",
|
|
||||||
+ .owner = THIS_MODULE,
|
|
||||||
+ .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 */
|
|
||||||
--- a/drivers/bcma/main.c
|
|
||||||
+++ b/drivers/bcma/main.c
|
|
||||||
@@ -528,6 +528,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 +550,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)
|
|
||||||
--- a/include/linux/bcma/bcma.h
|
|
||||||
+++ b/include/linux/bcma/bcma.h
|
|
||||||
@@ -323,6 +323,8 @@ struct bcma_bus {
|
|
||||||
struct pci_dev *host_pci;
|
|
||||||
/* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
|
|
||||||
struct sdio_func *host_sdio;
|
|
||||||
+ /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
|
|
||||||
+ struct platform_device *host_pdev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bcma_chipinfo chipinfo;
|
|
|
@ -15,73 +15,24 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
|
||||||
--- a/drivers/bcma/main.c
|
--- a/drivers/bcma/main.c
|
||||||
+++ b/drivers/bcma/main.c
|
+++ b/drivers/bcma/main.c
|
||||||
@@ -10,6 +10,8 @@
|
@@ -10,6 +10,7 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/bcma/bcma.h>
|
#include <linux/bcma/bcma.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
+#include <linux/of_irq.h>
|
+#include <linux/of_irq.h>
|
||||||
+#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
|
MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
|
||||||
MODULE_LICENSE("GPL");
|
@@ -159,8 +160,10 @@ static void bcma_of_fill_device(struct p
|
||||||
@@ -131,6 +133,45 @@ static bool bcma_is_core_needed_early(u1
|
struct device_node *node;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
+#ifdef CONFIG_OF
|
node = bcma_of_find_child_device(parent, core);
|
||||||
+static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
|
- if (node)
|
||||||
+ struct bcma_device *core)
|
- core->dev.of_node = node;
|
||||||
+{
|
|
||||||
+ 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)
|
+ if (!node)
|
||||||
+ return;
|
+ return;
|
||||||
+ core->dev.of_node = node;
|
+ core->dev.of_node = node;
|
||||||
+ core->irq = irq_of_parse_and_map(node, 0);
|
+ core->irq = irq_of_parse_and_map(node, 0);
|
||||||
+}
|
}
|
||||||
+#else
|
#else
|
||||||
+static void bcma_of_fill_device(struct platform_device *parent,
|
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 +188,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;
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||||
|
|
||||||
--- a/arch/arm/mach-bcm/Kconfig
|
--- a/arch/arm/mach-bcm/Kconfig
|
||||||
+++ b/arch/arm/mach-bcm/Kconfig
|
+++ b/arch/arm/mach-bcm/Kconfig
|
||||||
@@ -45,6 +45,7 @@ config ARCH_BCM_5301X
|
@@ -46,6 +46,7 @@ config ARCH_BCM_5301X
|
||||||
select ARM_GLOBAL_TIMER
|
select ARM_GLOBAL_TIMER
|
||||||
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
|
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
|
||||||
select MIGHT_HAVE_PCI
|
select MIGHT_HAVE_PCI
|
||||||
|
|
|
@ -77,6 +77,27 @@
|
||||||
/* driver_chipcommon_pmu.c */
|
/* driver_chipcommon_pmu.c */
|
||||||
u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
|
u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
|
||||||
u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
|
u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
|
||||||
|
@@ -84,6 +88,20 @@ extern int __init bcma_host_pci_init(voi
|
||||||
|
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);
|
||||||
|
|
||||||
--- a/drivers/bcma/core.c
|
--- a/drivers/bcma/core.c
|
||||||
+++ b/drivers/bcma/core.c
|
+++ b/drivers/bcma/core.c
|
||||||
@@ -9,6 +9,25 @@
|
@@ -9,6 +9,25 @@
|
||||||
|
@ -512,7 +533,7 @@
|
||||||
|
|
||||||
chip->label = "bcma_gpio";
|
chip->label = "bcma_gpio";
|
||||||
chip->owner = THIS_MODULE;
|
chip->owner = THIS_MODULE;
|
||||||
@@ -95,8 +215,18 @@ int bcma_gpio_init(struct bcma_drv_cc *c
|
@@ -95,8 +215,22 @@ int bcma_gpio_init(struct bcma_drv_cc *c
|
||||||
chip->set = bcma_gpio_set_value;
|
chip->set = bcma_gpio_set_value;
|
||||||
chip->direction_input = bcma_gpio_direction_input;
|
chip->direction_input = bcma_gpio_direction_input;
|
||||||
chip->direction_output = bcma_gpio_direction_output;
|
chip->direction_output = bcma_gpio_direction_output;
|
||||||
|
@ -520,6 +541,10 @@
|
||||||
chip->to_irq = bcma_gpio_to_irq;
|
chip->to_irq = bcma_gpio_to_irq;
|
||||||
- chip->ngpio = 16;
|
- chip->ngpio = 16;
|
||||||
+#endif
|
+#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) {
|
+ switch (cc->core->bus->chipinfo.id) {
|
||||||
+ case BCMA_CHIP_ID_BCM5357:
|
+ case BCMA_CHIP_ID_BCM5357:
|
||||||
+ case BCMA_CHIP_ID_BCM53572:
|
+ case BCMA_CHIP_ID_BCM53572:
|
||||||
|
@ -532,7 +557,7 @@
|
||||||
/* There is just one SoC in one device and its GPIO addresses should be
|
/* There is just one SoC in one device and its GPIO addresses should be
|
||||||
* deterministic to address them more easily. The other buses could get
|
* deterministic to address them more easily. The other buses could get
|
||||||
* a random base number. */
|
* a random base number. */
|
||||||
@@ -105,10 +235,21 @@ int bcma_gpio_init(struct bcma_drv_cc *c
|
@@ -105,10 +239,21 @@ int bcma_gpio_init(struct bcma_drv_cc *c
|
||||||
else
|
else
|
||||||
chip->base = -1;
|
chip->base = -1;
|
||||||
|
|
||||||
|
@ -929,7 +954,15 @@
|
||||||
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
|
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
|
||||||
--- a/drivers/bcma/main.c
|
--- a/drivers/bcma/main.c
|
||||||
+++ b/drivers/bcma/main.c
|
+++ b/drivers/bcma/main.c
|
||||||
@@ -69,28 +69,36 @@ static u16 bcma_cc_core_id(struct bcma_b
|
@@ -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");
|
||||||
|
@@ -69,28 +70,36 @@ static u16 bcma_cc_core_id(struct bcma_b
|
||||||
return BCMA_CORE_CHIPCOMMON;
|
return BCMA_CORE_CHIPCOMMON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,7 +1010,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bcma_release_core_dev(struct device *dev)
|
static void bcma_release_core_dev(struct device *dev)
|
||||||
@@ -103,55 +111,78 @@ static void bcma_release_core_dev(struct
|
@@ -103,55 +112,121 @@ static void bcma_release_core_dev(struct
|
||||||
kfree(core);
|
kfree(core);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,6 +1026,43 @@
|
||||||
+ return false;
|
+ 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)
|
+static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
|
||||||
+{
|
+{
|
||||||
+ int err;
|
+ int err;
|
||||||
|
@ -1009,7 +1079,13 @@
|
||||||
+ break;
|
+ break;
|
||||||
+ case BCMA_HOSTTYPE_SOC:
|
+ case BCMA_HOSTTYPE_SOC:
|
||||||
+ core->dev.dma_mask = &core->dev.coherent_dma_mask;
|
+ 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;
|
+ break;
|
||||||
+ case BCMA_HOSTTYPE_SDIO:
|
+ case BCMA_HOSTTYPE_SDIO:
|
||||||
+ break;
|
+ break;
|
||||||
|
@ -1085,7 +1161,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BCMA_DRIVER_MIPS
|
#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||||
@@ -218,7 +249,7 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -218,7 +293,7 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
err = bcma_bus_scan(bus);
|
err = bcma_bus_scan(bus);
|
||||||
if (err) {
|
if (err) {
|
||||||
bcma_err(bus, "Failed to scan: %d\n", err);
|
bcma_err(bus, "Failed to scan: %d\n", err);
|
||||||
|
@ -1094,7 +1170,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Early init CC core */
|
/* Early init CC core */
|
||||||
@@ -228,6 +259,12 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -228,6 +303,12 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
bcma_core_chipcommon_early_init(&bus->drv_cc);
|
bcma_core_chipcommon_early_init(&bus->drv_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,7 +1183,7 @@
|
||||||
/* Try to get SPROM */
|
/* Try to get SPROM */
|
||||||
err = bcma_sprom_get(bus);
|
err = bcma_sprom_get(bus);
|
||||||
if (err == -ENOENT) {
|
if (err == -ENOENT) {
|
||||||
@@ -242,6 +279,13 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -242,6 +323,13 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
bcma_core_chipcommon_init(&bus->drv_cc);
|
bcma_core_chipcommon_init(&bus->drv_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1121,7 +1197,7 @@
|
||||||
/* Init MIPS core */
|
/* Init MIPS core */
|
||||||
core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||||
if (core) {
|
if (core) {
|
||||||
@@ -263,6 +307,13 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -263,6 +351,13 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
bcma_core_pci_init(&bus->drv_pci[1]);
|
bcma_core_pci_init(&bus->drv_pci[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1135,7 +1211,7 @@
|
||||||
/* Init GBIT MAC COMMON core */
|
/* Init GBIT MAC COMMON core */
|
||||||
core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
||||||
if (core) {
|
if (core) {
|
||||||
@@ -271,7 +322,7 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -271,7 +366,7 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register found cores */
|
/* Register found cores */
|
||||||
|
@ -1144,7 +1220,7 @@
|
||||||
|
|
||||||
bcma_info(bus, "Bus registered\n");
|
bcma_info(bus, "Bus registered\n");
|
||||||
|
|
||||||
@@ -289,6 +340,8 @@ void bcma_bus_unregister(struct bcma_bus
|
@@ -289,6 +384,8 @@ void bcma_bus_unregister(struct bcma_bus
|
||||||
else if (err)
|
else if (err)
|
||||||
bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
|
bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
|
||||||
|
|
||||||
|
@ -1153,7 +1229,7 @@
|
||||||
cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||||
cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
|
cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
|
||||||
cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
||||||
@@ -308,8 +361,6 @@ int __init bcma_bus_early_register(struc
|
@@ -308,8 +405,6 @@ int __init bcma_bus_early_register(struc
|
||||||
struct bcma_device *core;
|
struct bcma_device *core;
|
||||||
struct bcma_device_id match;
|
struct bcma_device_id match;
|
||||||
|
|
||||||
|
@ -1162,6 +1238,26 @@
|
||||||
match.manuf = BCMA_MANUF_BCM;
|
match.manuf = BCMA_MANUF_BCM;
|
||||||
match.id = bcma_cc_core_id(bus);
|
match.id = bcma_cc_core_id(bus);
|
||||||
match.class = BCMA_CL_SIM;
|
match.class = BCMA_CL_SIM;
|
||||||
|
@@ -468,6 +563,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) {
|
||||||
|
@@ -485,6 +585,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)
|
||||||
--- a/drivers/bcma/scan.c
|
--- a/drivers/bcma/scan.c
|
||||||
+++ b/drivers/bcma/scan.c
|
+++ b/drivers/bcma/scan.c
|
||||||
@@ -32,6 +32,18 @@ static const struct bcma_device_id_name
|
@@ -32,6 +32,18 @@ static const struct bcma_device_id_name
|
||||||
|
@ -1625,7 +1721,16 @@
|
||||||
u32 wrap;
|
u32 wrap;
|
||||||
|
|
||||||
void __iomem *io_addr;
|
void __iomem *io_addr;
|
||||||
@@ -310,11 +332,12 @@ struct bcma_bus {
|
@@ -301,6 +323,8 @@ struct bcma_bus {
|
||||||
|
struct pci_dev *host_pci;
|
||||||
|
/* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
|
||||||
|
struct sdio_func *host_sdio;
|
||||||
|
+ /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
|
||||||
|
+ struct platform_device *host_pdev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bcma_chipinfo chipinfo;
|
||||||
|
@@ -310,11 +334,12 @@ struct bcma_bus {
|
||||||
struct bcma_device *mapped_core;
|
struct bcma_device *mapped_core;
|
||||||
struct list_head cores;
|
struct list_head cores;
|
||||||
u8 nr_cores;
|
u8 nr_cores;
|
||||||
|
@ -1639,7 +1744,7 @@
|
||||||
struct bcma_drv_mips drv_mips;
|
struct bcma_drv_mips drv_mips;
|
||||||
struct bcma_drv_gmac_cmn drv_gmac_cmn;
|
struct bcma_drv_gmac_cmn drv_gmac_cmn;
|
||||||
|
|
||||||
@@ -400,7 +423,14 @@ static inline void bcma_maskset16(struct
|
@@ -400,7 +425,14 @@ static inline void bcma_maskset16(struct
|
||||||
bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
|
bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2139,7 +2244,17 @@
|
||||||
void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
|
void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
|
||||||
--- a/drivers/bcma/host_soc.c
|
--- a/drivers/bcma/host_soc.c
|
||||||
+++ b/drivers/bcma/host_soc.c
|
+++ b/drivers/bcma/host_soc.c
|
||||||
@@ -134,12 +134,16 @@ static void bcma_host_soc_block_write(st
|
@@ -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>
|
||||||
|
|
||||||
|
@@ -134,12 +137,16 @@ static void bcma_host_soc_block_write(st
|
||||||
|
|
||||||
static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
|
static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
|
||||||
{
|
{
|
||||||
|
@ -2156,7 +2271,7 @@
|
||||||
writel(value, core->io_wrap + offset);
|
writel(value, core->io_wrap + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +165,6 @@ static const struct bcma_host_ops bcma_h
|
@@ -161,7 +168,6 @@ static const struct bcma_host_ops bcma_h
|
||||||
int __init bcma_host_soc_register(struct bcma_soc *soc)
|
int __init bcma_host_soc_register(struct bcma_soc *soc)
|
||||||
{
|
{
|
||||||
struct bcma_bus *bus = &soc->bus;
|
struct bcma_bus *bus = &soc->bus;
|
||||||
|
@ -2164,9 +2279,11 @@
|
||||||
|
|
||||||
/* iomap only first core. We have to read some register on this core
|
/* iomap only first core. We have to read some register on this core
|
||||||
* to scan the bus.
|
* to scan the bus.
|
||||||
@@ -174,7 +177,18 @@ int __init bcma_host_soc_register(struct
|
@@ -173,11 +179,100 @@ int __init bcma_host_soc_register(struct
|
||||||
|
/* Host specific */
|
||||||
bus->hosttype = BCMA_HOSTTYPE_SOC;
|
bus->hosttype = BCMA_HOSTTYPE_SOC;
|
||||||
bus->ops = &bcma_host_soc_ops;
|
bus->ops = &bcma_host_soc_ops;
|
||||||
|
+ bus->host_pdev = NULL;
|
||||||
|
|
||||||
- /* Register */
|
- /* Register */
|
||||||
+ /* Initialize struct, detect chip */
|
+ /* Initialize struct, detect chip */
|
||||||
|
@ -2184,6 +2301,86 @@
|
||||||
err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
|
err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
|
||||||
if (err)
|
if (err)
|
||||||
iounmap(bus->mmio);
|
iounmap(bus->mmio);
|
||||||
|
|
||||||
|
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 */
|
||||||
--- a/include/linux/bcma/bcma_regs.h
|
--- a/include/linux/bcma/bcma_regs.h
|
||||||
+++ b/include/linux/bcma/bcma_regs.h
|
+++ b/include/linux/bcma/bcma_regs.h
|
||||||
@@ -39,6 +39,11 @@
|
@@ -39,6 +39,11 @@
|
||||||
|
@ -2296,3 +2493,38 @@
|
||||||
panic("Failed to initialize BCMA bus (err %d)", err);
|
panic("Failed to initialize BCMA bus (err %d)", err);
|
||||||
|
|
||||||
bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL);
|
bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL);
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/bus/bcma.txt
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+Driver for ARM AXI Bus with Broadcom Plugins (bcma)
|
||||||
|
+
|
||||||
|
+Required properties:
|
||||||
|
+
|
||||||
|
+- compatible : brcm,bus-axi
|
||||||
|
+
|
||||||
|
+- reg : iomem address range of chipcommon core
|
||||||
|
+
|
||||||
|
+The cores on the AXI bus are automatically detected by bcma with the
|
||||||
|
+memory ranges they are using and they get registered afterwards.
|
||||||
|
+
|
||||||
|
+The top-level axi bus may contain children representing attached cores
|
||||||
|
+(devices). This is needed since some hardware details can't be auto
|
||||||
|
+detected (e.g. IRQ numbers). Also some of the cores may be responsible
|
||||||
|
+for extra things, e.g. ChipCommon providing access to the GPIO chip.
|
||||||
|
+
|
||||||
|
+Example:
|
||||||
|
+
|
||||||
|
+ axi@18000000 {
|
||||||
|
+ compatible = "brcm,bus-axi";
|
||||||
|
+ reg = <0x18000000 0x1000>;
|
||||||
|
+ ranges = <0x00000000 0x18000000 0x00100000>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
+
|
||||||
|
+ chipcommon {
|
||||||
|
+ reg = <0x00000000 0x1000>;
|
||||||
|
+
|
||||||
|
+ gpio-controller;
|
||||||
|
+ #gpio-cells = <2>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
|
static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
|
||||||
{
|
{
|
||||||
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
|
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
|
||||||
@@ -215,10 +215,18 @@ int bcma_gpio_init(struct bcma_drv_cc *c
|
@@ -215,10 +215,22 @@ int bcma_gpio_init(struct bcma_drv_cc *c
|
||||||
chip->set = bcma_gpio_set_value;
|
chip->set = bcma_gpio_set_value;
|
||||||
chip->direction_input = bcma_gpio_direction_input;
|
chip->direction_input = bcma_gpio_direction_input;
|
||||||
chip->direction_output = bcma_gpio_direction_output;
|
chip->direction_output = bcma_gpio_direction_output;
|
||||||
|
@ -42,6 +42,10 @@
|
||||||
chip->to_irq = bcma_gpio_to_irq;
|
chip->to_irq = bcma_gpio_to_irq;
|
||||||
#endif
|
#endif
|
||||||
- chip->ngpio = 16;
|
- chip->ngpio = 16;
|
||||||
|
+#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) {
|
+ switch (cc->core->bus->chipinfo.id) {
|
||||||
+ case BCMA_CHIP_ID_BCM5357:
|
+ case BCMA_CHIP_ID_BCM5357:
|
||||||
+ case BCMA_CHIP_ID_BCM53572:
|
+ case BCMA_CHIP_ID_BCM53572:
|
||||||
|
@ -257,7 +261,15 @@
|
||||||
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
|
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
|
||||||
--- a/drivers/bcma/main.c
|
--- a/drivers/bcma/main.c
|
||||||
+++ b/drivers/bcma/main.c
|
+++ b/drivers/bcma/main.c
|
||||||
@@ -120,56 +120,78 @@ static void bcma_release_core_dev(struct
|
@@ -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");
|
||||||
|
@@ -120,56 +121,121 @@ static void bcma_release_core_dev(struct
|
||||||
kfree(core);
|
kfree(core);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +285,43 @@
|
||||||
+ return false;
|
+ 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)
|
+static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
|
||||||
+{
|
+{
|
||||||
+ int err;
|
+ int err;
|
||||||
|
@ -289,7 +338,13 @@
|
||||||
+ break;
|
+ break;
|
||||||
+ case BCMA_HOSTTYPE_SOC:
|
+ case BCMA_HOSTTYPE_SOC:
|
||||||
+ core->dev.dma_mask = &core->dev.coherent_dma_mask;
|
+ 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;
|
+ break;
|
||||||
+ case BCMA_HOSTTYPE_SDIO:
|
+ case BCMA_HOSTTYPE_SDIO:
|
||||||
+ break;
|
+ break;
|
||||||
|
@ -366,7 +421,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BCMA_DRIVER_MIPS
|
#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||||
@@ -246,6 +268,12 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -246,6 +312,12 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
bcma_core_chipcommon_early_init(&bus->drv_cc);
|
bcma_core_chipcommon_early_init(&bus->drv_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +434,7 @@
|
||||||
/* Try to get SPROM */
|
/* Try to get SPROM */
|
||||||
err = bcma_sprom_get(bus);
|
err = bcma_sprom_get(bus);
|
||||||
if (err == -ENOENT) {
|
if (err == -ENOENT) {
|
||||||
@@ -260,6 +288,13 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -260,6 +332,13 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
bcma_core_chipcommon_init(&bus->drv_cc);
|
bcma_core_chipcommon_init(&bus->drv_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +448,7 @@
|
||||||
/* Init MIPS core */
|
/* Init MIPS core */
|
||||||
core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||||
if (core) {
|
if (core) {
|
||||||
@@ -281,6 +316,13 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -281,6 +360,13 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
bcma_core_pci_init(&bus->drv_pci[1]);
|
bcma_core_pci_init(&bus->drv_pci[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +462,7 @@
|
||||||
/* Init GBIT MAC COMMON core */
|
/* Init GBIT MAC COMMON core */
|
||||||
core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
||||||
if (core) {
|
if (core) {
|
||||||
@@ -289,7 +331,7 @@ int bcma_bus_register(struct bcma_bus *b
|
@@ -289,7 +375,7 @@ int bcma_bus_register(struct bcma_bus *b
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register found cores */
|
/* Register found cores */
|
||||||
|
@ -416,7 +471,7 @@
|
||||||
|
|
||||||
bcma_info(bus, "Bus registered\n");
|
bcma_info(bus, "Bus registered\n");
|
||||||
|
|
||||||
@@ -307,6 +349,8 @@ void bcma_bus_unregister(struct bcma_bus
|
@@ -307,6 +393,8 @@ void bcma_bus_unregister(struct bcma_bus
|
||||||
else if (err)
|
else if (err)
|
||||||
bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
|
bcma_err(bus, "Can not unregister GPIO driver: %i\n", err);
|
||||||
|
|
||||||
|
@ -425,7 +480,7 @@
|
||||||
cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||||
cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
|
cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
|
||||||
cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
||||||
@@ -326,8 +370,6 @@ int __init bcma_bus_early_register(struc
|
@@ -326,8 +414,6 @@ int __init bcma_bus_early_register(struc
|
||||||
struct bcma_device *core;
|
struct bcma_device *core;
|
||||||
struct bcma_device_id match;
|
struct bcma_device_id match;
|
||||||
|
|
||||||
|
@ -434,6 +489,26 @@
|
||||||
match.manuf = BCMA_MANUF_BCM;
|
match.manuf = BCMA_MANUF_BCM;
|
||||||
match.id = bcma_cc_core_id(bus);
|
match.id = bcma_cc_core_id(bus);
|
||||||
match.class = BCMA_CL_SIM;
|
match.class = BCMA_CL_SIM;
|
||||||
|
@@ -486,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) {
|
||||||
|
@@ -503,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)
|
||||||
--- a/drivers/bcma/sprom.c
|
--- a/drivers/bcma/sprom.c
|
||||||
+++ b/drivers/bcma/sprom.c
|
+++ b/drivers/bcma/sprom.c
|
||||||
@@ -201,6 +201,23 @@ static int bcma_sprom_valid(struct bcma_
|
@@ -201,6 +201,23 @@ static int bcma_sprom_valid(struct bcma_
|
||||||
|
@ -558,7 +633,16 @@
|
||||||
u32 wrap;
|
u32 wrap;
|
||||||
|
|
||||||
void __iomem *io_addr;
|
void __iomem *io_addr;
|
||||||
@@ -328,11 +332,12 @@ struct bcma_bus {
|
@@ -319,6 +323,8 @@ struct bcma_bus {
|
||||||
|
struct pci_dev *host_pci;
|
||||||
|
/* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
|
||||||
|
struct sdio_func *host_sdio;
|
||||||
|
+ /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
|
||||||
|
+ struct platform_device *host_pdev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bcma_chipinfo chipinfo;
|
||||||
|
@@ -328,11 +334,12 @@ struct bcma_bus {
|
||||||
struct bcma_device *mapped_core;
|
struct bcma_device *mapped_core;
|
||||||
struct list_head cores;
|
struct list_head cores;
|
||||||
u8 nr_cores;
|
u8 nr_cores;
|
||||||
|
@ -857,7 +941,17 @@
|
||||||
eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
|
eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
|
||||||
--- a/drivers/bcma/host_soc.c
|
--- a/drivers/bcma/host_soc.c
|
||||||
+++ b/drivers/bcma/host_soc.c
|
+++ b/drivers/bcma/host_soc.c
|
||||||
@@ -134,12 +134,16 @@ static void bcma_host_soc_block_write(st
|
@@ -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>
|
||||||
|
|
||||||
|
@@ -134,12 +137,16 @@ static void bcma_host_soc_block_write(st
|
||||||
|
|
||||||
static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
|
static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
|
||||||
{
|
{
|
||||||
|
@ -874,7 +968,7 @@
|
||||||
writel(value, core->io_wrap + offset);
|
writel(value, core->io_wrap + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +165,6 @@ static const struct bcma_host_ops bcma_h
|
@@ -161,7 +168,6 @@ static const struct bcma_host_ops bcma_h
|
||||||
int __init bcma_host_soc_register(struct bcma_soc *soc)
|
int __init bcma_host_soc_register(struct bcma_soc *soc)
|
||||||
{
|
{
|
||||||
struct bcma_bus *bus = &soc->bus;
|
struct bcma_bus *bus = &soc->bus;
|
||||||
|
@ -882,9 +976,11 @@
|
||||||
|
|
||||||
/* iomap only first core. We have to read some register on this core
|
/* iomap only first core. We have to read some register on this core
|
||||||
* to scan the bus.
|
* to scan the bus.
|
||||||
@@ -174,7 +177,18 @@ int __init bcma_host_soc_register(struct
|
@@ -173,11 +179,100 @@ int __init bcma_host_soc_register(struct
|
||||||
|
/* Host specific */
|
||||||
bus->hosttype = BCMA_HOSTTYPE_SOC;
|
bus->hosttype = BCMA_HOSTTYPE_SOC;
|
||||||
bus->ops = &bcma_host_soc_ops;
|
bus->ops = &bcma_host_soc_ops;
|
||||||
|
+ bus->host_pdev = NULL;
|
||||||
|
|
||||||
- /* Register */
|
- /* Register */
|
||||||
+ /* Initialize struct, detect chip */
|
+ /* Initialize struct, detect chip */
|
||||||
|
@ -902,6 +998,86 @@
|
||||||
err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
|
err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
|
||||||
if (err)
|
if (err)
|
||||||
iounmap(bus->mmio);
|
iounmap(bus->mmio);
|
||||||
|
|
||||||
|
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 */
|
||||||
--- a/drivers/bcma/driver_mips.c
|
--- a/drivers/bcma/driver_mips.c
|
||||||
+++ b/drivers/bcma/driver_mips.c
|
+++ b/drivers/bcma/driver_mips.c
|
||||||
@@ -21,6 +21,14 @@
|
@@ -21,6 +21,14 @@
|
||||||
|
@ -1030,6 +1206,27 @@
|
||||||
/* driver_chipcommon_pmu.c */
|
/* driver_chipcommon_pmu.c */
|
||||||
u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
|
u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
|
||||||
u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
|
u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
|
||||||
|
@@ -84,6 +88,20 @@ extern int __init bcma_host_pci_init(voi
|
||||||
|
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);
|
||||||
|
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/drivers/bcma/driver_chipcommon_b.c
|
+++ b/drivers/bcma/driver_chipcommon_b.c
|
||||||
@@ -0,0 +1,61 @@
|
@@ -0,0 +1,61 @@
|
||||||
|
@ -1139,3 +1336,38 @@
|
||||||
|
|
||||||
int bcma_bus_register(struct bcma_bus *bus);
|
int bcma_bus_register(struct bcma_bus *bus);
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Documentation/devicetree/bindings/bus/bcma.txt
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+Driver for ARM AXI Bus with Broadcom Plugins (bcma)
|
||||||
|
+
|
||||||
|
+Required properties:
|
||||||
|
+
|
||||||
|
+- compatible : brcm,bus-axi
|
||||||
|
+
|
||||||
|
+- reg : iomem address range of chipcommon core
|
||||||
|
+
|
||||||
|
+The cores on the AXI bus are automatically detected by bcma with the
|
||||||
|
+memory ranges they are using and they get registered afterwards.
|
||||||
|
+
|
||||||
|
+The top-level axi bus may contain children representing attached cores
|
||||||
|
+(devices). This is needed since some hardware details can't be auto
|
||||||
|
+detected (e.g. IRQ numbers). Also some of the cores may be responsible
|
||||||
|
+for extra things, e.g. ChipCommon providing access to the GPIO chip.
|
||||||
|
+
|
||||||
|
+Example:
|
||||||
|
+
|
||||||
|
+ axi@18000000 {
|
||||||
|
+ compatible = "brcm,bus-axi";
|
||||||
|
+ reg = <0x18000000 0x1000>;
|
||||||
|
+ ranges = <0x00000000 0x18000000 0x00100000>;
|
||||||
|
+ #address-cells = <1>;
|
||||||
|
+ #size-cells = <1>;
|
||||||
|
+
|
||||||
|
+ chipcommon {
|
||||||
|
+ reg = <0x00000000 0x1000>;
|
||||||
|
+
|
||||||
|
+ gpio-controller;
|
||||||
|
+ #gpio-cells = <2>;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
|
Loading…
Reference in a new issue