diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2019-06-18 14:11:36 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2019-06-29 09:31:24 +1000 |
commit | 9aa443a94b6fe4e808dd0c76cc2f3f31e90559ac (patch) | |
tree | cd1a897e74b501cf5ea9dcdd8d9229730e1463c3 | |
parent | a29e01b2c80599f495fb0ae7337163a641d348c1 (diff) | |
download | pci-9aa443a94b6fe4e808dd0c76cc2f3f31e90559ac.tar.gz |
alpha: PCI: Use pci_host_resource_survey()
This conversion isn't completely obvious, testing needed.
On some platforms, the alpha code used to call pcibios_claim_one_bus()
before pci_unassigned_assigned_resources().
This alpha specific function would claim resources if PCI_PROBE_ONLY
was set or if the resources had the IORESOURCE_PCI_FIXED flag set.
The latter was added to claim the legacy IDE resources before
re-assigning everything else.
We are replacing this with pci_bus_assign_resources() (called by
pci_host_resource_survey()). It will do that claiming of fixed
resources as well, however, interestingly, it does it *after* it
has assigned resources for the same bus segment (arguably a bug ?).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/alpha/kernel/pci.c | 72 | ||||
-rw-r--r-- | arch/alpha/kernel/sys_nautilus.c | 8 |
2 files changed, 30 insertions, 50 deletions
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 64fbfb0763b292..bcc079d6834275 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -253,12 +253,7 @@ pci_restore_srm_config(void) void pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_dev *dev = bus->self; - - if (pci_has_flag(PCI_PROBE_ONLY) && dev && - (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { - pci_read_bridge_bases(bus); - } + struct pci_dev *dev; list_for_each_entry(dev, &bus->devices, bus_list) { pdev_save_srm_config(dev); @@ -282,45 +277,9 @@ pcibios_set_master(struct pci_dev *dev) } void __init -pcibios_claim_one_bus(struct pci_bus *b) -{ - struct pci_dev *dev; - struct pci_bus *child_bus; - - list_for_each_entry(dev, &b->devices, bus_list) { - int i; - - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - - if (r->parent || !r->start || !r->flags) - continue; - if (pci_has_flag(PCI_PROBE_ONLY) || - (r->flags & IORESOURCE_PCI_FIXED)) { - if (pci_claim_resource(dev, i) == 0) - continue; - - pci_claim_bridge_resource(dev, i); - } - } - } - - list_for_each_entry(child_bus, &b->children, node) - pcibios_claim_one_bus(child_bus); -} - -static void __init -pcibios_claim_console_setup(void) -{ - struct pci_bus *b; - - list_for_each_entry(b, &pci_root_buses, node) - pcibios_claim_one_bus(b); -} - -void __init common_init_pci(void) { + enum pci_rsrc_policy rsrc_policy; struct pci_controller *hose; struct list_head resources; struct pci_host_bridge *bridge; @@ -331,6 +290,22 @@ common_init_pci(void) u32 sg_base; unsigned long end; + /* + * Resource policy depends on PCI_PROBE_ONLY. Note that alpha + * seems to give this a different meaning that most other archs. + * + * On most archs, it means to claim the existing FW setup, and + * not assign what's left unassigned nor attempt to realloc. + * + * However, alpha used to call pci_assign_unassigned_resources() + * unconditionally, so we'll set the policy here accordingly, + * overriding the default one set by pci_alloc_host_bridge + */ + if (pci_has_flag(PCI_PROBE_ONLY)) + rsrc_policy = pci_rsrc_claim_assign; + else + rsrc_policy = pci_rsrc_assign_only; + /* Scan all of the recorded PCI controllers. */ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0; @@ -359,6 +334,7 @@ common_init_pci(void) bridge->ops = alpha_mv.pci_ops; bridge->swizzle_irq = alpha_mv.pci_swizzle; bridge->map_irq = alpha_mv.pci_map_irq; + bridge->rsrc_policy = rsrc_policy; ret = pci_scan_root_bus_bridge(bridge); if (ret) { @@ -375,11 +351,10 @@ common_init_pci(void) next_busno = 0; need_domain_info = 1; } - } - pcibios_claim_console_setup(); + pci_host_resource_survey(bus); + } - pci_assign_unassigned_resources(); for (hose = hose_head; hose; hose = hose->next) { bus = hose->bus; if (bus) @@ -471,6 +446,11 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) EXPORT_SYMBOL(pci_iounmap); +bool pcibios_claim_zero_resource(struct pci_dev *dev, int rsrc_idx) +{ + return false; +} + /* FIXME: Some boxes have multiple ISA bridges! */ struct pci_dev *isa_bridge; EXPORT_SYMBOL(isa_bridge); diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index cd9a112d67ff10..be863afe89e074 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -227,6 +227,9 @@ nautilus_init_pci(void) bridge->swizzle_irq = alpha_mv.pci_swizzle; bridge->map_irq = alpha_mv.pci_map_irq; + /* Nautilus policy is to always reassign all resources */ + bridge->rsrc_policy = pci_rsrc_assign_only; + /* Scan our single hose. */ ret = pci_scan_root_bus_bridge(bridge); if (ret) { @@ -235,15 +238,12 @@ nautilus_init_pci(void) } bus = hose->bus = bridge->bus; - pcibios_claim_one_bus(bus); irongate = pci_get_domain_bus_and_slot(pci_domain_nr(bus), 0, 0); bus->self = irongate; bus->resource[0] = &irongate_io; bus->resource[1] = &irongate_mem; - pci_bus_size_bridges(bus); - /* IO port range. */ bus->resource[0]->start = 0; bus->resource[0]->end = 0xffff; @@ -274,7 +274,7 @@ nautilus_init_pci(void) if ((IRONGATE0->dev_vendor >> 16) > 0x7006) /* Albacore? */ IRONGATE0->pci_mem = pci_mem; - pci_bus_assign_resources(bus); + pci_host_resource_survey(bus); /* pci_common_swizzle() relies on bus->self being NULL for the root bus, so just clear it. */ |