@@ -624,6 +624,44 @@ static void pci_bus_register_of_sysfs(struct pci_bus *bus)
pci_bus_register_of_sysfs(child_bus);
}
+static void pci_claim_legacy_resources(struct pci_dev *dev)
+{
+ struct pci_bus_region region;
+ struct resource *p, *root, *conflict;
+
+ if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ return;
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return;
+
+ p->name = "Video RAM area";
+ p->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ region.start = 0xa0000UL;
+ region.end = region.start + 0x1ffffUL;
+ pcibios_bus_to_resource(bus, p, ®ion);
+
+ root = pci_find_parent_resource(dev, p);
+ if (!root) {
+ pci_info(dev, "can't claim VGA legacy %pR: no compatible bridge window\n", p);
+ goto err;
+ }
+
+ conflict = request_resource_conflict(root, p);
+ if (conflict) {
+ pci_info(dev, "can't claim VGA legacy %pR: address conflict with %s %pR\n",
+ p, conflict->name, conflict);
+ goto err;
+ }
+
+ return;
+
+err:
+ kfree(p);
+}
+
static void pci_claim_bus_resources(struct pci_bus *bus)
{
struct pci_bus *child_bus;
@@ -648,6 +686,8 @@ static void pci_claim_bus_resources(struct pci_bus *bus)
pci_claim_resource(dev, i);
}
+
+ pci_claim_legacy_resources(dev);
}
list_for_each_entry(child_bus, &bus->children, node)
@@ -687,6 +727,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
pci_bus_register_of_sysfs(bus);
pci_claim_bus_resources(bus);
+
pci_bus_add_devices(bus);
return bus;
}
@@ -329,23 +329,6 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm)
}
}
-static void pci_register_legacy_regions(struct resource *io_res,
- struct resource *mem_res)
-{
- struct resource *p;
-
- /* VGA Video RAM. */
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return;
-
- p->name = "Video RAM area";
- p->start = mem_res->start + 0xa0000UL;
- p->end = p->start + 0x1ffffUL;
- p->flags = IORESOURCE_BUSY;
- request_resource(mem_res, p);
-}
-
static void pci_register_iommu_region(struct pci_pbm_info *pbm)
{
const u32 *vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma",
@@ -487,8 +470,6 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
if (pbm->mem64_space.flags)
request_resource(&iomem_resource, &pbm->mem64_space);
- pci_register_legacy_regions(&pbm->io_space,
- &pbm->mem_space);
pci_register_iommu_region(pbm);
}