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

Commit 16e85d1a authored by Tony Luck's avatar Tony Luck
Browse files

Pull add-mmio-to-proc-iomem into release branch

parents 7669a225 4f41d5a4
Loading
Loading
Loading
Loading
+82 −24
Original line number Diff line number Diff line
@@ -137,35 +137,98 @@ alloc_pci_controller (int seg)
	return controller;
}

static u64 __devinit
add_io_space (struct acpi_resource_address64 *addr)
struct pci_root_info {
	struct pci_controller *controller;
	char *name;
};

static unsigned int
new_space (u64 phys_base, int sparse)
{
	u64 offset;
	int sparse = 0;
	u64 mmio_base;
	int i;

	if (addr->address_translation_offset == 0)
		return IO_SPACE_BASE(0);	/* part of legacy IO space */

	if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
		sparse = 1;
	if (phys_base == 0)
		return 0;	/* legacy I/O port space */

	offset = (u64) ioremap(addr->address_translation_offset, 0);
	mmio_base = (u64) ioremap(phys_base, 0);
	for (i = 0; i < num_io_spaces; i++)
		if (io_space[i].mmio_base == offset &&
		if (io_space[i].mmio_base == mmio_base &&
		    io_space[i].sparse == sparse)
			return IO_SPACE_BASE(i);
			return i;

	if (num_io_spaces == MAX_IO_SPACES) {
		printk("Too many IO port spaces\n");
		printk(KERN_ERR "PCI: Too many IO port spaces "
			"(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
		return ~0;
	}

	i = num_io_spaces++;
	io_space[i].mmio_base = offset;
	io_space[i].mmio_base = mmio_base;
	io_space[i].sparse = sparse;

	return IO_SPACE_BASE(i);
	return i;
}

static u64 __devinit
add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
{
	struct resource *resource;
	char *name;
	u64 base, min, max, base_port;
	unsigned int sparse = 0, space_nr, len;

	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
	if (!resource) {
		printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
			info->name);
		goto out;
	}

	len = strlen(info->name) + 32;
	name = kzalloc(len, GFP_KERNEL);
	if (!name) {
		printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
			info->name);
		goto free_resource;
	}

	min = addr->min_address_range;
	max = min + addr->address_length - 1;
	if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
		sparse = 1;

	space_nr = new_space(addr->address_translation_offset, sparse);
	if (space_nr == ~0)
		goto free_name;

	base = __pa(io_space[space_nr].mmio_base);
	base_port = IO_SPACE_BASE(space_nr);
	snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
		base_port + min, base_port + max);

	/*
	 * The SDM guarantees the legacy 0-64K space is sparse, but if the
	 * mapping is done by the processor (not the bridge), ACPI may not
	 * mark it as sparse.
	 */
	if (space_nr == 0)
		sparse = 1;

	resource->name  = name;
	resource->flags = IORESOURCE_MEM;
	resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
	resource->end   = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
	insert_resource(&iomem_resource, resource);

	return base_port;

free_name:
	kfree(name);
free_resource:
	kfree(resource);
out:
	return ~0;
}

static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data)
	return AE_OK;
}

struct pci_root_info {
	struct pci_controller *controller;
	char *name;
};

static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
{
	struct pci_root_info *info = data;
@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
	} else if (addr.resource_type == ACPI_IO_RANGE) {
		flags = IORESOURCE_IO;
		root = &ioport_resource;
		offset = add_io_space(&addr);
		offset = add_io_space(info, &addr);
		if (offset == ~0)
			return AE_OK;
	} else
@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
	window->resource.name = info->name;
	window->resource.flags = flags;
	window->resource.start = addr.min_address_range + offset;
	window->resource.end = addr.max_address_range + offset;
	window->resource.end = window->resource.start + addr.address_length - 1;
	window->resource.child = NULL;
	window->offset = offset;