Add of_pci_epc_get() and of_pci_epc_get_by_name() to get reference to EPC from device-tree. This is added in preparation to define an endpoint function device in device tree. Signed-off-by: Kishon Vijay Abraham I <kishon@xxxxxx> --- drivers/pci/endpoint/pci-epc-core.c | 61 +++++++++++++++++++++++++++++ include/linux/pci-epc.h | 3 ++ 2 files changed, 64 insertions(+) diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 82ba0dc7f2f5..177a3fc1a0dd 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -83,6 +83,66 @@ struct pci_epc *pci_epc_get(const char *epc_name) } EXPORT_SYMBOL_GPL(pci_epc_get); +/** + * of_pci_epc_get() - get PCI endpoint controller from device node and index + * @node: device node which contains the phandle to endpoint controller + * @index: index of the endpoint controller in "epcs" property + * + * Returns the EPC corresponding to the _index_ entry in "epcs" property + * present in device node, after getting a refcount to it or -ENODEV if + * there is no such EPC or -EPROBE_DEFER if there is a phandle to the phy, + * but the device is not yet loaded. + */ +struct pci_epc *of_pci_epc_get(struct device_node *node, int index) +{ + struct device_node *epc_node; + struct class_dev_iter iter; + struct pci_epc *epc; + struct device *dev; + + epc_node = of_parse_phandle(node, "epcs", index); + if (!epc_node) + return ERR_PTR(-ENODEV); + + class_dev_iter_init(&iter, pci_epc_class, NULL, NULL); + while ((dev = class_dev_iter_next(&iter))) { + epc = to_pci_epc(dev); + if (epc_node != epc->dev.of_node) + continue; + + of_node_put(epc_node); + class_dev_iter_exit(&iter); + get_device(&epc->dev); + return epc; + } + + of_node_put(epc_node); + class_dev_iter_exit(&iter); + return ERR_PTR(-EPROBE_DEFER); +} +EXPORT_SYMBOL_GPL(of_pci_epc_get); + +/** + * of_pci_epc_get_by_name() - get PCI endpoint controller from device node + * and string + * @node: device node which contains the phandle to endpoint controller + * @epc_name: name of endpoint controller as present in "epc-names" property + * + * Returns the EPC corresponding to the epc_name in "epc-names" property + * present in device node. + */ +struct pci_epc *of_pci_epc_get_by_name(struct device_node *node, + const char *epc_name) +{ + int index = 0; + + if (epc_name) + index = of_property_match_string(node, "epc-names", epc_name); + + return of_pci_epc_get(node, index); +} +EXPORT_SYMBOL_GPL(of_pci_epc_get_by_name); + /** * pci_epc_get_first_free_bar() - helper to get first unreserved BAR * @epc_features: pci_epc_features structure that holds the reserved bar bitmap @@ -629,6 +689,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops, device_initialize(&epc->dev); epc->dev.class = pci_epc_class; epc->dev.parent = dev; + epc->dev.of_node = dev->of_node; epc->ops = ops; ret = dev_set_name(&epc->dev, "%s", dev_name(dev)); diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h index cc66bec8be90..dd3c2d566c3d 100644 --- a/include/linux/pci-epc.h +++ b/include/linux/pci-epc.h @@ -211,6 +211,9 @@ int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base, int pci_epc_multi_mem_init(struct pci_epc *epc, struct pci_epc_mem_window *window, unsigned int num_windows); +struct pci_epc *of_pci_epc_get(struct device_node *node, int index); +struct pci_epc *of_pci_epc_get_by_name(struct device_node *node, + const char *epc_name); void pci_epc_mem_exit(struct pci_epc *epc); void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, phys_addr_t *phys_addr, size_t size); -- 2.17.1