aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma/scan.c
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2011-07-22 19:20:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-08 14:29:24 -0400
commit517f43e5a922d51ac960424de4f72676fe6a7390 (patch)
tree02920911d43c4e480ac0eba21c15587776b16d6b /drivers/bcma/scan.c
parent67a5c29e1623edda5ff3f0355af533e72a245ad9 (diff)
bcma: add functions to scan cores needed on SoCs
The chip common and mips core have to be setup early in the boot process to get the cpu clock. bcma_bus_early_register() gets pointers to some space to store the core data and searches for the chip common and mips core and initializes chip common. After that was done and the kernel is out of early boot we just have to run bcma_bus_register() and it will search for the other cores, initialize and register them. The cores are getting the same numbers as before. Acked-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/bcma/scan.c')
-rw-r--r--drivers/bcma/scan.c95
1 files changed, 89 insertions, 6 deletions
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 79705534217e..bf9f80652773 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -200,7 +200,20 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
200 return addrl; 200 return addrl;
201} 201}
202 202
203static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
204 u16 index)
205{
206 struct bcma_device *core;
207
208 list_for_each_entry(core, &bus->cores, list) {
209 if (core->core_index == index)
210 return core;
211 }
212 return NULL;
213}
214
203static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, 215static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
216 struct bcma_device_id *match, int core_num,
204 struct bcma_device *core) 217 struct bcma_device *core)
205{ 218{
206 s32 tmp; 219 s32 tmp;
@@ -251,6 +264,21 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
251 return -ENXIO; 264 return -ENXIO;
252 } 265 }
253 266
267 if (bcma_find_core_by_index(bus, core_num)) {
268 bcma_erom_skip_component(bus, eromptr);
269 return -ENODEV;
270 }
271
272 if (match && ((match->manuf != BCMA_ANY_MANUF &&
273 match->manuf != core->id.manuf) ||
274 (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
275 (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
276 (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
277 )) {
278 bcma_erom_skip_component(bus, eromptr);
279 return -ENODEV;
280 }
281
254 /* get & parse master ports */ 282 /* get & parse master ports */
255 for (i = 0; i < ports[0]; i++) { 283 for (i = 0; i < ports[0]; i++) {
256 u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr); 284 u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
@@ -312,10 +340,13 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
312 return 0; 340 return 0;
313} 341}
314 342
315static void bcma_init_bus(struct bcma_bus *bus) 343void bcma_init_bus(struct bcma_bus *bus)
316{ 344{
317 s32 tmp; 345 s32 tmp;
318 346
347 if (bus->init_done)
348 return;
349
319 INIT_LIST_HEAD(&bus->cores); 350 INIT_LIST_HEAD(&bus->cores);
320 bus->nr_cores = 0; 351 bus->nr_cores = 0;
321 352
@@ -325,6 +356,7 @@ static void bcma_init_bus(struct bcma_bus *bus)
325 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT; 356 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
326 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT; 357 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
327 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT; 358 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
359 bus->init_done = true;
328} 360}
329 361
330int bcma_bus_scan(struct bcma_bus *bus) 362int bcma_bus_scan(struct bcma_bus *bus)
@@ -332,7 +364,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
332 u32 erombase; 364 u32 erombase;
333 u32 __iomem *eromptr, *eromend; 365 u32 __iomem *eromptr, *eromend;
334 366
335 int err; 367 int err, core_num = 0;
336 368
337 bcma_init_bus(bus); 369 bcma_init_bus(bus);
338 370
@@ -349,23 +381,74 @@ int bcma_bus_scan(struct bcma_bus *bus)
349 INIT_LIST_HEAD(&core->list); 381 INIT_LIST_HEAD(&core->list);
350 core->bus = bus; 382 core->bus = bus;
351 383
352 err = bcma_get_next_core(bus, &eromptr, core); 384 err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
353 if (err == -ENXIO) 385 if (err == -ENODEV) {
386 core_num++;
387 continue;
388 } else if (err == -ENXIO)
354 continue; 389 continue;
355 else if (err == -ESPIPE) 390 else if (err == -ESPIPE)
356 break; 391 break;
357 else if (err < 0) 392 else if (err < 0)
358 return err; 393 return err;
359 394
395 core->core_index = core_num++;
396 bus->nr_cores++;
397
360 pr_info("Core %d found: %s " 398 pr_info("Core %d found: %s "
361 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", 399 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
362 bus->nr_cores, bcma_device_name(&core->id), 400 core->core_index, bcma_device_name(&core->id),
363 core->id.manuf, core->id.id, core->id.rev, 401 core->id.manuf, core->id.id, core->id.rev,
364 core->id.class); 402 core->id.class);
365 403
366 core->core_index = bus->nr_cores++;
367 list_add(&core->list, &bus->cores); 404 list_add(&core->list, &bus->cores);
368 } 405 }
369 406
370 return 0; 407 return 0;
371} 408}
409
410int __init bcma_bus_scan_early(struct bcma_bus *bus,
411 struct bcma_device_id *match,
412 struct bcma_device *core)
413{
414 u32 erombase;
415 u32 __iomem *eromptr, *eromend;
416
417 int err, core_num = 0;
418
419 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
420 eromptr = bus->mmio;
421 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
422
423 bcma_scan_switch_core(bus, erombase);
424
425 while (eromptr < eromend) {
426 memset(core, 0, sizeof(*core));
427 INIT_LIST_HEAD(&core->list);
428 core->bus = bus;
429
430 err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
431 if (err == -ENODEV) {
432 core_num++;
433 continue;
434 } else if (err == -ENXIO)
435 continue;
436 else if (err == -ESPIPE)
437 break;
438 else if (err < 0)
439 return err;
440
441 core->core_index = core_num++;
442 bus->nr_cores++;
443 pr_info("Core %d found: %s "
444 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
445 core->core_index, bcma_device_name(&core->id),
446 core->id.manuf, core->id.id, core->id.rev,
447 core->id.class);
448
449 list_add(&core->list, &bus->cores);
450 return 0;
451 }
452
453 return -ENODEV;
454}