doc: replace @return by Return:
[platform/kernel/u-boot.git] / drivers / core / uclass.c
index f38122d..2578803 100644 (file)
@@ -13,6 +13,7 @@
 #include <errno.h>
 #include <log.h>
 #include <malloc.h>
+#include <asm/global_data.h>
 #include <dm/device.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
@@ -45,7 +46,7 @@ struct uclass *uclass_find(enum uclass_id key)
  * uclass_add() - Create new uclass in list
  * @id: Id number to create
  * @ucp: Returns pointer to uclass, or NULL on error
- * @return 0 on success, -ve on error
+ * Return: 0 on success, -ve on error
  *
  * The new uclass is added to the list. There must be only one uclass for
  * each id.
@@ -145,10 +146,16 @@ int uclass_get(enum uclass_id id, struct uclass **ucp)
 {
        struct uclass *uc;
 
+       /* Immediately fail if driver model is not set up */
+       if (!gd->uclass_root)
+               return -EDEADLK;
        *ucp = NULL;
        uc = uclass_find(id);
-       if (!uc)
+       if (!uc) {
+               if (CONFIG_IS_ENABLED(OF_PLATDATA_INST))
+                       return -ENOENT;
                return uclass_add(id, ucp);
+       }
        *ucp = uc;
 
        return 0;
@@ -173,20 +180,25 @@ void uclass_set_priv(struct uclass *uc, void *priv)
        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;
@@ -390,7 +402,7 @@ done:
        return ret;
 }
 
-#if CONFIG_IS_ENABLED(OF_CONTROL)
+#if CONFIG_IS_ENABLED(OF_REAL)
 int uclass_find_device_by_phandle(enum uclass_id id, struct udevice *parent,
                                  const char *name, struct udevice **devp)
 {
@@ -631,6 +643,19 @@ int uclass_next_device_check(struct udevice **devp)
        return device_probe(*devp);
 }
 
+int uclass_get_count(void)
+{
+       const struct uclass *uc;
+       int count = 0;
+
+       if (gd->dm_root) {
+               list_for_each_entry(uc, gd->uclass_root, sibling_node)
+                       count++;
+       }
+
+       return count;
+}
+
 int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
                                struct udevice **devp)
 {
@@ -675,7 +700,7 @@ err:
 }
 
 #if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
-int uclass_unbind_device(struct udevice *dev)
+int uclass_pre_unbind_device(struct udevice *dev)
 {
        struct uclass *uc;
        int ret;
@@ -687,7 +712,13 @@ int uclass_unbind_device(struct udevice *dev)
                        return ret;
        }
 
+       return 0;
+}
+
+int uclass_unbind_device(struct udevice *dev)
+{
        list_del(&dev->uclass_node);
+
        return 0;
 }
 #endif
@@ -776,6 +807,18 @@ int uclass_probe_all(enum uclass_id id)
        return 0;
 }
 
+int uclass_id_count(enum uclass_id id)
+{
+       struct udevice *dev;
+       struct uclass *uc;
+       int count = 0;
+
+       uclass_id_foreach_dev(id, dev, uc)
+               count++;
+
+       return count;
+}
+
 UCLASS_DRIVER(nop) = {
        .id             = UCLASS_NOP,
        .name           = "nop",