X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fcore%2Flists.c;h=647e390bfe6743984c6d47fd14a9cd8882795c86;hb=52e6935774afa45121df6a712c17f91f8f6c4f99;hp=5f1c85fd6e41353aa9866369e50eed674e06c6f3;hpb=00606d7e39da4a8ecfbbc19d5af252bdfdd1fcc9;p=oweals%2Fu-boot.git diff --git a/drivers/core/lists.c b/drivers/core/lists.c index 5f1c85fd6e..647e390bfe 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -24,19 +24,9 @@ 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; } @@ -51,9 +41,6 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id) const int n_ents = ll_entry_count(struct uclass_driver, uclass); struct uclass_driver *entry; - if ((id == UCLASS_INVALID) || !uclass) - return NULL; - for (entry = uclass; entry != uclass + n_ents; entry++) { if (entry->id == id) return entry; @@ -84,72 +71,114 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) return result; } +int device_bind_driver(struct udevice *parent, const char *drv_name, + const char *dev_name, struct udevice **devp) +{ + struct driver *drv; + int ret; + + drv = lists_driver_lookup_name(drv_name); + if (!drv) { + printf("Cannot find driver '%s'\n", drv_name); + return -ENOENT; + } + ret = device_bind(parent, drv, dev_name, NULL, -1, devp); + if (ret) { + printf("Cannot create device named '%s' (err=%d)\n", + dev_name, ret); + return ret; + } + + return 0; +} + #ifdef CONFIG_OF_CONTROL /** * driver_check_compatible() - Check if a driver is compatible with this node * * @param blob: Device tree pointer * @param offset: Offset of node in device tree - * @param of_matchL List of compatible strings to match + * @param of_match: List of compatible strings to match + * @param of_idp: Returns the match that was found * @return 0 if there is a match, -ENOENT if no match, -ENODEV if the node * does not have a compatible string, other error <0 if there is a device * tree error */ static int driver_check_compatible(const void *blob, int offset, - const struct udevice_id *of_match) + const struct udevice_id *of_match, + const struct udevice_id **of_idp) { int ret; + *of_idp = NULL; if (!of_match) return -ENOENT; while (of_match->compatible) { ret = fdt_node_check_compatible(blob, offset, of_match->compatible); - if (!ret) + if (!ret) { + *of_idp = of_match; return 0; - else if (ret == -FDT_ERR_NOTFOUND) + } else if (ret == -FDT_ERR_NOTFOUND) { return -ENODEV; - else if (ret < 0) + } else if (ret < 0) { return -EINVAL; + } of_match++; } 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); + const struct udevice_id *id; 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); + ret = driver_check_compatible(blob, offset, entry->of_match, + &id); + 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); - if (!result || ret != -ENOENT) - result = ret; + result = ret; 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 { + dev->driver_data = id->data; + 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;