aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/pci-common.c')
-rw-r--r--arch/powerpc/kernel/pci-common.c78
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 */
217int pci_read_irq_line(struct pci_dev *pci_dev) 217static 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}
286EXPORT_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);
1309clear_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)
1747static void fixup_hide_host_resource_fsl(struct pci_dev *dev) 1758static 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;