diff options
Diffstat (limited to 'target/linux/generic/patches-3.14')
-rw-r--r-- | target/linux/generic/patches-3.14/025-bcma_backport.patch | 258 |
1 files changed, 245 insertions, 13 deletions
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>; ++ }; ++ }; |