diff options
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 2538030954d8..da5a3855a0c4 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * 2 of the License, or (at your option) any later version. | 16 | * 2 of the License, or (at your option) any later version. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #undef DEBUG | 19 | #define DEBUG |
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
@@ -1356,6 +1356,63 @@ static void __init pcibios_allocate_resources(int pass) | |||
1356 | } | 1356 | } |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus) | ||
1360 | { | ||
1361 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
1362 | resource_size_t offset; | ||
1363 | struct resource *res, *pres; | ||
1364 | int i; | ||
1365 | |||
1366 | pr_debug("Reserving legacy ranges for domain %04x\n", pci_domain_nr(bus)); | ||
1367 | |||
1368 | /* Check for IO */ | ||
1369 | if (!(hose->io_resource.flags & IORESOURCE_IO)) | ||
1370 | goto no_io; | ||
1371 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
1372 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | ||
1373 | BUG_ON(res == NULL); | ||
1374 | res->name = "Legacy IO"; | ||
1375 | res->flags = IORESOURCE_IO; | ||
1376 | res->start = offset; | ||
1377 | res->end = (offset + 0xfff) & 0xfffffffful; | ||
1378 | pr_debug("Candidate legacy IO: %pR\n", res); | ||
1379 | if (request_resource(&hose->io_resource, res)) { | ||
1380 | printk(KERN_DEBUG | ||
1381 | "PCI %04x:%02x Cannot reserve Legacy IO %pR\n", | ||
1382 | pci_domain_nr(bus), bus->number, res); | ||
1383 | kfree(res); | ||
1384 | } | ||
1385 | |||
1386 | no_io: | ||
1387 | /* Check for memory */ | ||
1388 | offset = hose->pci_mem_offset; | ||
1389 | pr_debug("hose mem offset: %016llx\n", (unsigned long long)offset); | ||
1390 | for (i = 0; i < 3; i++) { | ||
1391 | pres = &hose->mem_resources[i]; | ||
1392 | if (!(pres->flags & IORESOURCE_MEM)) | ||
1393 | continue; | ||
1394 | pr_debug("hose mem res: %pR\n", pres); | ||
1395 | if ((pres->start - offset) <= 0xa0000 && | ||
1396 | (pres->end - offset) >= 0xbffff) | ||
1397 | break; | ||
1398 | } | ||
1399 | if (i >= 3) | ||
1400 | return; | ||
1401 | res = kzalloc(sizeof(struct resource), GFP_KERNEL); | ||
1402 | BUG_ON(res == NULL); | ||
1403 | res->name = "Legacy VGA memory"; | ||
1404 | res->flags = IORESOURCE_MEM; | ||
1405 | res->start = 0xa0000 + offset; | ||
1406 | res->end = 0xbffff + offset; | ||
1407 | pr_debug("Candidate VGA memory: %pR\n", res); | ||
1408 | if (request_resource(pres, res)) { | ||
1409 | printk(KERN_DEBUG | ||
1410 | "PCI %04x:%02x Cannot reserve VGA memory %pR\n", | ||
1411 | pci_domain_nr(bus), bus->number, res); | ||
1412 | kfree(res); | ||
1413 | } | ||
1414 | } | ||
1415 | |||
1359 | void __init pcibios_resource_survey(void) | 1416 | void __init pcibios_resource_survey(void) |
1360 | { | 1417 | { |
1361 | struct pci_bus *b; | 1418 | struct pci_bus *b; |
@@ -1371,6 +1428,18 @@ void __init pcibios_resource_survey(void) | |||
1371 | pcibios_allocate_resources(1); | 1428 | pcibios_allocate_resources(1); |
1372 | } | 1429 | } |
1373 | 1430 | ||
1431 | /* Before we start assigning unassigned resource, we try to reserve | ||
1432 | * the low IO area and the VGA memory area if they intersect the | ||
1433 | * bus available resources to avoid allocating things on top of them | ||
1434 | */ | ||
1435 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { | ||
1436 | list_for_each_entry(b, &pci_root_buses, node) | ||
1437 | pcibios_reserve_legacy_regions(b); | ||
1438 | } | ||
1439 | |||
1440 | /* Now, if the platform didn't decide to blindly trust the firmware, | ||
1441 | * we proceed to assigning things that were left unassigned | ||
1442 | */ | ||
1374 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { | 1443 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { |
1375 | pr_debug("PCI: Assigning unassigned resouces...\n"); | 1444 | pr_debug("PCI: Assigning unassigned resouces...\n"); |
1376 | pci_assign_unassigned_resources(); | 1445 | pci_assign_unassigned_resources(); |