aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma
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
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')
-rw-r--r--drivers/bcma/bcma_private.h7
-rw-r--r--drivers/bcma/driver_chipcommon.c5
-rw-r--r--drivers/bcma/driver_pci.c5
-rw-r--r--drivers/bcma/main.c46
-rw-r--r--drivers/bcma/scan.c95
5 files changed, 152 insertions, 6 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index e02ff21835c..b97633d0d23 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -15,9 +15,16 @@ struct bcma_bus;
15/* main.c */ 15/* main.c */
16int bcma_bus_register(struct bcma_bus *bus); 16int bcma_bus_register(struct bcma_bus *bus);
17void bcma_bus_unregister(struct bcma_bus *bus); 17void bcma_bus_unregister(struct bcma_bus *bus);
18int __init bcma_bus_early_register(struct bcma_bus *bus,
19 struct bcma_device *core_cc,
20 struct bcma_device *core_mips);
18 21
19/* scan.c */ 22/* scan.c */
20int bcma_bus_scan(struct bcma_bus *bus); 23int bcma_bus_scan(struct bcma_bus *bus);
24int __init bcma_bus_scan_early(struct bcma_bus *bus,
25 struct bcma_device_id *match,
26 struct bcma_device *core);
27void bcma_init_bus(struct bcma_bus *bus);
21 28
22/* sprom.c */ 29/* sprom.c */
23int bcma_sprom_get(struct bcma_bus *bus); 30int bcma_sprom_get(struct bcma_bus *bus);
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 851e05bc948..acca327db3d 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
26 u32 leddc_on = 10; 26 u32 leddc_on = 10;
27 u32 leddc_off = 90; 27 u32 leddc_off = 90;
28 28
29 if (cc->setup_done)
30 return;
31
29 if (cc->core->id.rev >= 11) 32 if (cc->core->id.rev >= 11)
30 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); 33 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
31 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); 34 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
52 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | 55 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
53 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); 56 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
54 } 57 }
58
59 cc->setup_done = true;
55} 60}
56 61
57/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 62/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index 25f3ddf3382..4e082100fa9 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -189,6 +189,9 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
189 189
190void bcma_core_pci_init(struct bcma_drv_pci *pc) 190void bcma_core_pci_init(struct bcma_drv_pci *pc)
191{ 191{
192 if (pc->setup_done)
193 return;
194
192 if (bcma_core_pci_is_in_hostmode(pc)) { 195 if (bcma_core_pci_is_in_hostmode(pc)) {
193#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE 196#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
194 bcma_core_pci_hostmode_init(pc); 197 bcma_core_pci_hostmode_init(pc);
@@ -198,6 +201,8 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
198 } else { 201 } else {
199 bcma_core_pci_clientmode_init(pc); 202 bcma_core_pci_clientmode_init(pc);
200 } 203 }
204
205 pc->setup_done = true;
201} 206}
202 207
203int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, 208int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 873e2e4ac55..360a289738f 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -169,6 +169,52 @@ void bcma_bus_unregister(struct bcma_bus *bus)
169 bcma_unregister_cores(bus); 169 bcma_unregister_cores(bus);
170} 170}
171 171
172int __init bcma_bus_early_register(struct bcma_bus *bus,
173 struct bcma_device *core_cc,
174 struct bcma_device *core_mips)
175{
176 int err;
177 struct bcma_device *core;
178 struct bcma_device_id match;
179
180 bcma_init_bus(bus);
181
182 match.manuf = BCMA_MANUF_BCM;
183 match.id = BCMA_CORE_CHIPCOMMON;
184 match.class = BCMA_CL_SIM;
185 match.rev = BCMA_ANY_REV;
186
187 /* Scan for chip common core */
188 err = bcma_bus_scan_early(bus, &match, core_cc);
189 if (err) {
190 pr_err("Failed to scan for common core: %d\n", err);
191 return -1;
192 }
193
194 match.manuf = BCMA_MANUF_MIPS;
195 match.id = BCMA_CORE_MIPS_74K;
196 match.class = BCMA_CL_SIM;
197 match.rev = BCMA_ANY_REV;
198
199 /* Scan for mips core */
200 err = bcma_bus_scan_early(bus, &match, core_mips);
201 if (err) {
202 pr_err("Failed to scan for mips core: %d\n", err);
203 return -1;
204 }
205
206 /* Init CC core */
207 core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
208 if (core) {
209 bus->drv_cc.core = core;
210 bcma_core_chipcommon_init(&bus->drv_cc);
211 }
212
213 pr_info("Early bus registered\n");
214
215 return 0;
216}
217
172int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) 218int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
173{ 219{
174 drv->drv.name = drv->name; 220 drv->drv.name = drv->name;
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 79705534217..bf9f8065277 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}