]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/core/lists.c
dm: simplify the loop in lists_driver_lookup_name()
[karo-tx-uboot.git] / drivers / core / lists.c
index 205b140ef3d7c9d367df75f94ad62c1510454197..3a1ea8565449699a39ba5684dbecfbf71e30780b 100644 (file)
 #include <errno.h>
 #include <dm/device.h>
 #include <dm/device-internal.h>
+#include <dm/lists.h>
 #include <dm/platdata.h>
 #include <dm/uclass.h>
 #include <dm/util.h>
+#include <fdtdec.h>
 #include <linux/compiler.h>
 
 struct driver *lists_driver_lookup_name(const char *name)
@@ -22,19 +24,12 @@ struct driver *lists_driver_lookup_name(const char *name)
                ll_entry_start(struct driver, driver);
        const int n_ents = ll_entry_count(struct driver, driver);
        struct driver *entry;
-       int len;
 
        if (!drv || !n_ents)
                return NULL;
 
-       len = strlen(name);
-
        for (entry = drv; entry != drv + n_ents; entry++) {
-               if (strncmp(name, entry->name, len))
-                       continue;
-
-               /* Full match */
-               if (len == strlen(entry->name))
+               if (!strcmp(name, entry->name))
                        return entry;
        }
 
@@ -60,7 +55,7 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
        return NULL;
 }
 
-int lists_bind_drivers(struct udevice *parent)
+int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
 {
        struct driver_info *info =
                ll_entry_start(struct driver_info, driver_info);
@@ -71,8 +66,8 @@ int lists_bind_drivers(struct udevice *parent)
        int ret;
 
        for (entry = info; entry != info + n_ents; entry++) {
-               ret = device_bind_by_name(parent, entry, &dev);
-               if (ret) {
+               ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev);
+               if (ret && ret != -EPERM) {
                        dm_warn("No match for driver '%s'\n", entry->name);
                        if (!result || ret != -ENOENT)
                                result = ret;
@@ -94,7 +89,7 @@ int lists_bind_drivers(struct udevice *parent)
  * tree error
  */
 static int driver_check_compatible(const void *blob, int offset,
-                                  const struct device_id *of_match)
+                                  const struct udevice_id *of_match)
 {
        int ret;
 
@@ -116,22 +111,28 @@ static int driver_check_compatible(const void *blob, int offset,
        return -ENOENT;
 }
 
-int lists_bind_fdt(struct udevice *parent, const void *blob, int offset)
+int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
+                  struct udevice **devp)
 {
        struct driver *driver = ll_entry_start(struct driver, driver);
        const int n_ents = ll_entry_count(struct driver, driver);
        struct driver *entry;
        struct udevice *dev;
+       bool found = false;
        const char *name;
        int result = 0;
-       int ret;
+       int ret = 0;
 
        dm_dbg("bind node %s\n", fdt_get_name(blob, offset, NULL));
+       if (devp)
+               *devp = NULL;
        for (entry = driver; entry != driver + n_ents; entry++) {
                ret = driver_check_compatible(blob, offset, entry->of_match);
+               name = fdt_get_name(blob, offset, NULL);
                if (ret == -ENOENT) {
                        continue;
                } else if (ret == -ENODEV) {
+                       dm_dbg("Device '%s' has no compatible string\n", name);
                        break;
                } else if (ret) {
                        dm_warn("Device tree error at offset %d\n", offset);
@@ -140,14 +141,22 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset)
                        break;
                }
 
-               name = fdt_get_name(blob, offset, NULL);
                dm_dbg("   - found match at '%s'\n", entry->name);
                ret = device_bind(parent, entry, name, NULL, offset, &dev);
                if (ret) {
-                       dm_warn("No match for driver '%s'\n", entry->name);
-                       if (!result || ret != -ENOENT)
-                               result = ret;
+                       dm_warn("Error binding driver '%s'\n", entry->name);
+                       return ret;
+               } else {
+                       found = true;
+                       if (devp)
+                               *devp = dev;
                }
+               break;
+       }
+
+       if (!found && !result && ret != -ENODEV) {
+               dm_dbg("No match for node '%s'\n",
+                      fdt_get_name(blob, offset, NULL));
        }
 
        return result;