1 /* 2 * Broadcom specific AMBA 3 * Bus subsystem 4 * 5 * Licensed under the GNU/GPL. See COPYING for details. 6 */ 7 8 #include "bcma_private.h" 9 #include <linux/module.h> 10 #include <linux/bcma/bcma.h> 11 #include <linux/slab.h> 12 13 MODULE_DESCRIPTION("Broadcom's specific AMBA driver"); 14 MODULE_LICENSE("GPL"); 15 16 /* contains the number the next bus should get. */ 17 static unsigned int bcma_bus_next_num = 0; 18 19 /* bcma_buses_mutex locks the bcma_bus_next_num */ 20 static DEFINE_MUTEX(bcma_buses_mutex); 21 22 static int bcma_bus_match(struct device *dev, struct device_driver *drv); 23 static int bcma_device_probe(struct device *dev); 24 static int bcma_device_remove(struct device *dev); 25 static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env); 26 27 static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf) 28 { 29 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 30 return sprintf(buf, "0x%03X\n", core->id.manuf); 31 } 32 static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf) 33 { 34 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 35 return sprintf(buf, "0x%03X\n", core->id.id); 36 } 37 static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf) 38 { 39 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 40 return sprintf(buf, "0x%02X\n", core->id.rev); 41 } 42 static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf) 43 { 44 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 45 return sprintf(buf, "0x%X\n", core->id.class); 46 } 47 static struct device_attribute bcma_device_attrs[] = { 48 __ATTR_RO(manuf), 49 __ATTR_RO(id), 50 __ATTR_RO(rev), 51 __ATTR_RO(class), 52 __ATTR_NULL, 53 }; 54 55 static struct bus_type bcma_bus_type = { 56 .name = "bcma", 57 .match = bcma_bus_match, 58 .probe = bcma_device_probe, 59 .remove = bcma_device_remove, 60 .uevent = bcma_device_uevent, 61 .dev_attrs = bcma_device_attrs, 62 }; 63 64 struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) 65 { 66 struct bcma_device *core; 67 68 list_for_each_entry(core, &bus->cores, list) { 69 if (core->id.id == coreid) 70 return core; 71 } 72 return NULL; 73 } 74 EXPORT_SYMBOL_GPL(bcma_find_core); 75 76 static void bcma_release_core_dev(struct device *dev) 77 { 78 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 79 if (core->io_addr) 80 iounmap(core->io_addr); 81 if (core->io_wrap) 82 iounmap(core->io_wrap); 83 kfree(core); 84 } 85 86 static int bcma_register_cores(struct bcma_bus *bus) 87 { 88 struct bcma_device *core; 89 int err, dev_id = 0; 90 91 list_for_each_entry(core, &bus->cores, list) { 92 /* We support that cores ourself */ 93 switch (core->id.id) { 94 case BCMA_CORE_CHIPCOMMON: 95 case BCMA_CORE_PCI: 96 case BCMA_CORE_PCIE: 97 case BCMA_CORE_MIPS_74K: 98 continue; 99 } 100 101 core->dev.release = bcma_release_core_dev; 102 core->dev.bus = &bcma_bus_type; 103 dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id); 104 105 switch (bus->hosttype) { 106 case BCMA_HOSTTYPE_PCI: 107 core->dev.parent = &bus->host_pci->dev; 108 core->dma_dev = &bus->host_pci->dev; 109 core->irq = bus->host_pci->irq; 110 break; 111 case BCMA_HOSTTYPE_SOC: 112 core->dev.dma_mask = &core->dev.coherent_dma_mask; 113 core->dma_dev = &core->dev; 114 break; 115 case BCMA_HOSTTYPE_SDIO: 116 break; 117 } 118 119 err = device_register(&core->dev); 120 if (err) { 121 pr_err("Could not register dev for core 0x%03X\n", 122 core->id.id); 123 continue; 124 } 125 core->dev_registered = true; 126 dev_id++; 127 } 128 129 return 0; 130 } 131 132 static void bcma_unregister_cores(struct bcma_bus *bus) 133 { 134 struct bcma_device *core; 135 136 list_for_each_entry(core, &bus->cores, list) { 137 if (core->dev_registered) 138 device_unregister(&core->dev); 139 } 140 } 141 142 int __devinit bcma_bus_register(struct bcma_bus *bus) 143 { 144 int err; 145 struct bcma_device *core; 146 147 mutex_lock(&bcma_buses_mutex); 148 bus->num = bcma_bus_next_num++; 149 mutex_unlock(&bcma_buses_mutex); 150 151 /* Scan for devices (cores) */ 152 err = bcma_bus_scan(bus); 153 if (err) { 154 pr_err("Failed to scan: %d\n", err); 155 return -1; 156 } 157 158 /* Init CC core */ 159 core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); 160 if (core) { 161 bus->drv_cc.core = core; 162 bcma_core_chipcommon_init(&bus->drv_cc); 163 } 164 165 /* Init MIPS core */ 166 core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); 167 if (core) { 168 bus->drv_mips.core = core; 169 bcma_core_mips_init(&bus->drv_mips); 170 } 171 172 /* Init PCIE core */ 173 core = bcma_find_core(bus, BCMA_CORE_PCIE); 174 if (core) { 175 bus->drv_pci.core = core; 176 bcma_core_pci_init(&bus->drv_pci); 177 } 178 179 /* Try to get SPROM */ 180 err = bcma_sprom_get(bus); 181 if (err == -ENOENT) { 182 pr_err("No SPROM available\n"); 183 } else if (err) 184 pr_err("Failed to get SPROM: %d\n", err); 185 186 /* Register found cores */ 187 bcma_register_cores(bus); 188 189 pr_info("Bus registered\n"); 190 191 return 0; 192 } 193 194 void bcma_bus_unregister(struct bcma_bus *bus) 195 { 196 bcma_unregister_cores(bus); 197 } 198 199 int __init bcma_bus_early_register(struct bcma_bus *bus, 200 struct bcma_device *core_cc, 201 struct bcma_device *core_mips) 202 { 203 int err; 204 struct bcma_device *core; 205 struct bcma_device_id match; 206 207 bcma_init_bus(bus); 208 209 match.manuf = BCMA_MANUF_BCM; 210 match.id = BCMA_CORE_CHIPCOMMON; 211 match.class = BCMA_CL_SIM; 212 match.rev = BCMA_ANY_REV; 213 214 /* Scan for chip common core */ 215 err = bcma_bus_scan_early(bus, &match, core_cc); 216 if (err) { 217 pr_err("Failed to scan for common core: %d\n", err); 218 return -1; 219 } 220 221 match.manuf = BCMA_MANUF_MIPS; 222 match.id = BCMA_CORE_MIPS_74K; 223 match.class = BCMA_CL_SIM; 224 match.rev = BCMA_ANY_REV; 225 226 /* Scan for mips core */ 227 err = bcma_bus_scan_early(bus, &match, core_mips); 228 if (err) { 229 pr_err("Failed to scan for mips core: %d\n", err); 230 return -1; 231 } 232 233 /* Init CC core */ 234 core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); 235 if (core) { 236 bus->drv_cc.core = core; 237 bcma_core_chipcommon_init(&bus->drv_cc); 238 } 239 240 /* Init MIPS core */ 241 core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); 242 if (core) { 243 bus->drv_mips.core = core; 244 bcma_core_mips_init(&bus->drv_mips); 245 } 246 247 pr_info("Early bus registered\n"); 248 249 return 0; 250 } 251 252 #ifdef CONFIG_PM 253 int bcma_bus_suspend(struct bcma_bus *bus) 254 { 255 struct bcma_device *core; 256 257 list_for_each_entry(core, &bus->cores, list) { 258 struct device_driver *drv = core->dev.driver; 259 if (drv) { 260 struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv); 261 if (adrv->suspend) 262 adrv->suspend(core); 263 } 264 } 265 return 0; 266 } 267 268 int bcma_bus_resume(struct bcma_bus *bus) 269 { 270 struct bcma_device *core; 271 272 /* Init CC core */ 273 core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); 274 if (core) { 275 bus->drv_cc.setup_done = false; 276 bcma_core_chipcommon_init(&bus->drv_cc); 277 } 278 279 list_for_each_entry(core, &bus->cores, list) { 280 struct device_driver *drv = core->dev.driver; 281 if (drv) { 282 struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv); 283 if (adrv->resume) 284 adrv->resume(core); 285 } 286 } 287 288 return 0; 289 } 290 #endif 291 292 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) 293 { 294 drv->drv.name = drv->name; 295 drv->drv.bus = &bcma_bus_type; 296 drv->drv.owner = owner; 297 298 return driver_register(&drv->drv); 299 } 300 EXPORT_SYMBOL_GPL(__bcma_driver_register); 301 302 void bcma_driver_unregister(struct bcma_driver *drv) 303 { 304 driver_unregister(&drv->drv); 305 } 306 EXPORT_SYMBOL_GPL(bcma_driver_unregister); 307 308 static int bcma_bus_match(struct device *dev, struct device_driver *drv) 309 { 310 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 311 struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv); 312 const struct bcma_device_id *cid = &core->id; 313 const struct bcma_device_id *did; 314 315 for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) { 316 if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) && 317 (did->id == cid->id || did->id == BCMA_ANY_ID) && 318 (did->rev == cid->rev || did->rev == BCMA_ANY_REV) && 319 (did->class == cid->class || did->class == BCMA_ANY_CLASS)) 320 return 1; 321 } 322 return 0; 323 } 324 325 static int bcma_device_probe(struct device *dev) 326 { 327 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 328 struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver, 329 drv); 330 int err = 0; 331 332 if (adrv->probe) 333 err = adrv->probe(core); 334 335 return err; 336 } 337 338 static int bcma_device_remove(struct device *dev) 339 { 340 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 341 struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver, 342 drv); 343 344 if (adrv->remove) 345 adrv->remove(core); 346 347 return 0; 348 } 349 350 static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env) 351 { 352 struct bcma_device *core = container_of(dev, struct bcma_device, dev); 353 354 return add_uevent_var(env, 355 "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X", 356 core->id.manuf, core->id.id, 357 core->id.rev, core->id.class); 358 } 359 360 static int __init bcma_modinit(void) 361 { 362 int err; 363 364 err = bus_register(&bcma_bus_type); 365 if (err) 366 return err; 367 368 #ifdef CONFIG_BCMA_HOST_PCI 369 err = bcma_host_pci_init(); 370 if (err) { 371 pr_err("PCI host initialization failed\n"); 372 err = 0; 373 } 374 #endif 375 376 return err; 377 } 378 fs_initcall(bcma_modinit); 379 380 static void __exit bcma_modexit(void) 381 { 382 #ifdef CONFIG_BCMA_HOST_PCI 383 bcma_host_pci_exit(); 384 #endif 385 bus_unregister(&bcma_bus_type); 386 } 387 module_exit(bcma_modexit) 388