diff options
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 78 |
1 files changed, 46 insertions, 32 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 458ed3bee663..fa4a573d6716 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -214,7 +214,7 @@ char __devinit *pcibios_setup(char *str) | |||
214 | * If the interrupt is used, then gets the interrupt line from the | 214 | * If the interrupt is used, then gets the interrupt line from the |
215 | * openfirmware and sets it in the pci_dev and pci_config line. | 215 | * openfirmware and sets it in the pci_dev and pci_config line. |
216 | */ | 216 | */ |
217 | int pci_read_irq_line(struct pci_dev *pci_dev) | 217 | static int pci_read_irq_line(struct pci_dev *pci_dev) |
218 | { | 218 | { |
219 | struct of_irq oirq; | 219 | struct of_irq oirq; |
220 | unsigned int virq; | 220 | unsigned int virq; |
@@ -283,7 +283,6 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
283 | 283 | ||
284 | return 0; | 284 | return 0; |
285 | } | 285 | } |
286 | EXPORT_SYMBOL(pci_read_irq_line); | ||
287 | 286 | ||
288 | /* | 287 | /* |
289 | * Platform support for /proc/bus/pci/X/Y mmap()s, | 288 | * Platform support for /proc/bus/pci/X/Y mmap()s, |
@@ -921,18 +920,22 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) | |||
921 | struct resource *res = dev->resource + i; | 920 | struct resource *res = dev->resource + i; |
922 | if (!res->flags) | 921 | if (!res->flags) |
923 | continue; | 922 | continue; |
924 | /* On platforms that have PCI_PROBE_ONLY set, we don't | 923 | |
925 | * consider 0 as an unassigned BAR value. It's technically | 924 | /* If we're going to re-assign everything, we mark all resources |
926 | * a valid value, but linux doesn't like it... so when we can | 925 | * as unset (and 0-base them). In addition, we mark BARs starting |
927 | * re-assign things, we do so, but if we can't, we keep it | 926 | * at 0 as unset as well, except if PCI_PROBE_ONLY is also set |
928 | * around and hope for the best... | 927 | * since in that case, we don't want to re-assign anything |
929 | */ | 928 | */ |
930 | if (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY)) { | 929 | if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) || |
931 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n", | 930 | (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) { |
932 | pci_name(dev), i, | 931 | /* Only print message if not re-assigning */ |
933 | (unsigned long long)res->start, | 932 | if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) |
934 | (unsigned long long)res->end, | 933 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] " |
935 | (unsigned int)res->flags); | 934 | "is unassigned\n", |
935 | pci_name(dev), i, | ||
936 | (unsigned long long)res->start, | ||
937 | (unsigned long long)res->end, | ||
938 | (unsigned int)res->flags); | ||
936 | res->end -= res->start; | 939 | res->end -= res->start; |
937 | res->start = 0; | 940 | res->start = 0; |
938 | res->flags |= IORESOURCE_UNSET; | 941 | res->flags |= IORESOURCE_UNSET; |
@@ -1042,6 +1045,16 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1042 | if (i >= 3 && bus->self->transparent) | 1045 | if (i >= 3 && bus->self->transparent) |
1043 | continue; | 1046 | continue; |
1044 | 1047 | ||
1048 | /* If we are going to re-assign everything, mark the resource | ||
1049 | * as unset and move it down to 0 | ||
1050 | */ | ||
1051 | if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) { | ||
1052 | res->flags |= IORESOURCE_UNSET; | ||
1053 | res->end -= res->start; | ||
1054 | res->start = 0; | ||
1055 | continue; | ||
1056 | } | ||
1057 | |||
1045 | pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", | 1058 | pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", |
1046 | pci_name(dev), i, | 1059 | pci_name(dev), i, |
1047 | (unsigned long long)res->start,\ | 1060 | (unsigned long long)res->start,\ |
@@ -1262,18 +1275,15 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1262 | pci_bus_for_each_resource(bus, res, i) { | 1275 | pci_bus_for_each_resource(bus, res, i) { |
1263 | if (!res || !res->flags || res->start > res->end || res->parent) | 1276 | if (!res || !res->flags || res->start > res->end || res->parent) |
1264 | continue; | 1277 | continue; |
1278 | |||
1279 | /* If the resource was left unset at this point, we clear it */ | ||
1280 | if (res->flags & IORESOURCE_UNSET) | ||
1281 | goto clear_resource; | ||
1282 | |||
1265 | if (bus->parent == NULL) | 1283 | if (bus->parent == NULL) |
1266 | pr = (res->flags & IORESOURCE_IO) ? | 1284 | pr = (res->flags & IORESOURCE_IO) ? |
1267 | &ioport_resource : &iomem_resource; | 1285 | &ioport_resource : &iomem_resource; |
1268 | else { | 1286 | else { |
1269 | /* Don't bother with non-root busses when | ||
1270 | * re-assigning all resources. We clear the | ||
1271 | * resource flags as if they were colliding | ||
1272 | * and as such ensure proper re-allocation | ||
1273 | * later. | ||
1274 | */ | ||
1275 | if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) | ||
1276 | goto clear_resource; | ||
1277 | pr = pci_find_parent_resource(bus->self, res); | 1287 | pr = pci_find_parent_resource(bus->self, res); |
1278 | if (pr == res) { | 1288 | if (pr == res) { |
1279 | /* this happens when the generic PCI | 1289 | /* this happens when the generic PCI |
@@ -1304,9 +1314,9 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1304 | if (reparent_resources(pr, res) == 0) | 1314 | if (reparent_resources(pr, res) == 0) |
1305 | continue; | 1315 | continue; |
1306 | } | 1316 | } |
1307 | printk(KERN_WARNING "PCI: Cannot allocate resource region " | 1317 | pr_warning("PCI: Cannot allocate resource region " |
1308 | "%d of PCI bridge %d, will remap\n", i, bus->number); | 1318 | "%d of PCI bridge %d, will remap\n", i, bus->number); |
1309 | clear_resource: | 1319 | clear_resource: |
1310 | res->start = res->end = 0; | 1320 | res->start = res->end = 0; |
1311 | res->flags = 0; | 1321 | res->flags = 0; |
1312 | } | 1322 | } |
@@ -1451,16 +1461,11 @@ void __init pcibios_resource_survey(void) | |||
1451 | { | 1461 | { |
1452 | struct pci_bus *b; | 1462 | struct pci_bus *b; |
1453 | 1463 | ||
1454 | /* Allocate and assign resources. If we re-assign everything, then | 1464 | /* Allocate and assign resources */ |
1455 | * we skip the allocate phase | ||
1456 | */ | ||
1457 | list_for_each_entry(b, &pci_root_buses, node) | 1465 | list_for_each_entry(b, &pci_root_buses, node) |
1458 | pcibios_allocate_bus_resources(b); | 1466 | pcibios_allocate_bus_resources(b); |
1459 | 1467 | pcibios_allocate_resources(0); | |
1460 | if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) { | 1468 | pcibios_allocate_resources(1); |
1461 | pcibios_allocate_resources(0); | ||
1462 | pcibios_allocate_resources(1); | ||
1463 | } | ||
1464 | 1469 | ||
1465 | /* Before we start assigning unassigned resource, we try to reserve | 1470 | /* Before we start assigning unassigned resource, we try to reserve |
1466 | * the low IO area and the VGA memory area if they intersect the | 1471 | * the low IO area and the VGA memory area if they intersect the |
@@ -1732,6 +1737,12 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) | |||
1732 | if (mode == PCI_PROBE_NORMAL) | 1737 | if (mode == PCI_PROBE_NORMAL) |
1733 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | 1738 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); |
1734 | 1739 | ||
1740 | /* Platform gets a chance to do some global fixups before | ||
1741 | * we proceed to resource allocation | ||
1742 | */ | ||
1743 | if (ppc_md.pcibios_fixup_phb) | ||
1744 | ppc_md.pcibios_fixup_phb(hose); | ||
1745 | |||
1735 | /* Configure PCI Express settings */ | 1746 | /* Configure PCI Express settings */ |
1736 | if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { | 1747 | if (bus && !pci_has_flag(PCI_PROBE_ONLY)) { |
1737 | struct pci_bus *child; | 1748 | struct pci_bus *child; |
@@ -1747,10 +1758,13 @@ void __devinit pcibios_scan_phb(struct pci_controller *hose) | |||
1747 | static void fixup_hide_host_resource_fsl(struct pci_dev *dev) | 1758 | static void fixup_hide_host_resource_fsl(struct pci_dev *dev) |
1748 | { | 1759 | { |
1749 | int i, class = dev->class >> 8; | 1760 | int i, class = dev->class >> 8; |
1761 | /* When configured as agent, programing interface = 1 */ | ||
1762 | int prog_if = dev->class & 0xf; | ||
1750 | 1763 | ||
1751 | if ((class == PCI_CLASS_PROCESSOR_POWERPC || | 1764 | if ((class == PCI_CLASS_PROCESSOR_POWERPC || |
1752 | class == PCI_CLASS_BRIDGE_OTHER) && | 1765 | class == PCI_CLASS_BRIDGE_OTHER) && |
1753 | (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) && | 1766 | (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) && |
1767 | (prog_if == 0) && | ||
1754 | (dev->bus->parent == NULL)) { | 1768 | (dev->bus->parent == NULL)) { |
1755 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 1769 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
1756 | dev->resource[i].start = 0; | 1770 | dev->resource[i].start = 0; |