diff options
author | David S. Miller <davem@kimchee.(none)> | 2007-09-12 04:15:59 -0400 |
---|---|---|
committer | David S. Miller <davem@kimchee.(none)> | 2007-09-12 04:15:59 -0400 |
commit | 2cc7345ff71b27b5ac99e49ad7de39360042f601 (patch) | |
tree | faf19ff74e0a92652923ee9e4b42e47cbd16809a /arch/sparc64/kernel/pci.c | |
parent | 577107e8e4cf9f6f4f5ef8350ac9a8faa6c3796d (diff) |
[SPARC64]: Fix booting on V100 systems.
On the root PCI bus, the OBP device tree lists device 3 twice.
Once as 'pm' and once as 'lomp'.
Everything goes downhill from there.
Ignore the second instance to workaround this.
Thanks to Kövedi_Krisztián for the bug report and
testing the fix.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci.c')
-rw-r--r-- | arch/sparc64/kernel/pci.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 139b4cff8019..e8dac81d8a0d 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -744,7 +744,7 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | |||
744 | { | 744 | { |
745 | struct device_node *child; | 745 | struct device_node *child; |
746 | const u32 *reg; | 746 | const u32 *reg; |
747 | int reglen, devfn; | 747 | int reglen, devfn, prev_devfn; |
748 | struct pci_dev *dev; | 748 | struct pci_dev *dev; |
749 | 749 | ||
750 | if (ofpci_verbose) | 750 | if (ofpci_verbose) |
@@ -752,14 +752,25 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | |||
752 | node->full_name, bus->number); | 752 | node->full_name, bus->number); |
753 | 753 | ||
754 | child = NULL; | 754 | child = NULL; |
755 | prev_devfn = -1; | ||
755 | while ((child = of_get_next_child(node, child)) != NULL) { | 756 | while ((child = of_get_next_child(node, child)) != NULL) { |
756 | if (ofpci_verbose) | 757 | if (ofpci_verbose) |
757 | printk(" * %s\n", child->full_name); | 758 | printk(" * %s\n", child->full_name); |
758 | reg = of_get_property(child, "reg", ®len); | 759 | reg = of_get_property(child, "reg", ®len); |
759 | if (reg == NULL || reglen < 20) | 760 | if (reg == NULL || reglen < 20) |
760 | continue; | 761 | continue; |
762 | |||
761 | devfn = (reg[0] >> 8) & 0xff; | 763 | devfn = (reg[0] >> 8) & 0xff; |
762 | 764 | ||
765 | /* This is a workaround for some device trees | ||
766 | * which list PCI devices twice. On the V100 | ||
767 | * for example, device number 3 is listed twice. | ||
768 | * Once as "pm" and once again as "lomp". | ||
769 | */ | ||
770 | if (devfn == prev_devfn) | ||
771 | continue; | ||
772 | prev_devfn = devfn; | ||
773 | |||
763 | /* create a new pci_dev for this device */ | 774 | /* create a new pci_dev for this device */ |
764 | dev = of_create_pci_dev(pbm, child, bus, devfn, 0); | 775 | dev = of_create_pci_dev(pbm, child, bus, devfn, 0); |
765 | if (!dev) | 776 | if (!dev) |