Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48c2ce97 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt
Browse files

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 491b98c3
Loading
Loading
Loading
Loading
+36 −30
Original line number Original line Diff line number Diff line
@@ -921,14 +921,18 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
		struct resource *res = dev->resource + i;
		struct resource *res = dev->resource + i;
		if (!res->flags)
		if (!res->flags)
			continue;
			continue;
		/* On platforms that have PCI_PROBE_ONLY set, we don't

		 * consider 0 as an unassigned BAR value. It's technically
		/* If we're going to re-assign everything, we mark all resources
		 * a valid value, but linux doesn't like it... so when we can
		 * as unset (and 0-base them). In addition, we mark BARs starting
		 * re-assign things, we do so, but if we can't, we keep it
		 * at 0 as unset as well, except if PCI_PROBE_ONLY is also set
		 * around and hope for the best...
		 * since in that case, we don't want to re-assign anything
		 */
		 */
		if (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY)) {
		if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) ||
			pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n",
		    (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
			/* Only print message if not re-assigning */
			if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC))
				pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] "
					 "is unassigned\n",
					 pci_name(dev), i,
					 pci_name(dev), i,
					 (unsigned long long)res->start,
					 (unsigned long long)res->start,
					 (unsigned long long)res->end,
					 (unsigned long long)res->end,
@@ -1042,6 +1046,16 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
		if (i >= 3 && bus->self->transparent)
		if (i >= 3 && bus->self->transparent)
			continue;
			continue;


		/* If we are going to re-assign everything, mark the resource
		 * as unset and move it down to 0
		 */
		if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
			res->flags |= IORESOURCE_UNSET;
			res->end -= res->start;
			res->start = 0;
			continue;
		}

		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
			 pci_name(dev), i,
			 pci_name(dev), i,
			 (unsigned long long)res->start,\
			 (unsigned long long)res->start,\
@@ -1262,18 +1276,15 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
	pci_bus_for_each_resource(bus, res, i) {
	pci_bus_for_each_resource(bus, res, i) {
		if (!res || !res->flags || res->start > res->end || res->parent)
		if (!res || !res->flags || res->start > res->end || res->parent)
			continue;
			continue;

		/* If the resource was left unset at this point, we clear it */
		if (res->flags & IORESOURCE_UNSET)
			goto clear_resource;

		if (bus->parent == NULL)
		if (bus->parent == NULL)
			pr = (res->flags & IORESOURCE_IO) ?
			pr = (res->flags & IORESOURCE_IO) ?
				&ioport_resource : &iomem_resource;
				&ioport_resource : &iomem_resource;
		else {
		else {
			/* Don't bother with non-root busses when
			 * re-assigning all resources. We clear the
			 * resource flags as if they were colliding
			 * and as such ensure proper re-allocation
			 * later.
			 */
			if (pci_has_flag(PCI_REASSIGN_ALL_RSRC))
				goto clear_resource;
			pr = pci_find_parent_resource(bus->self, res);
			pr = pci_find_parent_resource(bus->self, res);
			if (pr == res) {
			if (pr == res) {
				/* this happens when the generic PCI
				/* this happens when the generic PCI
@@ -1304,7 +1315,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
			if (reparent_resources(pr, res) == 0)
			if (reparent_resources(pr, res) == 0)
				continue;
				continue;
		}
		}
		printk(KERN_WARNING "PCI: Cannot allocate resource region "
		pr_warning("PCI: Cannot allocate resource region "
			   "%d of PCI bridge %d, will remap\n", i, bus->number);
			   "%d of PCI bridge %d, will remap\n", i, bus->number);
	clear_resource:
	clear_resource:
		res->start = res->end = 0;
		res->start = res->end = 0;
@@ -1451,16 +1462,11 @@ void __init pcibios_resource_survey(void)
{
{
	struct pci_bus *b;
	struct pci_bus *b;


	/* Allocate and assign resources. If we re-assign everything, then
	/* Allocate and assign resources */
	 * we skip the allocate phase
	 */
	list_for_each_entry(b, &pci_root_buses, node)
	list_for_each_entry(b, &pci_root_buses, node)
		pcibios_allocate_bus_resources(b);
		pcibios_allocate_bus_resources(b);

	if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
	pcibios_allocate_resources(0);
	pcibios_allocate_resources(0);
	pcibios_allocate_resources(1);
	pcibios_allocate_resources(1);
	}


	/* Before we start assigning unassigned resource, we try to reserve
	/* Before we start assigning unassigned resource, we try to reserve
	 * the low IO area and the VGA memory area if they intersect the
	 * the low IO area and the VGA memory area if they intersect the