aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2011-07-22 19:20:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-08 14:29:23 -0400
commit982eee67dd703a37edc3532b85e3a4122b5eb90b (patch)
tree8544e6ecffad0607d6b9c3721f9dac86d474a9e8 /drivers/bcma
parent581c9c4f7113fbb4d28d58ab6b2125e16ce62812 (diff)
bcma: move parsing of EEPROM into own function.
Move the parsing of the EEPROM data in scan function for one core into an own function. Now we are able to use it in some other scan function as well. 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/scan.c230
1 files changed, 118 insertions, 112 deletions
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 40d7dcce8933..4012d8d93e91 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -200,16 +200,124 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
200 return addrl; 200 return addrl;
201} 201}
202 202
203static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
204 struct bcma_device *core)
205{
206 s32 tmp;
207 u8 i, j;
208 s32 cia, cib;
209 u8 ports[2], wrappers[2];
210
211 /* get CIs */
212 cia = bcma_erom_get_ci(bus, eromptr);
213 if (cia < 0) {
214 bcma_erom_push_ent(eromptr);
215 if (bcma_erom_is_end(bus, eromptr))
216 return -ESPIPE;
217 return -EILSEQ;
218 }
219 cib = bcma_erom_get_ci(bus, eromptr);
220 if (cib < 0)
221 return -EILSEQ;
222
223 /* parse CIs */
224 core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
225 core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
226 core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
227 ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
228 ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
229 wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
230 wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
231 core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
232
233 if (((core->id.manuf == BCMA_MANUF_ARM) &&
234 (core->id.id == 0xFFF)) ||
235 (ports[1] == 0)) {
236 bcma_erom_skip_component(bus, eromptr);
237 return -ENXIO;
238 }
239
240 /* check if component is a core at all */
241 if (wrappers[0] + wrappers[1] == 0) {
242 /* we could save addrl of the router
243 if (cid == BCMA_CORE_OOB_ROUTER)
244 */
245 bcma_erom_skip_component(bus, eromptr);
246 return -ENXIO;
247 }
248
249 if (bcma_erom_is_bridge(bus, eromptr)) {
250 bcma_erom_skip_component(bus, eromptr);
251 return -ENXIO;
252 }
253
254 /* get & parse master ports */
255 for (i = 0; i < ports[0]; i++) {
256 u32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
257 if (mst_port_d < 0)
258 return -EILSEQ;
259 }
260
261 /* get & parse slave ports */
262 for (i = 0; i < ports[1]; i++) {
263 for (j = 0; ; j++) {
264 tmp = bcma_erom_get_addr_desc(bus, eromptr,
265 SCAN_ADDR_TYPE_SLAVE, i);
266 if (tmp < 0) {
267 /* no more entries for port _i_ */
268 /* pr_debug("erom: slave port %d "
269 * "has %d descriptors\n", i, j); */
270 break;
271 } else {
272 if (i == 0 && j == 0)
273 core->addr = tmp;
274 }
275 }
276 }
277
278 /* get & parse master wrappers */
279 for (i = 0; i < wrappers[0]; i++) {
280 for (j = 0; ; j++) {
281 tmp = bcma_erom_get_addr_desc(bus, eromptr,
282 SCAN_ADDR_TYPE_MWRAP, i);
283 if (tmp < 0) {
284 /* no more entries for port _i_ */
285 /* pr_debug("erom: master wrapper %d "
286 * "has %d descriptors\n", i, j); */
287 break;
288 } else {
289 if (i == 0 && j == 0)
290 core->wrap = tmp;
291 }
292 }
293 }
294
295 /* get & parse slave wrappers */
296 for (i = 0; i < wrappers[1]; i++) {
297 u8 hack = (ports[1] == 1) ? 0 : 1;
298 for (j = 0; ; j++) {
299 tmp = bcma_erom_get_addr_desc(bus, eromptr,
300 SCAN_ADDR_TYPE_SWRAP, i + hack);
301 if (tmp < 0) {
302 /* no more entries for port _i_ */
303 /* pr_debug("erom: master wrapper %d "
304 * has %d descriptors\n", i, j); */
305 break;
306 } else {
307 if (wrappers[0] == 0 && !i && !j)
308 core->wrap = tmp;
309 }
310 }
311 }
312 return 0;
313}
314
203int bcma_bus_scan(struct bcma_bus *bus) 315int bcma_bus_scan(struct bcma_bus *bus)
204{ 316{
205 u32 erombase; 317 u32 erombase;
206 u32 __iomem *eromptr, *eromend; 318 u32 __iomem *eromptr, *eromend;
207 319
208 s32 cia, cib;
209 u8 ports[2], wrappers[2];
210
211 s32 tmp; 320 s32 tmp;
212 u8 i, j;
213 321
214 int err; 322 int err;
215 323
@@ -236,112 +344,13 @@ int bcma_bus_scan(struct bcma_bus *bus)
236 INIT_LIST_HEAD(&core->list); 344 INIT_LIST_HEAD(&core->list);
237 core->bus = bus; 345 core->bus = bus;
238 346
239 /* get CIs */ 347 err = bcma_get_next_core(bus, &eromptr, core);
240 cia = bcma_erom_get_ci(bus, &eromptr); 348 if (err == -ENXIO)
241 if (cia < 0) {
242 bcma_erom_push_ent(&eromptr);
243 if (bcma_erom_is_end(bus, &eromptr))
244 break;
245 err= -EILSEQ;
246 goto out;
247 }
248 cib = bcma_erom_get_ci(bus, &eromptr);
249 if (cib < 0) {
250 err= -EILSEQ;
251 goto out;
252 }
253
254 /* parse CIs */
255 core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
256 core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
257 core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
258 ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
259 ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
260 wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
261 wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
262 core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
263
264 if (((core->id.manuf == BCMA_MANUF_ARM) &&
265 (core->id.id == 0xFFF)) ||
266 (ports[1] == 0)) {
267 bcma_erom_skip_component(bus, &eromptr);
268 continue;
269 }
270
271 /* check if component is a core at all */
272 if (wrappers[0] + wrappers[1] == 0) {
273 /* we could save addrl of the router
274 if (cid == BCMA_CORE_OOB_ROUTER)
275 */
276 bcma_erom_skip_component(bus, &eromptr);
277 continue;
278 }
279
280 if (bcma_erom_is_bridge(bus, &eromptr)) {
281 bcma_erom_skip_component(bus, &eromptr);
282 continue; 349 continue;
283 } 350 else if (err == -ESPIPE)
284 351 break;
285 /* get & parse master ports */ 352 else if (err < 0)
286 for (i = 0; i < ports[0]; i++) { 353 return err;
287 u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
288 if (mst_port_d < 0) {
289 err= -EILSEQ;
290 goto out;
291 }
292 }
293
294 /* get & parse slave ports */
295 for (i = 0; i < ports[1]; i++) {
296 for (j = 0; ; j++) {
297 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
298 SCAN_ADDR_TYPE_SLAVE, i);
299 if (tmp < 0) {
300 /* no more entries for port _i_ */
301 /* pr_debug("erom: slave port %d "
302 * "has %d descriptors\n", i, j); */
303 break;
304 } else {
305 if (i == 0 && j == 0)
306 core->addr = tmp;
307 }
308 }
309 }
310
311 /* get & parse master wrappers */
312 for (i = 0; i < wrappers[0]; i++) {
313 for (j = 0; ; j++) {
314 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
315 SCAN_ADDR_TYPE_MWRAP, i);
316 if (tmp < 0) {
317 /* no more entries for port _i_ */
318 /* pr_debug("erom: master wrapper %d "
319 * "has %d descriptors\n", i, j); */
320 break;
321 } else {
322 if (i == 0 && j == 0)
323 core->wrap = tmp;
324 }
325 }
326 }
327
328 /* get & parse slave wrappers */
329 for (i = 0; i < wrappers[1]; i++) {
330 u8 hack = (ports[1] == 1) ? 0 : 1;
331 for (j = 0; ; j++) {
332 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
333 SCAN_ADDR_TYPE_SWRAP, i + hack);
334 if (tmp < 0) {
335 /* no more entries for port _i_ */
336 /* pr_debug("erom: master wrapper %d "
337 * has %d descriptors\n", i, j); */
338 break;
339 } else {
340 if (wrappers[0] == 0 && !i && !j)
341 core->wrap = tmp;
342 }
343 }
344 }
345 354
346 pr_info("Core %d found: %s " 355 pr_info("Core %d found: %s "
347 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", 356 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
@@ -351,9 +360,6 @@ int bcma_bus_scan(struct bcma_bus *bus)
351 360
352 core->core_index = bus->nr_cores++; 361 core->core_index = bus->nr_cores++;
353 list_add(&core->list, &bus->cores); 362 list_add(&core->list, &bus->cores);
354 continue;
355out:
356 return err;
357 } 363 }
358 364
359 return 0; 365 return 0;