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