diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-11-06 13:55:58 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2011-11-24 22:32:55 -0500 |
commit | 48c2ce97fa406607ca5e11a76cf507d171452dd9 (patch) | |
tree | d9daa6be9867b935dce21afd1bad1be806efafbd /arch/powerpc/kernel | |
parent | 491b98c315dbe39b20bd4a24a6179c42349f42c0 (diff) |
powerpc/pci: Change how re-assigning resouces work
When PCI_REASSIGN_ALL_RSRC is set, we used to clear all bus resources
at the beginning of survey and re-allocate them later.
This changes it so instead, during early fixup, we mark all resources
as IORESOURCE_UNSET and move them down to be 0-based.
Later, if bus resources are still unset at the beginning of the survey,
then we clear them.
This shouldn't impact the re-assignment case on 4xx, but will enable
us to have the platform do some custom resource assignment before the
survey, by clearing individual resources IORESOURCE_UNSET bit.
Also limits the clutter in the kernel log from fixup when re-assigning
since we don't care about the offset applied to the BAR values in this
case.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f5b753de3718..8f428fff545f 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -921,18 +921,22 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) | |||
921 | struct resource *res = dev->resource + i; | 921 | struct resource *res = dev->resource + i; |
922 | if (!res->flags) | 922 | if (!res->flags) |
923 | continue; | 923 | continue; |
924 | /* On platforms that have PCI_PROBE_ONLY set, we don't | 924 | |
925 | * consider 0 as an unassigned BAR value. It's technically | 925 | /* 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 | 926 | * 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 | 927 | * at 0 as unset as well, except if PCI_PROBE_ONLY is also set |
928 | * around and hope for the best... | 928 | * since in that case, we don't want to re-assign anything |
929 | */ | 929 | */ |
930 | if (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY)) { | 930 | if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) || |
931 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n", | 931 | (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) { |
932 | pci_name(dev), i, | 932 | /* Only print message if not re-assigning */ |
933 | (unsigned long long)res->start, | 933 | if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) |
934 | (unsigned long long)res->end, | 934 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] " |
935 | (unsigned int)res->flags); | 935 | "is unassigned\n", |
936 | pci_name(dev), i, | ||
937 | (unsigned long long)res->start, | ||
938 | (unsigned long long)res->end, | ||
939 | (unsigned int)res->flags); | ||
936 | res->end -= res->start; | 940 | res->end -= res->start; |
937 | res->start = 0; | 941 | res->start = 0; |
938 | res->flags |= IORESOURCE_UNSET; | 942 | res->flags |= IORESOURCE_UNSET; |
@@ -1042,6 +1046,16 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1042 | if (i >= 3 && bus->self->transparent) | 1046 | if (i >= 3 && bus->self->transparent) |
1043 | continue; | 1047 | continue; |
1044 | 1048 | ||
1049 | /* If we are going to re-assign everything, mark the resource | ||
1050 | * as unset and move it down to 0 | ||
1051 | */ | ||
1052 | if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) { | ||
1053 | res->flags |= IORESOURCE_UNSET; | ||
1054 | res->end -= res->start; | ||
1055 | res->start = 0; | ||
1056 | continue; | ||
1057 | } | ||
1058 | |||
1045 | pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", | 1059 | pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", |
1046 | pci_name(dev), i, | 1060 | pci_name(dev), i, |
1047 | (unsigned long long)res->start,\ | 1061 | (unsigned long long)res->start,\ |
@@ -1262,18 +1276,15 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1262 | pci_bus_for_each_resource(bus, res, i) { | 1276 | pci_bus_for_each_resource(bus, res, i) { |
1263 | if (!res || !res->flags || res->start > res->end || res->parent) | 1277 | if (!res || !res->flags || res->start > res->end || res->parent) |
1264 | continue; | 1278 | continue; |
1279 | |||
1280 | /* If the resource was left unset at this point, we clear it */ | ||
1281 | if (res->flags & IORESOURCE_UNSET) | ||
1282 | goto clear_resource; | ||
1283 | |||
1265 | if (bus->parent == NULL) | 1284 | if (bus->parent == NULL) |
1266 | pr = (res->flags & IORESOURCE_IO) ? | 1285 | pr = (res->flags & IORESOURCE_IO) ? |
1267 | &ioport_resource : &iomem_resource; | 1286 | &ioport_resource : &iomem_resource; |
1268 | else { | 1287 | 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); | 1288 | pr = pci_find_parent_resource(bus->self, res); |
1278 | if (pr == res) { | 1289 | if (pr == res) { |
1279 | /* this happens when the generic PCI | 1290 | /* this happens when the generic PCI |
@@ -1304,9 +1315,9 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1304 | if (reparent_resources(pr, res) == 0) | 1315 | if (reparent_resources(pr, res) == 0) |
1305 | continue; | 1316 | continue; |
1306 | } | 1317 | } |
1307 | printk(KERN_WARNING "PCI: Cannot allocate resource region " | 1318 | pr_warning("PCI: Cannot allocate resource region " |
1308 | "%d of PCI bridge %d, will remap\n", i, bus->number); | 1319 | "%d of PCI bridge %d, will remap\n", i, bus->number); |
1309 | clear_resource: | 1320 | clear_resource: |
1310 | res->start = res->end = 0; | 1321 | res->start = res->end = 0; |
1311 | res->flags = 0; | 1322 | res->flags = 0; |
1312 | } | 1323 | } |
@@ -1451,16 +1462,11 @@ void __init pcibios_resource_survey(void) | |||
1451 | { | 1462 | { |
1452 | struct pci_bus *b; | 1463 | struct pci_bus *b; |
1453 | 1464 | ||
1454 | /* Allocate and assign resources. If we re-assign everything, then | 1465 | /* Allocate and assign resources */ |
1455 | * we skip the allocate phase | ||
1456 | */ | ||
1457 | list_for_each_entry(b, &pci_root_buses, node) | 1466 | list_for_each_entry(b, &pci_root_buses, node) |
1458 | pcibios_allocate_bus_resources(b); | 1467 | pcibios_allocate_bus_resources(b); |
1459 | 1468 | pcibios_allocate_resources(0); | |
1460 | if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) { | 1469 | pcibios_allocate_resources(1); |
1461 | pcibios_allocate_resources(0); | ||
1462 | pcibios_allocate_resources(1); | ||
1463 | } | ||
1464 | 1470 | ||
1465 | /* Before we start assigning unassigned resource, we try to reserve | 1471 | /* Before we start assigning unassigned resource, we try to reserve |
1466 | * the low IO area and the VGA memory area if they intersect the | 1472 | * the low IO area and the VGA memory area if they intersect the |