diff options
-rw-r--r-- | drivers/bcma/bcma_private.h | 7 | ||||
-rw-r--r-- | drivers/bcma/driver_chipcommon.c | 5 | ||||
-rw-r--r-- | drivers/bcma/driver_pci.c | 5 | ||||
-rw-r--r-- | drivers/bcma/main.c | 46 | ||||
-rw-r--r-- | drivers/bcma/scan.c | 95 | ||||
-rw-r--r-- | include/linux/bcma/bcma.h | 1 | ||||
-rw-r--r-- | include/linux/bcma/bcma_driver_chipcommon.h | 1 |
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 */ |
16 | int bcma_bus_register(struct bcma_bus *bus); | 16 | int bcma_bus_register(struct bcma_bus *bus); |
17 | void bcma_bus_unregister(struct bcma_bus *bus); | 17 | void bcma_bus_unregister(struct bcma_bus *bus); |
18 | int __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 */ |
20 | int bcma_bus_scan(struct bcma_bus *bus); | 23 | int bcma_bus_scan(struct bcma_bus *bus); |
24 | int __init bcma_bus_scan_early(struct bcma_bus *bus, | ||
25 | struct bcma_device_id *match, | ||
26 | struct bcma_device *core); | ||
27 | void bcma_init_bus(struct bcma_bus *bus); | ||
21 | 28 | ||
22 | /* sprom.c */ | 29 | /* sprom.c */ |
23 | int bcma_sprom_get(struct bcma_bus *bus); | 30 | int 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 | ||
190 | void bcma_core_pci_init(struct bcma_drv_pci *pc) | 190 | void 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 | ||
203 | int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, | 208 | int 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 | ||
172 | int __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 | |||
172 | int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) | 218 | int __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 | ||
203 | static 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 | |||
203 | static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, | 215 | static 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 | ||
315 | static void bcma_init_bus(struct bcma_bus *bus) | 343 | void 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 | ||
330 | int bcma_bus_scan(struct bcma_bus *bus) | 362 | int 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 | |||
410 | int __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; |