aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--include/linux/bcma/bcma.h1
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h1
7 files changed, 154 insertions, 6 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index e02ff21835c9..b97633d0d237 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 851e05bc948a..acca327db3de 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 25f3ddf33823..4e082100fa9b 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 873e2e4ac55f..360a289738fc 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 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}
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 8c96654bef16..e31c9b462221 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -190,6 +190,7 @@ struct bcma_bus {
190 struct bcma_device *mapped_core; 190 struct bcma_device *mapped_core;
191 struct list_head cores; 191 struct list_head cores;
192 u8 nr_cores; 192 u8 nr_cores;
193 u8 init_done:1;
193 194
194 struct bcma_drv_cc drv_cc; 195 struct bcma_drv_cc drv_cc;
195 struct bcma_drv_pci drv_pci; 196 struct bcma_drv_pci drv_pci;
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index a0f684615ae5..c8b4cf7f9fae 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -252,6 +252,7 @@ struct bcma_drv_cc {
252 u32 status; 252 u32 status;
253 u32 capabilities; 253 u32 capabilities;
254 u32 capabilities_ext; 254 u32 capabilities_ext;
255 u8 setup_done:1;
255 /* Fast Powerup Delay constant */ 256 /* Fast Powerup Delay constant */
256 u16 fast_pwrup_delay; 257 u16 fast_pwrup_delay;
257 struct bcma_chipcommon_pmu pmu; 258 struct bcma_chipcommon_pmu pmu;