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>
This commit is contained in:
parent
2cd6975a4f
commit
7ec303a724
|
@ -134,9 +134,46 @@ struct pci_controller * __init pcibios_alloc_controller(void)
|
||||||
return pci_ctrl;
|
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)
|
static int __init pcibios_init(void)
|
||||||
{
|
{
|
||||||
struct pci_controller *pci_ctrl;
|
struct pci_controller *pci_ctrl;
|
||||||
|
struct list_head resources;
|
||||||
struct pci_bus *bus;
|
struct pci_bus *bus;
|
||||||
int next_busno = 0, i;
|
int next_busno = 0, i;
|
||||||
|
|
||||||
|
@ -145,19 +182,10 @@ static int __init pcibios_init(void)
|
||||||
/* Scan all of the recorded PCI controllers. */
|
/* Scan all of the recorded PCI controllers. */
|
||||||
for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
|
for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
|
||||||
pci_ctrl->last_busno = 0xff;
|
pci_ctrl->last_busno = 0xff;
|
||||||
bus = pci_scan_bus(pci_ctrl->first_busno, pci_ctrl->ops,
|
INIT_LIST_HEAD(&resources);
|
||||||
pci_ctrl);
|
pci_controller_apertures(pci_ctrl, &resources);
|
||||||
if (pci_ctrl->io_resource.flags) {
|
bus = pci_scan_root_bus(NULL, pci_ctrl->first_busno,
|
||||||
unsigned long offs;
|
pci_ctrl->ops, pci_ctrl, &resources);
|
||||||
|
|
||||||
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];
|
|
||||||
pci_ctrl->bus = bus;
|
pci_ctrl->bus = bus;
|
||||||
pci_ctrl->last_busno = bus->subordinate;
|
pci_ctrl->last_busno = bus->subordinate;
|
||||||
if (next_busno <= pci_ctrl->last_busno)
|
if (next_busno <= pci_ctrl->last_busno)
|
||||||
|
@ -178,36 +206,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
io_offset = (unsigned long)pci_ctrl->io_space.base;
|
io_offset = (unsigned long)pci_ctrl->io_space.base;
|
||||||
if (bus->parent == NULL) {
|
if (bus->parent) {
|
||||||
/* 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 {
|
|
||||||
/* This is a subordinate bridge */
|
/* This is a subordinate bridge */
|
||||||
pci_read_bridge_bases(bus);
|
pci_read_bridge_bases(bus);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue