diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2011-10-28 16:28:19 -0600 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2012-01-06 12:11:14 -0800 |
commit | 7ec303a7247a46a7a88a4f890466fd12dbdd5dc6 (patch) | |
tree | 7fc9f7f177509b99caf43c4103fa3c40e1e50431 /arch/xtensa | |
parent | 2cd6975a4ff92a75e46240109d01c1daf4682e5d (diff) | |
download | lwn-7ec303a7247a46a7a88a4f890466fd12dbdd5dc6.tar.gz lwn-7ec303a7247a46a7a88a4f890466fd12dbdd5dc6.zip |
xtensa/PCI: convert to pci_scan_root_bus() for correct root bus resources
Convert from pci_scan_bus() to pci_scan_root_bus() and remove root bus
fixups. This fixes the problem of "early" and "header" quirks
seeing incorrect root bus resources.
This arch was unusual because it filled in bus->resource[0..3] in
pcibios_init(), then overwrote them, applied io_space.offset and
checked for unset resources in pcibios_fixup_bus(). I moved all of
that to a new pci_controller_apertures() that we can use before
scanning the root bus.
CC: Chris Zankel <chris@zankel.net>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/xtensa')
-rw-r--r-- | arch/xtensa/kernel/pci.c | 85 |
1 files changed, 42 insertions, 43 deletions
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 644b2d4b299d..61045c192e88 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -134,9 +134,46 @@ struct pci_controller * __init pcibios_alloc_controller(void) return pci_ctrl; } +static void __init pci_controller_apertures(struct pci_controller *pci_ctrl, + struct list_head *resources) +{ + struct resource *res; + unsigned long io_offset; + int i; + + io_offset = (unsigned long)pci_ctrl->io_space.base; + res = &pci_ctrl->io_resource; + if (!res->flags) { + if (io_offset) + printk (KERN_ERR "I/O resource not set for host" + " bridge %d\n", pci_ctrl->index); + res->start = 0; + res->end = IO_SPACE_LIMIT; + res->flags = IORESOURCE_IO; + } + res->start += io_offset; + res->end += io_offset; + pci_add_resource(resources, res); + + for (i = 0; i < 3; i++) { + res = &pci_ctrl->mem_resources[i]; + if (!res->flags) { + if (i > 0) + continue; + printk(KERN_ERR "Memory resource not set for " + "host bridge %d\n", pci_ctrl->index); + res->start = 0; + res->end = ~0U; + res->flags = IORESOURCE_MEM; + } + pci_add_resource(resources, res); + } +} + static int __init pcibios_init(void) { struct pci_controller *pci_ctrl; + struct list_head resources; struct pci_bus *bus; int next_busno = 0, i; @@ -145,19 +182,10 @@ static int __init pcibios_init(void) /* Scan all of the recorded PCI controllers. */ for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) { pci_ctrl->last_busno = 0xff; - bus = pci_scan_bus(pci_ctrl->first_busno, pci_ctrl->ops, - pci_ctrl); - if (pci_ctrl->io_resource.flags) { - unsigned long offs; - - offs = (unsigned long)pci_ctrl->io_space.base; - pci_ctrl->io_resource.start += offs; - pci_ctrl->io_resource.end += offs; - bus->resource[0] = &pci_ctrl->io_resource; - } - for (i = 0; i < 3; ++i) - if (pci_ctrl->mem_resources[i].flags) - bus->resource[i+1] =&pci_ctrl->mem_resources[i]; + INIT_LIST_HEAD(&resources); + pci_controller_apertures(pci_ctrl, &resources); + bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno, + pci_ctrl->ops, pci_ctrl, &resources); pci_ctrl->bus = bus; pci_ctrl->last_busno = bus->subordinate; if (next_busno <= pci_ctrl->last_busno) @@ -178,36 +206,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) int i; io_offset = (unsigned long)pci_ctrl->io_space.base; - if (bus->parent == NULL) { - /* this is a host bridge - fill in its resources */ - pci_ctrl->bus = bus; - - bus->resource[0] = res = &pci_ctrl->io_resource; - if (!res->flags) { - if (io_offset) - printk (KERN_ERR "I/O resource not set for host" - " bridge %d\n", pci_ctrl->index); - res->start = 0; - res->end = IO_SPACE_LIMIT; - res->flags = IORESOURCE_IO; - } - res->start += io_offset; - res->end += io_offset; - - for (i = 0; i < 3; i++) { - res = &pci_ctrl->mem_resources[i]; - if (!res->flags) { - if (i > 0) - continue; - printk(KERN_ERR "Memory resource not set for " - "host bridge %d\n", pci_ctrl->index); - res->start = 0; - res->end = ~0U; - res->flags = IORESOURCE_MEM; - } - bus->resource[i+1] = res; - } - } else { + if (bus->parent) { /* This is a subordinate bridge */ pci_read_bridge_bases(bus); |