xref: /openbmc/linux/drivers/bcma/main.c (revision 3d9d8af3)
18369ae33SRafał Miłecki /*
28369ae33SRafał Miłecki  * Broadcom specific AMBA
38369ae33SRafał Miłecki  * Bus subsystem
48369ae33SRafał Miłecki  *
58369ae33SRafał Miłecki  * Licensed under the GNU/GPL. See COPYING for details.
68369ae33SRafał Miłecki  */
78369ae33SRafał Miłecki 
88369ae33SRafał Miłecki #include "bcma_private.h"
9200351c7SPaul Gortmaker #include <linux/module.h>
108369ae33SRafał Miłecki #include <linux/bcma/bcma.h>
11eef72699SGeert Uytterhoeven #include <linux/slab.h>
128369ae33SRafał Miłecki 
138369ae33SRafał Miłecki MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
148369ae33SRafał Miłecki MODULE_LICENSE("GPL");
158369ae33SRafał Miłecki 
168f9ada4fSHauke Mehrtens /* contains the number the next bus should get. */
178f9ada4fSHauke Mehrtens static unsigned int bcma_bus_next_num = 0;
188f9ada4fSHauke Mehrtens 
198f9ada4fSHauke Mehrtens /* bcma_buses_mutex locks the bcma_bus_next_num */
208f9ada4fSHauke Mehrtens static DEFINE_MUTEX(bcma_buses_mutex);
218f9ada4fSHauke Mehrtens 
228369ae33SRafał Miłecki static int bcma_bus_match(struct device *dev, struct device_driver *drv);
238369ae33SRafał Miłecki static int bcma_device_probe(struct device *dev);
248369ae33SRafał Miłecki static int bcma_device_remove(struct device *dev);
25886b66efSDavid Woodhouse static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
268369ae33SRafał Miłecki 
278369ae33SRafał Miłecki static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
288369ae33SRafał Miłecki {
298369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
308369ae33SRafał Miłecki 	return sprintf(buf, "0x%03X\n", core->id.manuf);
318369ae33SRafał Miłecki }
328369ae33SRafał Miłecki static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
338369ae33SRafał Miłecki {
348369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
358369ae33SRafał Miłecki 	return sprintf(buf, "0x%03X\n", core->id.id);
368369ae33SRafał Miłecki }
378369ae33SRafał Miłecki static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
388369ae33SRafał Miłecki {
398369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
408369ae33SRafał Miłecki 	return sprintf(buf, "0x%02X\n", core->id.rev);
418369ae33SRafał Miłecki }
428369ae33SRafał Miłecki static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
438369ae33SRafał Miłecki {
448369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
458369ae33SRafał Miłecki 	return sprintf(buf, "0x%X\n", core->id.class);
468369ae33SRafał Miłecki }
478369ae33SRafał Miłecki static struct device_attribute bcma_device_attrs[] = {
488369ae33SRafał Miłecki 	__ATTR_RO(manuf),
498369ae33SRafał Miłecki 	__ATTR_RO(id),
508369ae33SRafał Miłecki 	__ATTR_RO(rev),
518369ae33SRafał Miłecki 	__ATTR_RO(class),
528369ae33SRafał Miłecki 	__ATTR_NULL,
538369ae33SRafał Miłecki };
548369ae33SRafał Miłecki 
558369ae33SRafał Miłecki static struct bus_type bcma_bus_type = {
568369ae33SRafał Miłecki 	.name		= "bcma",
578369ae33SRafał Miłecki 	.match		= bcma_bus_match,
588369ae33SRafał Miłecki 	.probe		= bcma_device_probe,
598369ae33SRafał Miłecki 	.remove		= bcma_device_remove,
60886b66efSDavid Woodhouse 	.uevent		= bcma_device_uevent,
618369ae33SRafał Miłecki 	.dev_attrs	= bcma_device_attrs,
628369ae33SRafał Miłecki };
638369ae33SRafał Miłecki 
641c9351cfSHauke Mehrtens struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
658369ae33SRafał Miłecki {
668369ae33SRafał Miłecki 	struct bcma_device *core;
678369ae33SRafał Miłecki 
688369ae33SRafał Miłecki 	list_for_each_entry(core, &bus->cores, list) {
698369ae33SRafał Miłecki 		if (core->id.id == coreid)
708369ae33SRafał Miłecki 			return core;
718369ae33SRafał Miłecki 	}
728369ae33SRafał Miłecki 	return NULL;
738369ae33SRafał Miłecki }
741c9351cfSHauke Mehrtens EXPORT_SYMBOL_GPL(bcma_find_core);
758369ae33SRafał Miłecki 
768369ae33SRafał Miłecki static void bcma_release_core_dev(struct device *dev)
778369ae33SRafał Miłecki {
788369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
79ecd177c2SHauke Mehrtens 	if (core->io_addr)
80ecd177c2SHauke Mehrtens 		iounmap(core->io_addr);
81ecd177c2SHauke Mehrtens 	if (core->io_wrap)
82ecd177c2SHauke Mehrtens 		iounmap(core->io_wrap);
838369ae33SRafał Miłecki 	kfree(core);
848369ae33SRafał Miłecki }
858369ae33SRafał Miłecki 
868369ae33SRafał Miłecki static int bcma_register_cores(struct bcma_bus *bus)
878369ae33SRafał Miłecki {
888369ae33SRafał Miłecki 	struct bcma_device *core;
898369ae33SRafał Miłecki 	int err, dev_id = 0;
908369ae33SRafał Miłecki 
918369ae33SRafał Miłecki 	list_for_each_entry(core, &bus->cores, list) {
928369ae33SRafał Miłecki 		/* We support that cores ourself */
938369ae33SRafał Miłecki 		switch (core->id.id) {
948369ae33SRafał Miłecki 		case BCMA_CORE_CHIPCOMMON:
958369ae33SRafał Miłecki 		case BCMA_CORE_PCI:
968369ae33SRafał Miłecki 		case BCMA_CORE_PCIE:
9721e0534aSHauke Mehrtens 		case BCMA_CORE_MIPS_74K:
988369ae33SRafał Miłecki 			continue;
998369ae33SRafał Miłecki 		}
1008369ae33SRafał Miłecki 
1018369ae33SRafał Miłecki 		core->dev.release = bcma_release_core_dev;
1028369ae33SRafał Miłecki 		core->dev.bus = &bcma_bus_type;
1038f9ada4fSHauke Mehrtens 		dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
1048369ae33SRafał Miłecki 
1058369ae33SRafał Miłecki 		switch (bus->hosttype) {
1068369ae33SRafał Miłecki 		case BCMA_HOSTTYPE_PCI:
1078369ae33SRafał Miłecki 			core->dev.parent = &bus->host_pci->dev;
1081bdcd095SRafał Miłecki 			core->dma_dev = &bus->host_pci->dev;
1091bdcd095SRafał Miłecki 			core->irq = bus->host_pci->irq;
1108369ae33SRafał Miłecki 			break;
111ecd177c2SHauke Mehrtens 		case BCMA_HOSTTYPE_SOC:
112ecd177c2SHauke Mehrtens 			core->dev.dma_mask = &core->dev.coherent_dma_mask;
113ecd177c2SHauke Mehrtens 			core->dma_dev = &core->dev;
114ecd177c2SHauke Mehrtens 			break;
1158369ae33SRafał Miłecki 		case BCMA_HOSTTYPE_SDIO:
1168369ae33SRafał Miłecki 			break;
1178369ae33SRafał Miłecki 		}
1188369ae33SRafał Miłecki 
1198369ae33SRafał Miłecki 		err = device_register(&core->dev);
1208369ae33SRafał Miłecki 		if (err) {
1213d9d8af3SRafał Miłecki 			bcma_err(bus,
1223d9d8af3SRafał Miłecki 				 "Could not register dev for core 0x%03X\n",
1238369ae33SRafał Miłecki 				 core->id.id);
1248369ae33SRafał Miłecki 			continue;
1258369ae33SRafał Miłecki 		}
1268369ae33SRafał Miłecki 		core->dev_registered = true;
1278369ae33SRafał Miłecki 		dev_id++;
1288369ae33SRafał Miłecki 	}
1298369ae33SRafał Miłecki 
1308369ae33SRafał Miłecki 	return 0;
1318369ae33SRafał Miłecki }
1328369ae33SRafał Miłecki 
1338369ae33SRafał Miłecki static void bcma_unregister_cores(struct bcma_bus *bus)
1348369ae33SRafał Miłecki {
1358369ae33SRafał Miłecki 	struct bcma_device *core;
1368369ae33SRafał Miłecki 
1378369ae33SRafał Miłecki 	list_for_each_entry(core, &bus->cores, list) {
1388369ae33SRafał Miłecki 		if (core->dev_registered)
1398369ae33SRafał Miłecki 			device_unregister(&core->dev);
1408369ae33SRafał Miłecki 	}
1418369ae33SRafał Miłecki }
1428369ae33SRafał Miłecki 
143d1a7a8e1SHauke Mehrtens int __devinit bcma_bus_register(struct bcma_bus *bus)
1448369ae33SRafał Miłecki {
1458369ae33SRafał Miłecki 	int err;
1468369ae33SRafał Miłecki 	struct bcma_device *core;
1478369ae33SRafał Miłecki 
1488f9ada4fSHauke Mehrtens 	mutex_lock(&bcma_buses_mutex);
1498f9ada4fSHauke Mehrtens 	bus->num = bcma_bus_next_num++;
1508f9ada4fSHauke Mehrtens 	mutex_unlock(&bcma_buses_mutex);
1518f9ada4fSHauke Mehrtens 
1528369ae33SRafał Miłecki 	/* Scan for devices (cores) */
1538369ae33SRafał Miłecki 	err = bcma_bus_scan(bus);
1548369ae33SRafał Miłecki 	if (err) {
1553d9d8af3SRafał Miłecki 		bcma_err(bus, "Failed to scan: %d\n", err);
1568369ae33SRafał Miłecki 		return -1;
1578369ae33SRafał Miłecki 	}
1588369ae33SRafał Miłecki 
1598369ae33SRafał Miłecki 	/* Init CC core */
1608369ae33SRafał Miłecki 	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1618369ae33SRafał Miłecki 	if (core) {
1628369ae33SRafał Miłecki 		bus->drv_cc.core = core;
1638369ae33SRafał Miłecki 		bcma_core_chipcommon_init(&bus->drv_cc);
1648369ae33SRafał Miłecki 	}
1658369ae33SRafał Miłecki 
16621e0534aSHauke Mehrtens 	/* Init MIPS core */
16721e0534aSHauke Mehrtens 	core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
16821e0534aSHauke Mehrtens 	if (core) {
16921e0534aSHauke Mehrtens 		bus->drv_mips.core = core;
17021e0534aSHauke Mehrtens 		bcma_core_mips_init(&bus->drv_mips);
17121e0534aSHauke Mehrtens 	}
17221e0534aSHauke Mehrtens 
1738369ae33SRafał Miłecki 	/* Init PCIE core */
1748369ae33SRafał Miłecki 	core = bcma_find_core(bus, BCMA_CORE_PCIE);
1758369ae33SRafał Miłecki 	if (core) {
1768369ae33SRafał Miłecki 		bus->drv_pci.core = core;
1778369ae33SRafał Miłecki 		bcma_core_pci_init(&bus->drv_pci);
1788369ae33SRafał Miłecki 	}
1798369ae33SRafał Miłecki 
18027f18dc2SRafał Miłecki 	/* Try to get SPROM */
18127f18dc2SRafał Miłecki 	err = bcma_sprom_get(bus);
182534e7a45SHauke Mehrtens 	if (err == -ENOENT) {
1833d9d8af3SRafał Miłecki 		bcma_err(bus, "No SPROM available\n");
1842e6b4119SHenrik Rydberg 	} else if (err)
1853d9d8af3SRafał Miłecki 		bcma_err(bus, "Failed to get SPROM: %d\n", err);
18627f18dc2SRafał Miłecki 
1878369ae33SRafał Miłecki 	/* Register found cores */
1888369ae33SRafał Miłecki 	bcma_register_cores(bus);
1898369ae33SRafał Miłecki 
1903d9d8af3SRafał Miłecki 	bcma_info(bus, "Bus registered\n");
1918369ae33SRafał Miłecki 
1928369ae33SRafał Miłecki 	return 0;
1938369ae33SRafał Miłecki }
1948369ae33SRafał Miłecki 
1958369ae33SRafał Miłecki void bcma_bus_unregister(struct bcma_bus *bus)
1968369ae33SRafał Miłecki {
1978369ae33SRafał Miłecki 	bcma_unregister_cores(bus);
1988369ae33SRafał Miłecki }
1998369ae33SRafał Miłecki 
200517f43e5SHauke Mehrtens int __init bcma_bus_early_register(struct bcma_bus *bus,
201517f43e5SHauke Mehrtens 				   struct bcma_device *core_cc,
202517f43e5SHauke Mehrtens 				   struct bcma_device *core_mips)
203517f43e5SHauke Mehrtens {
204517f43e5SHauke Mehrtens 	int err;
205517f43e5SHauke Mehrtens 	struct bcma_device *core;
206517f43e5SHauke Mehrtens 	struct bcma_device_id match;
207517f43e5SHauke Mehrtens 
208517f43e5SHauke Mehrtens 	bcma_init_bus(bus);
209517f43e5SHauke Mehrtens 
210517f43e5SHauke Mehrtens 	match.manuf = BCMA_MANUF_BCM;
211517f43e5SHauke Mehrtens 	match.id = BCMA_CORE_CHIPCOMMON;
212517f43e5SHauke Mehrtens 	match.class = BCMA_CL_SIM;
213517f43e5SHauke Mehrtens 	match.rev = BCMA_ANY_REV;
214517f43e5SHauke Mehrtens 
215517f43e5SHauke Mehrtens 	/* Scan for chip common core */
216517f43e5SHauke Mehrtens 	err = bcma_bus_scan_early(bus, &match, core_cc);
217517f43e5SHauke Mehrtens 	if (err) {
2183d9d8af3SRafał Miłecki 		bcma_err(bus, "Failed to scan for common core: %d\n", err);
219517f43e5SHauke Mehrtens 		return -1;
220517f43e5SHauke Mehrtens 	}
221517f43e5SHauke Mehrtens 
222517f43e5SHauke Mehrtens 	match.manuf = BCMA_MANUF_MIPS;
223517f43e5SHauke Mehrtens 	match.id = BCMA_CORE_MIPS_74K;
224517f43e5SHauke Mehrtens 	match.class = BCMA_CL_SIM;
225517f43e5SHauke Mehrtens 	match.rev = BCMA_ANY_REV;
226517f43e5SHauke Mehrtens 
227517f43e5SHauke Mehrtens 	/* Scan for mips core */
228517f43e5SHauke Mehrtens 	err = bcma_bus_scan_early(bus, &match, core_mips);
229517f43e5SHauke Mehrtens 	if (err) {
2303d9d8af3SRafał Miłecki 		bcma_err(bus, "Failed to scan for mips core: %d\n", err);
231517f43e5SHauke Mehrtens 		return -1;
232517f43e5SHauke Mehrtens 	}
233517f43e5SHauke Mehrtens 
234517f43e5SHauke Mehrtens 	/* Init CC core */
235517f43e5SHauke Mehrtens 	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
236517f43e5SHauke Mehrtens 	if (core) {
237517f43e5SHauke Mehrtens 		bus->drv_cc.core = core;
238517f43e5SHauke Mehrtens 		bcma_core_chipcommon_init(&bus->drv_cc);
239517f43e5SHauke Mehrtens 	}
240517f43e5SHauke Mehrtens 
24121e0534aSHauke Mehrtens 	/* Init MIPS core */
24221e0534aSHauke Mehrtens 	core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
24321e0534aSHauke Mehrtens 	if (core) {
24421e0534aSHauke Mehrtens 		bus->drv_mips.core = core;
24521e0534aSHauke Mehrtens 		bcma_core_mips_init(&bus->drv_mips);
24621e0534aSHauke Mehrtens 	}
24721e0534aSHauke Mehrtens 
2483d9d8af3SRafał Miłecki 	bcma_info(bus, "Early bus registered\n");
249517f43e5SHauke Mehrtens 
250517f43e5SHauke Mehrtens 	return 0;
251517f43e5SHauke Mehrtens }
252517f43e5SHauke Mehrtens 
253775ab521SRafał Miłecki #ifdef CONFIG_PM
254685a4ef0SLinus Torvalds int bcma_bus_suspend(struct bcma_bus *bus)
255685a4ef0SLinus Torvalds {
2567d5869e7SLinus Torvalds 	struct bcma_device *core;
2577d5869e7SLinus Torvalds 
2587d5869e7SLinus Torvalds 	list_for_each_entry(core, &bus->cores, list) {
2597d5869e7SLinus Torvalds 		struct device_driver *drv = core->dev.driver;
2607d5869e7SLinus Torvalds 		if (drv) {
2617d5869e7SLinus Torvalds 			struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2627d5869e7SLinus Torvalds 			if (adrv->suspend)
2637d5869e7SLinus Torvalds 				adrv->suspend(core);
2647d5869e7SLinus Torvalds 		}
2657d5869e7SLinus Torvalds 	}
266685a4ef0SLinus Torvalds 	return 0;
267685a4ef0SLinus Torvalds }
268685a4ef0SLinus Torvalds 
269775ab521SRafał Miłecki int bcma_bus_resume(struct bcma_bus *bus)
270775ab521SRafał Miłecki {
271775ab521SRafał Miłecki 	struct bcma_device *core;
272775ab521SRafał Miłecki 
273775ab521SRafał Miłecki 	/* Init CC core */
274775ab521SRafał Miłecki 	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
275775ab521SRafał Miłecki 	if (core) {
276775ab521SRafał Miłecki 		bus->drv_cc.setup_done = false;
277775ab521SRafał Miłecki 		bcma_core_chipcommon_init(&bus->drv_cc);
278775ab521SRafał Miłecki 	}
279775ab521SRafał Miłecki 
2807d5869e7SLinus Torvalds 	list_for_each_entry(core, &bus->cores, list) {
2817d5869e7SLinus Torvalds 		struct device_driver *drv = core->dev.driver;
2827d5869e7SLinus Torvalds 		if (drv) {
2837d5869e7SLinus Torvalds 			struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2847d5869e7SLinus Torvalds 			if (adrv->resume)
2857d5869e7SLinus Torvalds 				adrv->resume(core);
2867d5869e7SLinus Torvalds 		}
2877d5869e7SLinus Torvalds 	}
2887d5869e7SLinus Torvalds 
289775ab521SRafał Miłecki 	return 0;
290775ab521SRafał Miłecki }
291775ab521SRafał Miłecki #endif
292775ab521SRafał Miłecki 
2938369ae33SRafał Miłecki int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
2948369ae33SRafał Miłecki {
2958369ae33SRafał Miłecki 	drv->drv.name = drv->name;
2968369ae33SRafał Miłecki 	drv->drv.bus = &bcma_bus_type;
2978369ae33SRafał Miłecki 	drv->drv.owner = owner;
2988369ae33SRafał Miłecki 
2998369ae33SRafał Miłecki 	return driver_register(&drv->drv);
3008369ae33SRafał Miłecki }
3018369ae33SRafał Miłecki EXPORT_SYMBOL_GPL(__bcma_driver_register);
3028369ae33SRafał Miłecki 
3038369ae33SRafał Miłecki void bcma_driver_unregister(struct bcma_driver *drv)
3048369ae33SRafał Miłecki {
3058369ae33SRafał Miłecki 	driver_unregister(&drv->drv);
3068369ae33SRafał Miłecki }
3078369ae33SRafał Miłecki EXPORT_SYMBOL_GPL(bcma_driver_unregister);
3088369ae33SRafał Miłecki 
3098369ae33SRafał Miłecki static int bcma_bus_match(struct device *dev, struct device_driver *drv)
3108369ae33SRafał Miłecki {
3118369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
3128369ae33SRafał Miłecki 	struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
3138369ae33SRafał Miłecki 	const struct bcma_device_id *cid = &core->id;
3148369ae33SRafał Miłecki 	const struct bcma_device_id *did;
3158369ae33SRafał Miłecki 
3168369ae33SRafał Miłecki 	for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
3178369ae33SRafał Miłecki 	    if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
3188369ae33SRafał Miłecki 		(did->id == cid->id || did->id == BCMA_ANY_ID) &&
3198369ae33SRafał Miłecki 		(did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
3208369ae33SRafał Miłecki 		(did->class == cid->class || did->class == BCMA_ANY_CLASS))
3218369ae33SRafał Miłecki 			return 1;
3228369ae33SRafał Miłecki 	}
3238369ae33SRafał Miłecki 	return 0;
3248369ae33SRafał Miłecki }
3258369ae33SRafał Miłecki 
3268369ae33SRafał Miłecki static int bcma_device_probe(struct device *dev)
3278369ae33SRafał Miłecki {
3288369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
3298369ae33SRafał Miłecki 	struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
3308369ae33SRafał Miłecki 					       drv);
3318369ae33SRafał Miłecki 	int err = 0;
3328369ae33SRafał Miłecki 
3338369ae33SRafał Miłecki 	if (adrv->probe)
3348369ae33SRafał Miłecki 		err = adrv->probe(core);
3358369ae33SRafał Miłecki 
3368369ae33SRafał Miłecki 	return err;
3378369ae33SRafał Miłecki }
3388369ae33SRafał Miłecki 
3398369ae33SRafał Miłecki static int bcma_device_remove(struct device *dev)
3408369ae33SRafał Miłecki {
3418369ae33SRafał Miłecki 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
3428369ae33SRafał Miłecki 	struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
3438369ae33SRafał Miłecki 					       drv);
3448369ae33SRafał Miłecki 
3458369ae33SRafał Miłecki 	if (adrv->remove)
3468369ae33SRafał Miłecki 		adrv->remove(core);
3478369ae33SRafał Miłecki 
3488369ae33SRafał Miłecki 	return 0;
3498369ae33SRafał Miłecki }
3508369ae33SRafał Miłecki 
351886b66efSDavid Woodhouse static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
352886b66efSDavid Woodhouse {
353886b66efSDavid Woodhouse 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
354886b66efSDavid Woodhouse 
355886b66efSDavid Woodhouse 	return add_uevent_var(env,
356886b66efSDavid Woodhouse 			      "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
357886b66efSDavid Woodhouse 			      core->id.manuf, core->id.id,
358886b66efSDavid Woodhouse 			      core->id.rev, core->id.class);
359886b66efSDavid Woodhouse }
360886b66efSDavid Woodhouse 
3618369ae33SRafał Miłecki static int __init bcma_modinit(void)
3628369ae33SRafał Miłecki {
3638369ae33SRafał Miłecki 	int err;
3648369ae33SRafał Miłecki 
3658369ae33SRafał Miłecki 	err = bus_register(&bcma_bus_type);
3668369ae33SRafał Miłecki 	if (err)
3678369ae33SRafał Miłecki 		return err;
3688369ae33SRafał Miłecki 
3698369ae33SRafał Miłecki #ifdef CONFIG_BCMA_HOST_PCI
3708369ae33SRafał Miłecki 	err = bcma_host_pci_init();
3718369ae33SRafał Miłecki 	if (err) {
3728369ae33SRafał Miłecki 		pr_err("PCI host initialization failed\n");
3738369ae33SRafał Miłecki 		err = 0;
3748369ae33SRafał Miłecki 	}
3758369ae33SRafał Miłecki #endif
3768369ae33SRafał Miłecki 
3778369ae33SRafał Miłecki 	return err;
3788369ae33SRafał Miłecki }
3798369ae33SRafał Miłecki fs_initcall(bcma_modinit);
3808369ae33SRafał Miłecki 
3818369ae33SRafał Miłecki static void __exit bcma_modexit(void)
3828369ae33SRafał Miłecki {
3838369ae33SRafał Miłecki #ifdef CONFIG_BCMA_HOST_PCI
3848369ae33SRafał Miłecki 	bcma_host_pci_exit();
3858369ae33SRafał Miłecki #endif
3868369ae33SRafał Miłecki 	bus_unregister(&bcma_bus_type);
3878369ae33SRafał Miłecki }
3888369ae33SRafał Miłecki module_exit(bcma_modexit)
389