summaryrefslogtreecommitdiff
path: root/drivers/pci/of.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2018-01-31 19:21:33 +0300
committerBjorn Helgaas <helgaas@kernel.org>2018-01-31 19:21:33 +0300
commitc7f75aecb2d9436c4bef8b413231f60deae3453c (patch)
treead6082d4a0d79226637af66ee8f2fc4b24590d4b /drivers/pci/of.c
parenta07ae842e209196ffe0fe8feacd489aba772d8a0 (diff)
parent37dddf14f1aecd9fa89a5136b38b33cab54b9195 (diff)
downloadlinux-c7f75aecb2d9436c4bef8b413231f60deae3453c.tar.xz
Merge remote-tracking branch 'lorenzo/pci/cadence' into next
* lorenzo/pci/cadence: PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller PCI: endpoint: Fix EPF device name to support multi-function devices PCI: endpoint: Add the function number as argument to EPC ops PCI: cadence: Add host driver for Cadence PCIe controller dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller PCI: Add vendor ID for Cadence PCI: Add generic function to probe PCI host controllers PCI: generic: fix missing call of pci_free_resource_list() PCI: OF: Add generic function to parse and allocate PCI resources PCI: Regroup all PCI related entries into drivers/pci/Makefile Conflicts: drivers/pci/of.c include/linux/pci.h
Diffstat (limited to 'drivers/pci/of.c')
-rw-r--r--drivers/pci/of.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index e81835bdf4fa..c7136e259698 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -92,7 +92,6 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
#endif
}
-
static inline int __of_pci_pci_compare(struct device_node *node,
unsigned int data)
{
@@ -598,3 +597,55 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
}
EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
#endif /* CONFIG_OF_IRQ */
+
+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;
+}
+