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

Commit 463eb297 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Tony Luck
Browse files

[IA64] respect ACPI producer/consumer flag for PCI root bridges



Address space resources for ACPI devices have a producer/consumer
flag.  All devices "consume" the indicated address space.  If the
resource is marked as a "producer", the range is also passed on
to child devices.

We currently ignore this flag when setting up MMIO and I/O port
windows for PCI root bridges, so we could mistakenly interpret
a "consumed-only" range, like CSR space for the device itself,
as a window that is routed to children.

Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 12f44f46
Loading
Loading
Loading
Loading
+27 −8
Original line number Diff line number Diff line
@@ -191,6 +191,29 @@ add_io_space (struct acpi_resource_address64 *addr)
	return IO_SPACE_BASE(i);
}

static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
	struct acpi_resource_address64 *addr)
{
	acpi_status status;

	/*
	 * We're only interested in _CRS descriptors that are
	 *	- address space descriptors for memory or I/O space
	 *	- non-zero size
	 *	- producers, i.e., the address space is routed downstream,
	 *	  not consumed by the bridge itself
	 */
	status = acpi_resource_to_address64(resource, addr);
	if (ACPI_SUCCESS(status) &&
	    (addr->resource_type == ACPI_MEMORY_RANGE ||
	     addr->resource_type == ACPI_IO_RANGE) &&
	    addr->address_length &&
	    addr->producer_consumer == ACPI_PRODUCER)
		return AE_OK;

	return AE_ERROR;
}

static acpi_status __devinit
count_window (struct acpi_resource *resource, void *data)
{
@@ -198,10 +221,8 @@ count_window (struct acpi_resource *resource, void *data)
	struct acpi_resource_address64 addr;
	acpi_status status;

	status = acpi_resource_to_address64(resource, &addr);
	status = resource_to_window(resource, &addr);
	if (ACPI_SUCCESS(status))
		if (addr.resource_type == ACPI_MEMORY_RANGE ||
		    addr.resource_type == ACPI_IO_RANGE)
		(*windows)++;

	return AE_OK;
@@ -221,13 +242,11 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
	unsigned long flags, offset = 0;
	struct resource *root;

	status = acpi_resource_to_address64(res, &addr);
	/* Return AE_OK for non-window resources to keep scanning for more */
	status = resource_to_window(res, &addr);
	if (!ACPI_SUCCESS(status))
		return AE_OK;

	if (!addr.address_length)
		return AE_OK;

	if (addr.resource_type == ACPI_MEMORY_RANGE) {
		flags = IORESOURCE_MEM;
		root = &iomem_resource;