diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/host/pci-host-common.c | 49 | ||||
-rw-r--r-- | drivers/pci/of.c | 51 |
2 files changed, 53 insertions, 47 deletions
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 44a47d4..efd904d 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -24,50 +24,6 @@ #include <linux/pci-ecam.h> #include <linux/platform_device.h> -static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) -{ - int err, res_valid = 0; - struct device_node *np = dev->of_node; - resource_size_t iobase; - struct resource_entry *win, *tmp; - - err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase); - if (err) - return err; - - err = devm_request_pci_bus_resources(dev, resources); - if (err) - return err; - - resource_list_for_each_entry_safe(win, tmp, resources) { - struct resource *res = win->res; - - switch (resource_type(res)) { - case IORESOURCE_IO: - err = pci_remap_iospace(res, iobase); - if (err) { - dev_warn(dev, "error %d: failed to map resource %pR\n", - err, res); - resource_list_destroy_entry(win); - } - break; - case IORESOURCE_MEM: - res_valid |= !(res->flags & IORESOURCE_PREFETCH); - break; - case IORESOURCE_BUS: - *bus_range = res; - break; - } - } - - if (res_valid) - return 0; - - dev_err(dev, "non-prefetchable memory resource required\n"); - return -EINVAL; -} - static void gen_pci_unmap_cfg(void *ptr) { pci_ecam_free((struct pci_config_window *)ptr); @@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, struct pci_config_window *cfg; /* Parse our PCI ranges and request their resources */ - err = gen_pci_parse_request_of_pci_ranges(dev, resources, &bus_range); + err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range); if (err) - goto err_out; + return ERR_PTR(err); err = of_address_to_resource(dev->of_node, 0, &cfgres); if (err) { @@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev, of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - INIT_LIST_HEAD(&resources); cfg = gen_pci_init(dev, &resources, ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index e112da1..54e2105 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -88,3 +88,54 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) return NULL; #endif } + +int pci_parse_request_of_pci_ranges(struct device *dev, + struct list_head *resources, + struct resource **bus_range) +{ + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; + struct resource_entry *win, *tmp; + + INIT_LIST_HEAD(resources); + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase); + if (err) + return err; + + err = devm_request_pci_bus_resources(dev, resources); + if (err) + goto out_release_res; + + resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); + if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", + err, res); + resource_list_destroy_entry(win); + } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); + break; + case IORESOURCE_BUS: + if (bus_range) + *bus_range = res; + break; + } + } + + if (res_valid) + return 0; + + dev_err(dev, "non-prefetchable memory resource required\n"); + err = -EINVAL; + + out_release_res: + pci_free_resource_list(resources); + return err; +} |