aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2014-09-25 18:09:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-30 13:17:14 -0400
commit2101e533f41a90b25bee17ce969734e26eb0eb55 (patch)
tree359f7ca110591aa3805bd628d4d4da5440c774ed
parent7e174833dec99ca901241730efa84029c4047bae (diff)
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> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--Documentation/devicetree/bindings/bus/bcma.txt20
-rw-r--r--drivers/bcma/bcma_private.h14
-rw-r--r--drivers/bcma/host_soc.c81
-rw-r--r--drivers/bcma/main.c52
-rw-r--r--include/linux/bcma/bcma.h2
5 files changed, 168 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/bus/bcma.txt b/Documentation/devicetree/bindings/bus/bcma.txt
new file mode 100644
index 000000000000..e9070c161172
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/bcma.txt
@@ -0,0 +1,20 @@
1Driver for ARM AXI Bus with Broadcom Plugins (bcma)
2
3Required properties:
4
5- compatible : brcm,bus-axi
6
7- reg : iomem address range of chipcommon core
8
9The cores on the AXI bus are automatically detected by bcma with the
10memory ranges they are using and they get registered afterwards.
11
12Example:
13
14 axi@18000000 {
15 compatible = "brcm,bus-axi";
16 reg = <0x18000000 0x1000>;
17 ranges = <0x00000000 0x18000000 0x00100000>;
18 #address-cells = <1>;
19 #size-cells = <1>;
20 };
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index b40be43c6f31..b6412b2d748d 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -88,6 +88,20 @@ extern int __init bcma_host_pci_init(void);
88extern void __exit bcma_host_pci_exit(void); 88extern void __exit bcma_host_pci_exit(void);
89#endif /* CONFIG_BCMA_HOST_PCI */ 89#endif /* CONFIG_BCMA_HOST_PCI */
90 90
91/* host_soc.c */
92#if defined(CONFIG_BCMA_HOST_SOC) && defined(CONFIG_OF)
93extern int __init bcma_host_soc_register_driver(void);
94extern void __exit bcma_host_soc_unregister_driver(void);
95#else
96static inline int __init bcma_host_soc_register_driver(void)
97{
98 return 0;
99}
100static inline void __exit bcma_host_soc_unregister_driver(void)
101{
102}
103#endif /* CONFIG_BCMA_HOST_SOC && CONFIG_OF */
104
91/* driver_pci.c */ 105/* driver_pci.c */
92u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); 106u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
93 107
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
index 718e054dd727..335cbcfd945b 100644
--- a/drivers/bcma/host_soc.c
+++ b/drivers/bcma/host_soc.c
@@ -7,6 +7,9 @@
7 7
8#include "bcma_private.h" 8#include "bcma_private.h"
9#include "scan.h" 9#include "scan.h"
10#include <linux/slab.h>
11#include <linux/module.h>
12#include <linux/of_address.h>
10#include <linux/bcma/bcma.h> 13#include <linux/bcma/bcma.h>
11#include <linux/bcma/bcma_soc.h> 14#include <linux/bcma/bcma_soc.h>
12 15
@@ -176,6 +179,7 @@ int __init bcma_host_soc_register(struct bcma_soc *soc)
176 /* Host specific */ 179 /* Host specific */
177 bus->hosttype = BCMA_HOSTTYPE_SOC; 180 bus->hosttype = BCMA_HOSTTYPE_SOC;
178 bus->ops = &bcma_host_soc_ops; 181 bus->ops = &bcma_host_soc_ops;
182 bus->host_pdev = NULL;
179 183
180 /* Initialize struct, detect chip */ 184 /* Initialize struct, detect chip */
181 bcma_init_bus(bus); 185 bcma_init_bus(bus);
@@ -195,3 +199,80 @@ int __init bcma_host_soc_init(struct bcma_soc *soc)
195 199
196 return err; 200 return err;
197} 201}
202
203#ifdef CONFIG_OF
204static int bcma_host_soc_probe(struct platform_device *pdev)
205{
206 struct device *dev = &pdev->dev;
207 struct device_node *np = dev->of_node;
208 struct bcma_bus *bus;
209 int err;
210
211 /* Alloc */
212 bus = devm_kzalloc(dev, sizeof(*bus), GFP_KERNEL);
213 if (!bus)
214 return -ENOMEM;
215
216 /* Map MMIO */
217 bus->mmio = of_iomap(np, 0);
218 if (!bus->mmio)
219 return -ENOMEM;
220
221 /* Host specific */
222 bus->hosttype = BCMA_HOSTTYPE_SOC;
223 bus->ops = &bcma_host_soc_ops;
224 bus->host_pdev = pdev;
225
226 /* Initialize struct, detect chip */
227 bcma_init_bus(bus);
228
229 /* Register */
230 err = bcma_bus_register(bus);
231 if (err)
232 goto err_unmap_mmio;
233
234 platform_set_drvdata(pdev, bus);
235
236 return err;
237
238err_unmap_mmio:
239 iounmap(bus->mmio);
240 return err;
241}
242
243static int bcma_host_soc_remove(struct platform_device *pdev)
244{
245 struct bcma_bus *bus = platform_get_drvdata(pdev);
246
247 bcma_bus_unregister(bus);
248 iounmap(bus->mmio);
249 platform_set_drvdata(pdev, NULL);
250
251 return 0;
252}
253
254static const struct of_device_id bcma_host_soc_of_match[] = {
255 { .compatible = "brcm,bus-axi", },
256 {},
257};
258MODULE_DEVICE_TABLE(of, bcma_host_soc_of_match);
259
260static struct platform_driver bcma_host_soc_driver = {
261 .driver = {
262 .name = "bcma-host-soc",
263 .of_match_table = bcma_host_soc_of_match,
264 },
265 .probe = bcma_host_soc_probe,
266 .remove = bcma_host_soc_remove,
267};
268
269int __init bcma_host_soc_register_driver(void)
270{
271 return platform_driver_register(&bcma_host_soc_driver);
272}
273
274void __exit bcma_host_soc_unregister_driver(void)
275{
276 platform_driver_unregister(&bcma_host_soc_driver);
277}
278#endif /* CONFIG_OF */
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index c421403cab43..d1656c2f70af 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -10,6 +10,7 @@
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <linux/bcma/bcma.h> 11#include <linux/bcma/bcma.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/of_address.h>
13 14
14MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); 15MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
15MODULE_LICENSE("GPL"); 16MODULE_LICENSE("GPL");
@@ -131,6 +132,43 @@ static bool bcma_is_core_needed_early(u16 core_id)
131 return false; 132 return false;
132} 133}
133 134
135#ifdef CONFIG_OF
136static struct device_node *bcma_of_find_child_device(struct platform_device *parent,
137 struct bcma_device *core)
138{
139 struct device_node *node;
140 u64 size;
141 const __be32 *reg;
142
143 if (!parent || !parent->dev.of_node)
144 return NULL;
145
146 for_each_child_of_node(parent->dev.of_node, node) {
147 reg = of_get_address(node, 0, &size, NULL);
148 if (!reg)
149 continue;
150 if (of_translate_address(node, reg) == core->addr)
151 return node;
152 }
153 return NULL;
154}
155
156static void bcma_of_fill_device(struct platform_device *parent,
157 struct bcma_device *core)
158{
159 struct device_node *node;
160
161 node = bcma_of_find_child_device(parent, core);
162 if (node)
163 core->dev.of_node = node;
164}
165#else
166static void bcma_of_fill_device(struct platform_device *parent,
167 struct bcma_device *core)
168{
169}
170#endif /* CONFIG_OF */
171
134static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) 172static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
135{ 173{
136 int err; 174 int err;
@@ -147,7 +185,13 @@ static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
147 break; 185 break;
148 case BCMA_HOSTTYPE_SOC: 186 case BCMA_HOSTTYPE_SOC:
149 core->dev.dma_mask = &core->dev.coherent_dma_mask; 187 core->dev.dma_mask = &core->dev.coherent_dma_mask;
150 core->dma_dev = &core->dev; 188 if (bus->host_pdev) {
189 core->dma_dev = &bus->host_pdev->dev;
190 core->dev.parent = &bus->host_pdev->dev;
191 bcma_of_fill_device(bus->host_pdev, core);
192 } else {
193 core->dma_dev = &core->dev;
194 }
151 break; 195 break;
152 case BCMA_HOSTTYPE_SDIO: 196 case BCMA_HOSTTYPE_SDIO:
153 break; 197 break;
@@ -528,6 +572,11 @@ static int __init bcma_modinit(void)
528 if (err) 572 if (err)
529 return err; 573 return err;
530 574
575 err = bcma_host_soc_register_driver();
576 if (err) {
577 pr_err("SoC host initialization failed\n");
578 err = 0;
579 }
531#ifdef CONFIG_BCMA_HOST_PCI 580#ifdef CONFIG_BCMA_HOST_PCI
532 err = bcma_host_pci_init(); 581 err = bcma_host_pci_init();
533 if (err) { 582 if (err) {
@@ -545,6 +594,7 @@ static void __exit bcma_modexit(void)
545#ifdef CONFIG_BCMA_HOST_PCI 594#ifdef CONFIG_BCMA_HOST_PCI
546 bcma_host_pci_exit(); 595 bcma_host_pci_exit();
547#endif 596#endif
597 bcma_host_soc_unregister_driver();
548 bus_unregister(&bcma_bus_type); 598 bus_unregister(&bcma_bus_type);
549} 599}
550module_exit(bcma_modexit) 600module_exit(bcma_modexit)
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 634597917670..729f48e6b20b 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -323,6 +323,8 @@ struct bcma_bus {
323 struct pci_dev *host_pci; 323 struct pci_dev *host_pci;
324 /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */ 324 /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
325 struct sdio_func *host_sdio; 325 struct sdio_func *host_sdio;
326 /* Pointer to platform device (only for BCMA_HOSTTYPE_SOC) */
327 struct platform_device *host_pdev;
326 }; 328 };
327 329
328 struct bcma_chipinfo chipinfo; 330 struct bcma_chipinfo chipinfo;