diff options
| author | David S. Miller <davem@sunset.davemloft.net> | 2006-07-18 00:39:09 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-07-21 17:18:11 -0400 |
| commit | 9d7ab1f4d56dffcddc1177b3cd55b6da6620e1e1 (patch) | |
| tree | a551efc605c7b4d10af4df101470c17308b7822e | |
| parent | 67e23a1e60b6bc0a090407d0fc060166ab558b72 (diff) | |
[SPARC]: Fix initialization of sun4d SBUS interrupts.
1) Explicitly traverse to the root looking for the "sbi".
2) Grab the "board#" property from the sbi's parent and
verify that this parent is an "io-unit" node.
3) Skip IRQ initialization when device lacks "reg" property.
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | arch/sparc/kernel/of_device.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 5a2faad5d043..97bf87e8cdde 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c | |||
| @@ -596,14 +596,41 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
| 596 | static int pil_to_sbus[] = { | 596 | static int pil_to_sbus[] = { |
| 597 | 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, | 597 | 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, |
| 598 | }; | 598 | }; |
| 599 | struct device_node *busp = dp->parent; | 599 | struct device_node *io_unit, *sbi = dp->parent; |
| 600 | struct linux_prom_registers *regs; | 600 | struct linux_prom_registers *regs; |
| 601 | int board = of_getintprop_default(busp, "board#", 0); | 601 | int board, slot; |
| 602 | int slot; | 602 | |
| 603 | while (sbi) { | ||
| 604 | if (!strcmp(sbi->name, "sbi")) | ||
| 605 | break; | ||
| 606 | |||
| 607 | sbi = sbi->parent; | ||
| 608 | } | ||
| 609 | if (!sbi) | ||
| 610 | goto build_resources; | ||
| 603 | 611 | ||
| 604 | regs = of_get_property(dp, "reg", NULL); | 612 | regs = of_get_property(dp, "reg", NULL); |
| 613 | if (!regs) | ||
| 614 | goto build_resources; | ||
| 615 | |||
| 605 | slot = regs->which_io; | 616 | slot = regs->which_io; |
| 606 | 617 | ||
| 618 | /* If SBI's parent is not io-unit or the io-unit lacks | ||
| 619 | * a "board#" property, something is very wrong. | ||
| 620 | */ | ||
| 621 | if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { | ||
| 622 | printk("%s: Error, parent is not io-unit.\n", | ||
| 623 | sbi->full_name); | ||
| 624 | goto build_resources; | ||
| 625 | } | ||
| 626 | io_unit = sbi->parent; | ||
| 627 | board = of_getintprop_default(io_unit, "board#", -1); | ||
| 628 | if (board == -1) { | ||
| 629 | printk("%s: Error, lacks board# property.\n", | ||
| 630 | io_unit->full_name); | ||
| 631 | goto build_resources; | ||
| 632 | } | ||
| 633 | |||
| 607 | for (i = 0; i < op->num_irqs; i++) { | 634 | for (i = 0; i < op->num_irqs; i++) { |
| 608 | int this_irq = op->irqs[i]; | 635 | int this_irq = op->irqs[i]; |
| 609 | int sbusl = pil_to_sbus[this_irq]; | 636 | int sbusl = pil_to_sbus[this_irq]; |
| @@ -617,6 +644,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
| 617 | } | 644 | } |
| 618 | } | 645 | } |
| 619 | 646 | ||
| 647 | build_resources: | ||
| 620 | build_device_resources(op, parent); | 648 | build_device_resources(op, parent); |
| 621 | 649 | ||
| 622 | op->dev.parent = parent; | 650 | op->dev.parent = parent; |
