diff options
5 files changed, 505 insertions, 309 deletions
diff --git a/target/linux/bcm53xx/patches-3.14/120-bcma-register-bcma-as-device-tree-driver.patch b/target/linux/bcm53xx/patches-3.14/120-bcma-register-bcma-as-device-tree-driver.patch deleted file mode 100644 index 0af4bf66aa..0000000000 --- a/target/linux/bcm53xx/patches-3.14/120-bcma-register-bcma-as-device-tree-driver.patch +++ /dev/null @@ -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; diff --git a/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch b/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch index 53e4d91fa6..e38b5bc1c6 100644 --- a/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch +++ b/target/linux/bcm53xx/patches-3.14/121-bcma-get-irqs-from-dt.patch @@ -15,73 +15,24 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c -@@ -10,6 +10,8 @@ +@@ -10,6 +10,7 @@ #include <linux/platform_device.h> #include <linux/bcma/bcma.h> #include <linux/slab.h> +#include <linux/of_irq.h> -+#include <linux/of_address.h> + #include <linux/of_address.h> MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); - MODULE_LICENSE("GPL"); -@@ -131,6 +133,45 @@ static bool bcma_is_core_needed_early(u1 - return false; - } +@@ -159,8 +160,10 @@ static void bcma_of_fill_device(struct p + struct device_node *node; -+#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); + node = bcma_of_find_child_device(parent, core); +- if (node) +- core->dev.of_node = node; + if (!node) + return; + core->dev.of_node = node; + core->irq = irq_of_parse_and_map(node, 0); -+} -+#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 +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; + } + #else + static void bcma_of_fill_device(struct platform_device *parent, diff --git a/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch b/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch index 2cdfebf983..11d4148ccd 100644 --- a/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch +++ b/target/linux/bcm53xx/patches-3.14/170-pcie2-bcma-add-new-PCIe2-driver-for-bcma.patch @@ -17,7 +17,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> --- a/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 CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK select MIGHT_HAVE_PCI diff --git a/target/linux/generic/patches-3.10/025-bcma_backport.patch b/target/linux/generic/patches-3.10/025-bcma_backport.patch index 0ff3483314..3468e79e06 100644 --- a/target/linux/generic/patches-3.10/025-bcma_backport.patch +++ b/target/linux/generic/patches-3.10/025-bcma_backport.patch @@ -77,6 +77,27 @@ /* driver_chipcommon_pmu.c */ u32 bcma_pmu_get_alp_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 +++ b/drivers/bcma/core.c @@ -9,6 +9,25 @@ @@ -512,7 +533,7 @@ chip->label = "bcma_gpio"; 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->direction_input = bcma_gpio_direction_input; chip->direction_output = bcma_gpio_direction_output; @@ -520,6 +541,10 @@ chip->to_irq = bcma_gpio_to_irq; - chip->ngpio = 16; +#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: @@ -532,7 +557,7 @@ /* 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 * 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 chip->base = -1; @@ -929,7 +954,15 @@ MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); --- a/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; } @@ -977,7 +1010,7 @@ } 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); } @@ -993,6 +1026,43 @@ + 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; @@ -1009,7 +1079,13 @@ + 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; @@ -1085,7 +1161,7 @@ } #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); if (err) { bcma_err(bus, "Failed to scan: %d\n", err); @@ -1094,7 +1170,7 @@ } /* 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); } @@ -1107,7 +1183,7 @@ /* Try to get SPROM */ err = bcma_sprom_get(bus); 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); } @@ -1121,7 +1197,7 @@ /* Init MIPS core */ core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); 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]); } @@ -1135,7 +1211,7 @@ /* Init GBIT MAC COMMON core */ core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); 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 */ @@ -1144,7 +1220,7 @@ 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) 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[1] = bcma_find_core(bus, BCMA_CORE_PCIE); 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_id match; @@ -1162,6 +1238,26 @@ match.manuf = BCMA_MANUF_BCM; match.id = bcma_cc_core_id(bus); 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 +++ b/drivers/bcma/scan.c @@ -32,6 +32,18 @@ static const struct bcma_device_id_name @@ -1625,7 +1721,16 @@ u32 wrap; 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 list_head cores; u8 nr_cores; @@ -1639,7 +1744,7 @@ struct bcma_drv_mips drv_mips; 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); } @@ -2139,7 +2244,17 @@ void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) --- a/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) { @@ -2156,7 +2271,7 @@ 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) { struct bcma_bus *bus = &soc->bus; @@ -2164,9 +2279,11 @@ /* iomap only first core. We have to read some register on this core * 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->ops = &bcma_host_soc_ops; ++ bus->host_pdev = NULL; - /* Register */ + /* Initialize struct, detect chip */ @@ -2184,6 +2301,86 @@ err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips); if (err) 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 +++ b/include/linux/bcma/bcma_regs.h @@ -39,6 +39,11 @@ @@ -2296,3 +2493,38 @@ panic("Failed to initialize BCMA bus (err %d)", err); 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>; ++ }; ++ }; diff --git a/target/linux/generic/patches-3.14/025-bcma_backport.patch b/target/linux/generic/patches-3.14/025-bcma_backport.patch index 1bb026c1e7..0aff0f7dc7 100644 --- a/target/linux/generic/patches-3.14/025-bcma_backport.patch +++ b/target/linux/generic/patches-3.14/025-bcma_backport.patch @@ -33,7 +33,7 @@ static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) { 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->direction_input = bcma_gpio_direction_input; chip->direction_output = bcma_gpio_direction_output; @@ -42,6 +42,10 @@ chip->to_irq = bcma_gpio_to_irq; #endif - 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) { + case BCMA_CHIP_ID_BCM5357: + case BCMA_CHIP_ID_BCM53572: @@ -257,7 +261,15 @@ MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); --- a/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); } @@ -273,6 +285,43 @@ + 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; @@ -289,7 +338,13 @@ + 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; @@ -366,7 +421,7 @@ } #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); } @@ -379,7 +434,7 @@ /* Try to get SPROM */ err = bcma_sprom_get(bus); 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); } @@ -393,7 +448,7 @@ /* Init MIPS core */ core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); 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]); } @@ -407,7 +462,7 @@ /* Init GBIT MAC COMMON core */ core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); 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 */ @@ -416,7 +471,7 @@ 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) 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[1] = bcma_find_core(bus, BCMA_CORE_PCIE); 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_id match; @@ -434,6 +489,26 @@ match.manuf = BCMA_MANUF_BCM; match.id = bcma_cc_core_id(bus); 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 +++ b/drivers/bcma/sprom.c @@ -201,6 +201,23 @@ static int bcma_sprom_valid(struct bcma_ @@ -558,7 +633,16 @@ u32 wrap; 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 list_head cores; u8 nr_cores; @@ -857,7 +941,17 @@ eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); --- a/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) { @@ -874,7 +968,7 @@ 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) { struct bcma_bus *bus = &soc->bus; @@ -882,9 +976,11 @@ /* iomap only first core. We have to read some register on this core * 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->ops = &bcma_host_soc_ops; ++ bus->host_pdev = NULL; - /* Register */ + /* Initialize struct, detect chip */ @@ -902,6 +998,86 @@ err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips); if (err) 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 +++ b/drivers/bcma/driver_mips.c @@ -21,6 +21,14 @@ @@ -1030,6 +1206,27 @@ /* driver_chipcommon_pmu.c */ u32 bcma_pmu_get_alp_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 +++ b/drivers/bcma/driver_chipcommon_b.c @@ -0,0 +1,61 @@ @@ -1139,3 +1336,38 @@ 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>; ++ }; ++ }; |