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

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

parents 7669a225 4f41d5a4
...@@ -137,35 +137,98 @@ alloc_pci_controller (int seg) ...@@ -137,35 +137,98 @@ alloc_pci_controller (int seg)
return controller; return controller;
} }
static u64 __devinit struct pci_root_info {
add_io_space (struct acpi_resource_address64 *addr) struct pci_controller *controller;
char *name;
};
static unsigned int
new_space (u64 phys_base, int sparse)
{ {
u64 offset; u64 mmio_base;
int sparse = 0;
int i; int i;
if (addr->address_translation_offset == 0) if (phys_base == 0)
return IO_SPACE_BASE(0); /* part of legacy IO space */ return 0; /* legacy I/O port space */
if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
sparse = 1;
offset = (u64) ioremap(addr->address_translation_offset, 0); mmio_base = (u64) ioremap(phys_base, 0);
for (i = 0; i < num_io_spaces; i++) 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) io_space[i].sparse == sparse)
return IO_SPACE_BASE(i); return i;
if (num_io_spaces == MAX_IO_SPACES) { 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; return ~0;
} }
i = num_io_spaces++; i = num_io_spaces++;
io_space[i].mmio_base = offset; io_space[i].mmio_base = mmio_base;
io_space[i].sparse = sparse; 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, static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
...@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data) ...@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data)
return AE_OK; 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) static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
{ {
struct pci_root_info *info = data; struct pci_root_info *info = data;
...@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *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) { } else if (addr.resource_type == ACPI_IO_RANGE) {
flags = IORESOURCE_IO; flags = IORESOURCE_IO;
root = &ioport_resource; root = &ioport_resource;
offset = add_io_space(&addr); offset = add_io_space(info, &addr);
if (offset == ~0) if (offset == ~0)
return AE_OK; return AE_OK;
} else } else
...@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) ...@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
window->resource.name = info->name; window->resource.name = info->name;
window->resource.flags = flags; window->resource.flags = flags;
window->resource.start = addr.min_address_range + offset; 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->resource.child = NULL;
window->offset = offset; window->offset = offset;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment