dm: core: Allow finding children / uclasses by partial name

In some cases it is useful to search just by a partial name, such as
when looking for a sibling device that has a common name substring. Add
helper functions to handle these requirements.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/drivers/core/device.c b/drivers/core/device.c
index efd0717..aed093c 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -902,15 +902,16 @@
 	return -ENODEV;
 }
 
-int device_find_child_by_name(const struct udevice *parent, const char *name,
-			      struct udevice **devp)
+int device_find_child_by_namelen(const struct udevice *parent, const char *name,
+				 int len, struct udevice **devp)
 {
 	struct udevice *dev;
 
 	*devp = NULL;
 
 	list_for_each_entry(dev, &parent->child_head, sibling_node) {
-		if (!strcmp(dev->name, name)) {
+		if (!strncmp(dev->name, name, len) &&
+		    strlen(dev->name) == len) {
 			*devp = dev;
 			return 0;
 		}
@@ -919,6 +920,12 @@
 	return -ENODEV;
 }
 
+int device_find_child_by_name(const struct udevice *parent, const char *name,
+			      struct udevice **devp)
+{
+	return device_find_child_by_namelen(parent, name, strlen(name), devp);
+}
+
 int device_first_child_err(struct udevice *parent, struct udevice **devp)
 {
 	struct udevice *dev;
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 2fede89..3de5f27 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -180,20 +180,25 @@
 	uc->priv_ = priv;
 }
 
-enum uclass_id uclass_get_by_name(const char *name)
+enum uclass_id uclass_get_by_name_len(const char *name, int len)
 {
 	int i;
 
 	for (i = 0; i < UCLASS_COUNT; i++) {
 		struct uclass_driver *uc_drv = lists_uclass_lookup(i);
 
-		if (uc_drv && !strcmp(uc_drv->name, name))
+		if (uc_drv && !strncmp(uc_drv->name, name, len))
 			return i;
 	}
 
 	return UCLASS_INVALID;
 }
 
+enum uclass_id uclass_get_by_name(const char *name)
+{
+	return uclass_get_by_name_len(name, strlen(name));
+}
+
 int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp)
 {
 	struct udevice *iter;
diff --git a/include/dm/device.h b/include/dm/device.h
index 3028d00..daf28a0 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -763,6 +763,18 @@
  *
  * @parent:	Parent device to search
  * @name:	Name to look for
+ * @len:	Length of the name
+ * @devp:	Returns device found, if any
+ * @return 0 if found, else -ENODEV
+ */
+int device_find_child_by_namelen(const struct udevice *parent, const char *name,
+				 int len, struct udevice **devp);
+
+/**
+ * device_find_child_by_name() - Find a child by device name
+ *
+ * @parent:	Parent device to search
+ * @name:	Name to look for
  * @devp:	Returns device found, if any
  * @return 0 if found, else -ENODEV
  */
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index 15e5f9e..aea2f34 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -176,6 +176,15 @@
  * uclass_get_by_name() - Look up a uclass by its driver name
  *
  * @name: Name to look up
+ * @len: Length of name
+ * @returns the associated uclass ID, or UCLASS_INVALID if not found
+ */
+enum uclass_id uclass_get_by_name_len(const char *name, int len);
+
+/**
+ * uclass_get_by_name() - Look up a uclass by its driver name
+ *
+ * @name: Name to look up
  * @returns the associated uclass ID, or UCLASS_INVALID if not found
  */
 enum uclass_id uclass_get_by_name(const char *name);