doc: replace @return by Return:
[platform/kernel/u-boot.git] / drivers / core / uclass.c
index e845f60..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>
@@ -33,7 +34,7 @@ struct uclass *uclass_find(enum uclass_id key)
         * node to the start of the list, or creating a linear array mapping
         * id to node.
         */
-       list_for_each_entry(uc, &gd->uclass_root, sibling_node) {
+       list_for_each_entry(uc, gd->uclass_root, sibling_node) {
                if (uc->uc_drv->id == key)
                        return uc;
        }
@@ -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.
@@ -84,7 +85,7 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp)
        uc->uc_drv = uc_drv;
        INIT_LIST_HEAD(&uc->sibling_node);
        INIT_LIST_HEAD(&uc->dev_head);
-       list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);
+       list_add(&uc->sibling_node, DM_UCLASS_ROOT_NON_CONST);
 
        if (uc_drv->init) {
                ret = uc_drv->init(uc);
@@ -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;
@@ -165,28 +172,33 @@ const char *uclass_get_name(enum uclass_id id)
 
 void *uclass_get_priv(const struct uclass *uc)
 {
-       return uc->priv;
+       return uc->priv_;
 }
 
 void uclass_set_priv(struct uclass *uc, void *priv)
 {
-       uc->priv = 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;
@@ -297,8 +309,8 @@ int uclass_find_next_free_seq(struct uclass *uc)
 
        /* Avoid conflict with existing devices */
        list_for_each_entry(dev, &uc->dev_head, uclass_node) {
-               if (dev->sqq > max)
-                       max = dev->sqq;
+               if (dev->seq_ > max)
+                       max = dev->seq_;
        }
        /*
         * At this point, max will be -1 if there are no existing aliases or
@@ -323,8 +335,8 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq, struct udevice **devp)
                return ret;
 
        uclass_foreach_dev(dev, uc) {
-               log_debug("   - %d '%s'\n", dev->sqq, dev->name);
-               if (dev->sqq == seq) {
+               log_debug("   - %d '%s'\n", dev->seq_, dev->name);
+               if (dev->seq_ == seq) {
                        *devp = dev;
                        log_debug("   - found\n");
                        return 0;
@@ -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
@@ -757,6 +788,37 @@ int uclass_pre_remove_device(struct udevice *dev)
 }
 #endif
 
+int uclass_probe_all(enum uclass_id id)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = uclass_first_device(id, &dev);
+       if (ret || !dev)
+               return ret;
+
+       /* Scanning uclass to probe all devices */
+       while (dev) {
+               ret = uclass_next_device(&dev);
+               if (ret)
+                       return ret;
+       }
+
+       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",