aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/ebus.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-22 22:12:03 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:28 -0400
commit690c8fd31f1e35985d0f35772fde514da59ec9d1 (patch)
tree8a5a0036b3780a9eb315ea2201a2562570de1ebe /arch/sparc64/kernel/ebus.c
parentde8d28b16f5614aeb12bb69c8f9a38578b8d3ada (diff)
[SPARC64]: Use in-kernel PROM tree for EBUS and ISA.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/ebus.c')
-rw-r--r--arch/sparc64/kernel/ebus.c141
1 files changed, 75 insertions, 66 deletions
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 3125a5b49775..919a91d9e5de 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -285,36 +285,38 @@ static inline void *ebus_alloc(size_t size)
285 285
286static void __init ebus_ranges_init(struct linux_ebus *ebus) 286static void __init ebus_ranges_init(struct linux_ebus *ebus)
287{ 287{
288 int success; 288 struct linux_prom_ebus_ranges *rngs;
289 int len;
289 290
290 ebus->num_ebus_ranges = 0; 291 ebus->num_ebus_ranges = 0;
291 success = prom_getproperty(ebus->prom_node, "ranges", 292 rngs = of_get_property(ebus->prom_node, "ranges", &len);
292 (char *)ebus->ebus_ranges, 293 if (rngs) {
293 sizeof(ebus->ebus_ranges)); 294 memcpy(ebus->ebus_ranges, rngs, len);
294 if (success != -1) 295 ebus->num_ebus_ranges =
295 ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges)); 296 (len / sizeof(struct linux_prom_ebus_ranges));
297 }
296} 298}
297 299
298static void __init ebus_intmap_init(struct linux_ebus *ebus) 300static void __init ebus_intmap_init(struct linux_ebus *ebus)
299{ 301{
300 int success; 302 struct linux_prom_ebus_intmap *imap;
303 struct linux_prom_ebus_intmask *imask;
304 int len;
301 305
302 ebus->num_ebus_intmap = 0; 306 ebus->num_ebus_intmap = 0;
303 success = prom_getproperty(ebus->prom_node, "interrupt-map", 307 imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
304 (char *)ebus->ebus_intmap, 308 if (!imap)
305 sizeof(ebus->ebus_intmap));
306 if (success == -1)
307 return; 309 return;
308 310
309 ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap)); 311 memcpy(ebus->ebus_intmap, imap, len);
312 ebus->num_ebus_intmap = (len / sizeof(struct linux_prom_ebus_intmap));
310 313
311 success = prom_getproperty(ebus->prom_node, "interrupt-map-mask", 314 imask = of_get_property(ebus->prom_node, "interrupt-map-mask", &len);
312 (char *)&ebus->ebus_intmask, 315 if (!imask) {
313 sizeof(ebus->ebus_intmask)); 316 prom_printf("EBUS: can't get interrupt-map-mask\n");
314 if (success == -1) {
315 prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
316 prom_halt(); 317 prom_halt();
317 } 318 }
319 memcpy(&ebus->ebus_intmask, imask, sizeof(ebus->ebus_intmask));
318} 320}
319 321
320int __init ebus_intmap_match(struct linux_ebus *ebus, 322int __init ebus_intmap_match(struct linux_ebus *ebus,
@@ -341,19 +343,23 @@ int __init ebus_intmap_match(struct linux_ebus *ebus,
341 return -1; 343 return -1;
342} 344}
343 345
344void __init fill_ebus_child(int node, struct linux_prom_registers *preg, 346void __init fill_ebus_child(struct device_node *dp,
345 struct linux_ebus_child *dev, int non_standard_regs) 347 struct linux_prom_registers *preg,
348 struct linux_ebus_child *dev,
349 int non_standard_regs)
346{ 350{
347 int regs[PROMREG_MAX]; 351 int *regs;
348 int irqs[PROMREG_MAX]; 352 int *irqs;
349 int i, len; 353 int i, len;
350 354
351 dev->prom_node = node; 355 dev->prom_node = dp;
352 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); 356 printk(" (%s)", dp->name);
353 printk(" (%s)", dev->prom_name);
354 357
355 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 358 regs = of_get_property(dp, "reg", &len);
356 dev->num_addrs = len / sizeof(regs[0]); 359 if (!regs)
360 dev->num_addrs = 0;
361 else
362 dev->num_addrs = len / sizeof(regs[0]);
357 363
358 if (non_standard_regs) { 364 if (non_standard_regs) {
359 /* This is to handle reg properties which are not 365 /* This is to handle reg properties which are not
@@ -370,21 +376,21 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
370 int rnum = regs[i]; 376 int rnum = regs[i];
371 if (rnum >= dev->parent->num_addrs) { 377 if (rnum >= dev->parent->num_addrs) {
372 prom_printf("UGH: property for %s was %d, need < %d\n", 378 prom_printf("UGH: property for %s was %d, need < %d\n",
373 dev->prom_name, len, dev->parent->num_addrs); 379 dp->name, len, dev->parent->num_addrs);
374 panic(__FUNCTION__); 380 prom_halt();
375 } 381 }
376 dev->resource[i].start = dev->parent->resource[i].start; 382 dev->resource[i].start = dev->parent->resource[i].start;
377 dev->resource[i].end = dev->parent->resource[i].end; 383 dev->resource[i].end = dev->parent->resource[i].end;
378 dev->resource[i].flags = IORESOURCE_MEM; 384 dev->resource[i].flags = IORESOURCE_MEM;
379 dev->resource[i].name = dev->prom_name; 385 dev->resource[i].name = dp->name;
380 } 386 }
381 } 387 }
382 388
383 for (i = 0; i < PROMINTR_MAX; i++) 389 for (i = 0; i < PROMINTR_MAX; i++)
384 dev->irqs[i] = PCI_IRQ_NONE; 390 dev->irqs[i] = PCI_IRQ_NONE;
385 391
386 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 392 irqs = of_get_property(dp, "interrupts", &len);
387 if ((len == -1) || (len == 0)) { 393 if (!irqs) {
388 dev->num_irqs = 0; 394 dev->num_irqs = 0;
389 /* 395 /*
390 * Oh, well, some PROMs don't export interrupts 396 * Oh, well, some PROMs don't export interrupts
@@ -392,8 +398,8 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
392 * 398 *
393 * Be smart about PS/2 keyboard and mouse. 399 * Be smart about PS/2 keyboard and mouse.
394 */ 400 */
395 if (!strcmp(dev->parent->prom_name, "8042")) { 401 if (!strcmp(dev->parent->prom_node->name, "8042")) {
396 if (!strcmp(dev->prom_name, "kb_ps2")) { 402 if (!strcmp(dev->prom_node->name, "kb_ps2")) {
397 dev->num_irqs = 1; 403 dev->num_irqs = 1;
398 dev->irqs[0] = dev->parent->irqs[0]; 404 dev->irqs[0] = dev->parent->irqs[0];
399 } else { 405 } else {
@@ -423,32 +429,32 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
423 429
424static int __init child_regs_nonstandard(struct linux_ebus_device *dev) 430static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
425{ 431{
426 if (!strcmp(dev->prom_name, "i2c") || 432 if (!strcmp(dev->prom_node->name, "i2c") ||
427 !strcmp(dev->prom_name, "SUNW,lombus")) 433 !strcmp(dev->prom_node->name, "SUNW,lombus"))
428 return 1; 434 return 1;
429 return 0; 435 return 0;
430} 436}
431 437
432void __init fill_ebus_device(int node, struct linux_ebus_device *dev) 438void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
433{ 439{
434 struct linux_prom_registers regs[PROMREG_MAX]; 440 struct linux_prom_registers *regs;
435 struct linux_ebus_child *child; 441 struct linux_ebus_child *child;
436 int irqs[PROMINTR_MAX]; 442 int *irqs;
437 int i, n, len; 443 int i, n, len;
438 444
439 dev->prom_node = node; 445 dev->prom_node = dp;
440 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
441 printk(" [%s", dev->prom_name);
442 446
443 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 447 printk(" [%s", dp->name);
444 if (len == -1) { 448
449 regs = of_get_property(dp, "reg", &len);
450 if (!regs) {
445 dev->num_addrs = 0; 451 dev->num_addrs = 0;
446 goto probe_interrupts; 452 goto probe_interrupts;
447 } 453 }
448 454
449 if (len % sizeof(struct linux_prom_registers)) { 455 if (len % sizeof(struct linux_prom_registers)) {
450 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", 456 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
451 dev->prom_name, len, 457 dev->prom_node->name, len,
452 (int)sizeof(struct linux_prom_registers)); 458 (int)sizeof(struct linux_prom_registers));
453 prom_halt(); 459 prom_halt();
454 } 460 }
@@ -466,7 +472,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
466 dev->resource[i].end = 472 dev->resource[i].end =
467 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL); 473 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
468 dev->resource[i].flags = IORESOURCE_MEM; 474 dev->resource[i].flags = IORESOURCE_MEM;
469 dev->resource[i].name = dev->prom_name; 475 dev->resource[i].name = dev->prom_node->name;
470 request_resource(&dev->bus->self->resource[n], 476 request_resource(&dev->bus->self->resource[n],
471 &dev->resource[i]); 477 &dev->resource[i]);
472 } 478 }
@@ -475,8 +481,8 @@ probe_interrupts:
475 for (i = 0; i < PROMINTR_MAX; i++) 481 for (i = 0; i < PROMINTR_MAX; i++)
476 dev->irqs[i] = PCI_IRQ_NONE; 482 dev->irqs[i] = PCI_IRQ_NONE;
477 483
478 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 484 irqs = of_get_property(dp, "interrupts", &len);
479 if ((len == -1) || (len == 0)) { 485 if (!irqs) {
480 dev->num_irqs = 0; 486 dev->num_irqs = 0;
481 } else { 487 } else {
482 dev->num_irqs = len / sizeof(irqs[0]); 488 dev->num_irqs = len / sizeof(irqs[0]);
@@ -497,7 +503,8 @@ probe_interrupts:
497 } 503 }
498 } 504 }
499 505
500 if ((node = prom_getchild(node))) { 506 dp = dp->child;
507 if (dp) {
501 printk(" ->"); 508 printk(" ->");
502 dev->children = ebus_alloc(sizeof(struct linux_ebus_child)); 509 dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
503 510
@@ -505,18 +512,18 @@ probe_interrupts:
505 child->next = NULL; 512 child->next = NULL;
506 child->parent = dev; 513 child->parent = dev;
507 child->bus = dev->bus; 514 child->bus = dev->bus;
508 fill_ebus_child(node, &regs[0], 515 fill_ebus_child(dp, regs, child,
509 child, child_regs_nonstandard(dev)); 516 child_regs_nonstandard(dev));
510 517
511 while ((node = prom_getsibling(node)) != 0) { 518 while ((dp = dp->sibling) != NULL) {
512 child->next = ebus_alloc(sizeof(struct linux_ebus_child)); 519 child->next = ebus_alloc(sizeof(struct linux_ebus_child));
513 520
514 child = child->next; 521 child = child->next;
515 child->next = NULL; 522 child->next = NULL;
516 child->parent = dev; 523 child->parent = dev;
517 child->bus = dev->bus; 524 child->bus = dev->bus;
518 fill_ebus_child(node, &regs[0], 525 fill_ebus_child(dp, regs, child,
519 child, child_regs_nonstandard(dev)); 526 child_regs_nonstandard(dev));
520 } 527 }
521 } 528 }
522 printk("]"); 529 printk("]");
@@ -543,7 +550,8 @@ void __init ebus_init(void)
543 struct linux_ebus *ebus; 550 struct linux_ebus *ebus;
544 struct pci_dev *pdev; 551 struct pci_dev *pdev;
545 struct pcidev_cookie *cookie; 552 struct pcidev_cookie *cookie;
546 int nd, ebusnd, is_rio; 553 struct device_node *dp;
554 int is_rio;
547 int num_ebus = 0; 555 int num_ebus = 0;
548 556
549 pdev = find_next_ebus(NULL, &is_rio); 557 pdev = find_next_ebus(NULL, &is_rio);
@@ -553,20 +561,22 @@ void __init ebus_init(void)
553 } 561 }
554 562
555 cookie = pdev->sysdata; 563 cookie = pdev->sysdata;
556 ebusnd = cookie->prom_node->node; 564 dp = cookie->prom_node;
557 565
558 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); 566 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
559 ebus->next = NULL; 567 ebus->next = NULL;
560 ebus->is_rio = is_rio; 568 ebus->is_rio = is_rio;
561 569
562 while (ebusnd) { 570 while (dp) {
571 struct device_node *child;
572
563 /* SUNW,pci-qfe uses four empty ebuses on it. 573 /* SUNW,pci-qfe uses four empty ebuses on it.
564 I think we should not consider them here, 574 I think we should not consider them here,
565 as they have half of the properties this 575 as they have half of the properties this
566 code expects and once we do PCI hot-plug, 576 code expects and once we do PCI hot-plug,
567 we'd have to tweak with the ebus_chain 577 we'd have to tweak with the ebus_chain
568 in the runtime after initialization. -jj */ 578 in the runtime after initialization. -jj */
569 if (!prom_getchild (ebusnd)) { 579 if (!dp->child) {
570 pdev = find_next_ebus(pdev, &is_rio); 580 pdev = find_next_ebus(pdev, &is_rio);
571 if (!pdev) { 581 if (!pdev) {
572 if (ebus == ebus_chain) { 582 if (ebus == ebus_chain) {
@@ -578,22 +588,21 @@ void __init ebus_init(void)
578 } 588 }
579 ebus->is_rio = is_rio; 589 ebus->is_rio = is_rio;
580 cookie = pdev->sysdata; 590 cookie = pdev->sysdata;
581 ebusnd = cookie->prom_node->node; 591 dp = cookie->prom_node;
582 continue; 592 continue;
583 } 593 }
584 printk("ebus%d:", num_ebus); 594 printk("ebus%d:", num_ebus);
585 595
586 prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
587 ebus->index = num_ebus; 596 ebus->index = num_ebus;
588 ebus->prom_node = ebusnd; 597 ebus->prom_node = dp;
589 ebus->self = pdev; 598 ebus->self = pdev;
590 ebus->parent = pbm = cookie->pbm; 599 ebus->parent = pbm = cookie->pbm;
591 600
592 ebus_ranges_init(ebus); 601 ebus_ranges_init(ebus);
593 ebus_intmap_init(ebus); 602 ebus_intmap_init(ebus);
594 603
595 nd = prom_getchild(ebusnd); 604 child = dp->child;
596 if (!nd) 605 if (!child)
597 goto next_ebus; 606 goto next_ebus;
598 607
599 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); 608 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
@@ -602,16 +611,16 @@ void __init ebus_init(void)
602 dev->next = NULL; 611 dev->next = NULL;
603 dev->children = NULL; 612 dev->children = NULL;
604 dev->bus = ebus; 613 dev->bus = ebus;
605 fill_ebus_device(nd, dev); 614 fill_ebus_device(child, dev);
606 615
607 while ((nd = prom_getsibling(nd)) != 0) { 616 while ((child = child->sibling) != NULL) {
608 dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); 617 dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
609 618
610 dev = dev->next; 619 dev = dev->next;
611 dev->next = NULL; 620 dev->next = NULL;
612 dev->children = NULL; 621 dev->children = NULL;
613 dev->bus = ebus; 622 dev->bus = ebus;
614 fill_ebus_device(nd, dev); 623 fill_ebus_device(child, dev);
615 } 624 }
616 625
617 next_ebus: 626 next_ebus:
@@ -622,7 +631,7 @@ void __init ebus_init(void)
622 break; 631 break;
623 632
624 cookie = pdev->sysdata; 633 cookie = pdev->sysdata;
625 ebusnd = cookie->prom_node->node; 634 dp = cookie->prom_node;
626 635
627 ebus->next = ebus_alloc(sizeof(struct linux_ebus)); 636 ebus->next = ebus_alloc(sizeof(struct linux_ebus));
628 ebus = ebus->next; 637 ebus = ebus->next;