bcm53xx: update patches adding bcma support
[openwrt.git] / target / linux / bcm53xx / patches-3.14 / 120-bcma-register-bcma-as-device-tree-driver.patch
1 From ef8bdd6f383d3b43a96cdaa990b5412e40dbf238 Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Mon, 6 Jan 2014 23:29:15 +0100
4 Subject: [PATCH v3 1/2] bcma: register bcma as device tree driver
5
6 This driver is used by the bcm53xx ARM SoC code. Now it is possible to
7 give the address of the chipcommon core in device tree and bcma will
8 search for all the other cores.
9
10 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
11 ---
12  Documentation/devicetree/bindings/bus/bcma.txt | 39 ++++++++++++
13  drivers/bcma/bcma_private.h                    | 14 +++++
14  drivers/bcma/host_soc.c                        | 82 ++++++++++++++++++++++++++
15  drivers/bcma/main.c                            |  6 ++
16  include/linux/bcma/bcma.h                      |  2 +
17  5 files changed, 143 insertions(+)
18  create mode 100644 Documentation/devicetree/bindings/bus/bcma.txt
19
20 --- /dev/null
21 +++ b/Documentation/devicetree/bindings/bus/bcma.txt
22 @@ -0,0 +1,39 @@
23 +Driver for ARM AXI Bus with Broadcom Plugins (bcma)
24 +
25 +Required properties:
26 +
27 +- compatible : brcm,bus-axi
28 +
29 +- reg : iomem address range of chipcommon core
30 +
31 +The cores on the AXI bus are automatically detected by bcma with the
32 +memory ranges they are using and they get registered afterwards.
33 +Automatic detection of the IRQ number is not reliable on
34 +BCM47xx/BCM53xx ARM SoCs. To assign IRQ numbers to the cores, provide
35 +them manually through device tree. The IRQ number and the device tree
36 +child entry will get assigned to the core with the matching reg address.
37 +
38 +Example:
39 +
40 +       axi@18000000 {
41 +               compatible = "brcm,bus-axi";
42 +               reg = <0x18000000 0x1000>;
43 +               ranges = <0x00000000 0x18000000 0x00100000>;
44 +               #address-cells = <1>;
45 +               #size-cells = <1>;
46 +
47 +               pcie@12000 {
48 +                       reg = <0x00012000 0x1000>;
49 +                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
50 +               };
51 +
52 +               ethernet@24000 {
53 +                       reg = <0x00024000 0x1000>;
54 +                       interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
55 +               };
56 +
57 +               ethernet@25000 {
58 +                       reg = <0x00025000 0x1000>;
59 +                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
60 +               };
61 +       };
62 --- a/drivers/bcma/bcma_private.h
63 +++ b/drivers/bcma/bcma_private.h
64 @@ -88,6 +88,20 @@ extern int __init bcma_host_pci_init(voi
65  extern void __exit bcma_host_pci_exit(void);
66  #endif /* CONFIG_BCMA_HOST_PCI */
67  
68 +/* host_soc.c */
69 +#if defined(CONFIG_BCMA_HOST_SOC) && defined(CONFIG_OF)
70 +extern int __init bcma_host_soc_register_driver(void);
71 +extern void __exit bcma_host_soc_unregister_driver(void);
72 +#else
73 +static inline int __init bcma_host_soc_register_driver(void)
74 +{
75 +       return 0;
76 +}
77 +static inline void __exit bcma_host_soc_unregister_driver(void)
78 +{
79 +}
80 +#endif /* CONFIG_BCMA_HOST_SOC && CONFIG_OF */
81 +
82  /* driver_pci.c */
83  u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
84  
85 --- a/drivers/bcma/host_soc.c
86 +++ b/drivers/bcma/host_soc.c
87 @@ -7,6 +7,9 @@
88  
89  #include "bcma_private.h"
90  #include "scan.h"
91 +#include <linux/slab.h>
92 +#include <linux/module.h>
93 +#include <linux/of_address.h>
94  #include <linux/bcma/bcma.h>
95  #include <linux/bcma/bcma_soc.h>
96  
97 @@ -176,6 +179,7 @@ int __init bcma_host_soc_register(struct
98         /* Host specific */
99         bus->hosttype = BCMA_HOSTTYPE_SOC;
100         bus->ops = &bcma_host_soc_ops;
101 +       bus->host_pdev = NULL;
102  
103         /* Initialize struct, detect chip */
104         bcma_init_bus(bus);
105 @@ -195,3 +199,81 @@ int __init bcma_host_soc_init(struct bcm
106  
107         return err;
108  }
109 +
110 +#ifdef CONFIG_OF
111 +static int bcma_host_soc_probe(struct platform_device *pdev)
112 +{
113 +       struct device *dev = &pdev->dev;
114 +       struct device_node *np = dev->of_node;
115 +       struct bcma_bus *bus;
116 +       int err;
117 +
118 +       /* Alloc */
119 +       bus = devm_kzalloc(dev, sizeof(*bus), GFP_KERNEL);
120 +       if (!bus)
121 +               return -ENOMEM;
122 +
123 +       /* Map MMIO */
124 +       bus->mmio = of_iomap(np, 0);
125 +       if (!bus->mmio)
126 +               return -ENOMEM;
127 +
128 +       /* Host specific */
129 +       bus->hosttype = BCMA_HOSTTYPE_SOC;
130 +       bus->ops = &bcma_host_soc_ops;
131 +       bus->host_pdev = pdev;
132 +
133 +       /* Initialize struct, detect chip */
134 +       bcma_init_bus(bus);
135 +
136 +       /* Register */
137 +       err = bcma_bus_register(bus);
138 +       if (err)
139 +               goto err_unmap_mmio;
140 +
141 +       platform_set_drvdata(pdev, bus);
142 +
143 +       return err;
144 +
145 +err_unmap_mmio:
146 +       iounmap(bus->mmio);
147 +       return err;
148 +}
149 +
150 +static int bcma_host_soc_remove(struct platform_device *pdev)
151 +{
152 +       struct bcma_bus *bus = platform_get_drvdata(pdev);
153 +
154 +       bcma_bus_unregister(bus);
155 +       iounmap(bus->mmio);
156 +       platform_set_drvdata(pdev, NULL);
157 +
158 +       return 0;
159 +}
160 +
161 +static const struct of_device_id bcma_host_soc_of_match[] = {
162 +       { .compatible = "brcm,bus-axi", },
163 +       {},
164 +};
165 +MODULE_DEVICE_TABLE(of, bcma_host_soc_of_match);
166 +
167 +static struct platform_driver bcma_host_soc_driver = {
168 +       .driver = {
169 +               .name = "bcma-host-soc",
170 +               .owner = THIS_MODULE,
171 +               .of_match_table = bcma_host_soc_of_match,
172 +       },
173 +       .probe          = bcma_host_soc_probe,
174 +       .remove         = bcma_host_soc_remove,
175 +};
176 +
177 +int __init bcma_host_soc_register_driver(void)
178 +{
179 +       return platform_driver_register(&bcma_host_soc_driver);
180 +}
181 +
182 +void __exit bcma_host_soc_unregister_driver(void)
183 +{
184 +       platform_driver_unregister(&bcma_host_soc_driver);
185 +}
186 +#endif /* CONFIG_OF */
187 --- a/drivers/bcma/main.c
188 +++ b/drivers/bcma/main.c
189 @@ -528,6 +528,11 @@ static int __init bcma_modinit(void)
190         if (err)
191                 return err;
192  
193 +       err = bcma_host_soc_register_driver();
194 +       if (err) {
195 +               pr_err("SoC host initialization failed\n");
196 +               err = 0;
197 +       }
198  #ifdef CONFIG_BCMA_HOST_PCI
199         err = bcma_host_pci_init();
200         if (err) {
201 @@ -545,6 +550,7 @@ static void __exit bcma_modexit(void)
202  #ifdef CONFIG_BCMA_HOST_PCI
203         bcma_host_pci_exit();
204  #endif
205 +       bcma_host_soc_unregister_driver();
206         bus_unregister(&bcma_bus_type);
207  }
208  module_exit(bcma_modexit)
209 --- a/include/linux/bcma/bcma.h
210 +++ b/include/linux/bcma/bcma.h
211 @@ -323,6 +323,8 @@ struct bcma_bus {
212                 struct pci_dev *host_pci;
213                 /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
214                 struct sdio_func *host_sdio;
215 +               /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
216 +               struct platform_device *host_pdev;
217         };
218  
219         struct bcma_chipinfo chipinfo;