[U-Boot] [PATCH 3/6] pci: Support parsing PCI controller DT subnodes
Marek Vasut
marek.vasut at gmail.com
Fri Sep 21 22:59:18 UTC 2018
The PCI controller can have DT subnodes describing extra properties
of particular PCI devices, ie. a PHY attached to an EHCI controller
on a PCI bus. This patch parses those DT subnodes and assigns a node
to the PCI device instance, so that the driver can extract details
from that node and ie. configure the PHY using the PHY subsystem.
Signed-off-by: Marek Vasut <marek.vasut+renesas at gmail.com>
Cc: Simon Glass <sjg at chromium.org>
Cc: Tom Rini <trini at konsulko.com>
---
drivers/pci/pci-uclass.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index de523a76ad..e274632428 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -90,6 +90,25 @@ int pci_get_ff(enum pci_size_t size)
}
}
+static void pci_dev_find_ofnode(struct udevice *bus, phys_addr_t bdf,
+ ofnode *rnode)
+{
+ ofnode node;
+
+ dev_for_each_subnode(node, bus) {
+ phys_addr_t df, size;
+ df = ofnode_get_addr_size(node, "reg", &size);
+ if (df == FDT_ADDR_T_NONE)
+ continue;
+
+ if (PCI_MASK_BUS(df) != PCI_MASK_BUS(bdf))
+ continue;
+
+ *rnode = node;
+ break;
+ }
+};
+
int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
struct udevice **devp)
{
@@ -641,6 +660,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
pci_dev_t bdf, struct udevice **devp)
{
struct pci_driver_entry *start, *entry;
+ ofnode node = ofnode_null();
const char *drv;
int n_ents;
int ret;
@@ -651,6 +671,10 @@ static int pci_find_and_bind_driver(struct udevice *parent,
debug("%s: Searching for driver: vendor=%x, device=%x\n", __func__,
find_id->vendor, find_id->device);
+
+ /* Determine optional OF node */
+ pci_dev_find_ofnode(parent, bdf, &node);
+
start = ll_entry_start(struct pci_driver_entry, pci_driver_entry);
n_ents = ll_entry_count(struct pci_driver_entry, pci_driver_entry);
for (entry = start; entry != start + n_ents; entry++) {
@@ -684,8 +708,8 @@ static int pci_find_and_bind_driver(struct udevice *parent,
* find another driver. For now this doesn't seem
* necesssary, so just bind the first match.
*/
- ret = device_bind(parent, drv, drv->name, NULL, -1,
- &dev);
+ ret = device_bind_ofnode(parent, drv, drv->name, NULL,
+ node, &dev);
if (ret)
goto error;
debug("%s: Match found: %s\n", __func__, drv->name);
@@ -712,7 +736,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
return -ENOMEM;
drv = bridge ? "pci_bridge_drv" : "pci_generic_drv";
- ret = device_bind_driver(parent, drv, str, devp);
+ ret = device_bind_driver_to_node(parent, drv, str, node, devp);
if (ret) {
debug("%s: Failed to bind generic driver: %d\n", __func__, ret);
free(str);
--
2.18.0
More information about the U-Boot
mailing list