Commit 28eeb698 authored by Jayachandran C's avatar Jayachandran C Committed by Khalid Elmously

PCI/ACPI: Support I/O resources when parsing host bridge resources

BugLink: https://bugs.launchpad.net/bugs/1797092

On platforms with memory-mapped I/O ports, such as ia64 and ARM64, we have
to map the memory region and coordinate it with the arch's I/O port
accessors.

For ia64, we do this in arch code because it supports both dense (1 byte
per I/O port) and sparse (1024 bytes per I/O port) memory mapping.  For
arm64, we only support dense mappings, which we can do in the generic code
with pci_register_io_range() and pci_remap_iospace().

Add acpi_pci_root_remap_iospace() to remap dense memory-mapped I/O port
space when adding a bridge, and call pci_unmap_iospace() to release the
space when removing the bridge.

[bhelgaas: changelog, move #ifdef inside acpi_pci_root_remap_iospace()]
Signed-off-by: default avatarJayachandran C <jchandra@broadcom.com>
Signed-off-by: default avatarSinan Kaya <okaya@codeaurora.org>
[Tomasz: merged in Sinan's patch to unmap IO resources properly, updated changelog]
Signed-off-by: default avatarTomasz Nowicki <tn@semihalf.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
(cherry picked from commit 0a70abb3)
Signed-off-by: default avatardann frazier <dann.frazier@canonical.com>
Acked-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
Acked-by: default avatarStefan Bader <stefan.bader@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 1bf376c1
...@@ -722,6 +722,36 @@ static void acpi_pci_root_validate_resources(struct device *dev, ...@@ -722,6 +722,36 @@ static void acpi_pci_root_validate_resources(struct device *dev,
} }
} }
static void acpi_pci_root_remap_iospace(struct resource_entry *entry)
{
#ifdef PCI_IOBASE
struct resource *res = entry->res;
resource_size_t cpu_addr = res->start;
resource_size_t pci_addr = cpu_addr - entry->offset;
resource_size_t length = resource_size(res);
unsigned long port;
if (pci_register_io_range(cpu_addr, length))
goto err;
port = pci_address_to_pio(cpu_addr);
if (port == (unsigned long)-1)
goto err;
res->start = port;
res->end = port + length - 1;
entry->offset = port - pci_addr;
if (pci_remap_iospace(res, cpu_addr) < 0)
goto err;
pr_info("Remapped I/O %pa to %pR\n", &cpu_addr, res);
return;
err:
res->flags |= IORESOURCE_DISABLED;
#endif
}
int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
{ {
int ret; int ret;
...@@ -742,6 +772,9 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) ...@@ -742,6 +772,9 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
"no IO and memory resources present in _CRS\n"); "no IO and memory resources present in _CRS\n");
else { else {
resource_list_for_each_entry_safe(entry, tmp, list) { resource_list_for_each_entry_safe(entry, tmp, list) {
if (entry->res->flags & IORESOURCE_IO)
acpi_pci_root_remap_iospace(entry);
if (entry->res->flags & IORESOURCE_DISABLED) if (entry->res->flags & IORESOURCE_DISABLED)
resource_list_destroy_entry(entry); resource_list_destroy_entry(entry);
else else
...@@ -813,6 +846,8 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge) ...@@ -813,6 +846,8 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge)
resource_list_for_each_entry(entry, &bridge->windows) { resource_list_for_each_entry(entry, &bridge->windows) {
res = entry->res; res = entry->res;
if (res->flags & IORESOURCE_IO)
pci_unmap_iospace(res);
if (res->parent && if (res->parent &&
(res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) (res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
release_resource(res); release_resource(res);
......
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