[U-Boot] [PATCH 12/22] dm: core: Add a method to find a driver for a livetree node
Simon Glass
sjg at chromium.org
Wed Jan 18 06:51:48 CET 2017
We already have a means to locate drivers for flat device tree nodes. Add
a separate method for the live tree.
TODO: Refactor this to avoid code duplication.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
drivers/core/lists.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/dm/lists.h | 5 ++++
2 files changed, 81 insertions(+)
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 72c55e205f9..b9bfbf5cc86 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -12,6 +12,7 @@
#include <dm/device.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
+#include <dm/of_access.h>
#include <dm/platdata.h>
#include <dm/uclass.h>
#include <dm/util.h>
@@ -199,4 +200,79 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
return result;
}
+
+#ifdef CONFIG_OF_LIVE
+/*
+ * TODO(sjg at chromium.org): Perhaps we can use np_to_offset(np)() to merge this
+ * function with lists_bind_fdt()
+ */
+int lists_bind_node(struct udevice *parent, struct device_node *np,
+ struct udevice **devp)
+{
+ struct driver *driver = ll_entry_start(struct driver, driver);
+ const int n_ents = ll_entry_count(struct driver, driver);
+ const struct udevice_id *id;
+ struct driver *entry;
+ struct udevice *dev;
+ bool found = false;
+ const struct property *compat_prop;
+ const char *compat;
+ int compat_length, i;
+ int result = 0;
+ int ret = 0;
+
+ if (devp)
+ *devp = NULL;
+ dm_dbg("bind node %s\n", np->name);
+
+ compat_prop = of_find_property(np, "compatible", &compat_length);
+ if (!compat_prop) {
+ dm_dbg("Device '%s' has no compatible string\n", np->name);
+ return 0;
+ }
+
+ /*
+ * Walk through the compatible string list, attempting to match each
+ * compatible string in order such that we match in order of priority
+ * from the first string to the last.
+ */
+ for (i = 0; i < compat_prop->length; i += strlen(compat) + 1) {
+ compat = compat_prop->value + i;
+ dm_dbg(" - attempt to match compatible string '%s'\n",
+ compat);
+
+ for (entry = driver; entry != driver + n_ents; entry++) {
+ ret = driver_check_compatible(entry->of_match, &id,
+ compat);
+ if (!ret)
+ break;
+ }
+ if (entry == driver + n_ents)
+ continue;
+
+ dm_dbg(" - found match at '%s'\n", entry->name);
+ ret = device_bind_node_with_driver_data(parent, entry, np->name,
+ id->data, np, &dev);
+ if (ret == -ENODEV) {
+ dm_dbg("Driver '%s' refuses to bind\n", entry->name);
+ continue;
+ }
+ if (ret) {
+ dm_warn("Error binding driver '%s': %d\n", entry->name,
+ ret);
+ return ret;
+ } else {
+ found = true;
+ if (devp)
+ *devp = dev;
+ }
+ break;
+ }
+
+ if (!found && !result && ret != -ENODEV)
+ dm_dbg("No match for node '%s'\n", np->name);
+
+ return result;
+}
+#endif /* CONFIG_OF_LIVE */
#endif
diff --git a/include/dm/lists.h b/include/dm/lists.h
index 4513d6a311a..2ca7079bc86 100644
--- a/include/dm/lists.h
+++ b/include/dm/lists.h
@@ -12,6 +12,8 @@
#include <dm/uclass-id.h>
+struct device_node;
+
/**
* lists_driver_lookup_name() - Return u_boot_driver corresponding to name
*
@@ -60,6 +62,9 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only);
int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
struct udevice **devp);
+int lists_bind_node(struct udevice *parent, struct device_node *np,
+ struct udevice **devp);
+
/**
* device_bind_driver() - bind a device to a driver
*
--
2.11.0.483.g087da7b7c-goog
More information about the U-Boot
mailing list