aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2019-06-18 14:11:36 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2019-06-29 09:31:24 +1000
commit9aa443a94b6fe4e808dd0c76cc2f3f31e90559ac (patch)
treecd1a897e74b501cf5ea9dcdd8d9229730e1463c3
parenta29e01b2c80599f495fb0ae7337163a641d348c1 (diff)
downloadpci-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.c72
-rw-r--r--arch/alpha/kernel/sys_nautilus.c8
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. */