For SPL we don't expect to need to remove a device. Save some code space
by dropping this feature. The board config can define
CONFIG_DM_DEVICE_REMOVE if this is in fact needed.

Signed-off-by: Simon Glass <s...@chromium.org>
---

 drivers/core/Makefile        |   3 +-
 drivers/core/device-remove.c | 187 +++++++++++++++++++++++++++++++++++++++++++
 drivers/core/device.c        | 168 --------------------------------------
 include/config_defaults.h    |   4 +
 include/dm/device-internal.h |  10 +++
 5 files changed, 203 insertions(+), 169 deletions(-)
 create mode 100644 drivers/core/device-remove.c

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 90b2a7f..8fbaba3 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -4,4 +4,5 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_DM)       := device.o lists.o root.o uclass.o util.o
+obj-$(CONFIG_DM)       += device.o lists.o root.o uclass.o util.o
+obj-$(CONFIG_DM_DEVICE_REMOVE) += device-remove.o
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
new file mode 100644
index 0000000..8fc6b71
--- /dev/null
+++ b/drivers/core/device-remove.c
@@ -0,0 +1,187 @@
+/*
+ * Device manager
+ *
+ * Copyright (c) 2014 Google, Inc
+ *
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.i...@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <malloc.h>
+#include <dm/device.h>
+#include <dm/device-internal.h>
+#include <dm/uclass.h>
+#include <dm/uclass-internal.h>
+#include <dm/util.h>
+
+/**
+ * device_chld_unbind() - Unbind all device's children from the device
+ *
+ * On error, the function continues to unbind all children, and reports the
+ * first error.
+ *
+ * @dev:       The device that is to be stripped of its children
+ * @return 0 on success, -ve on error
+ */
+static int device_chld_unbind(struct udevice *dev)
+{
+       struct udevice *pos, *n;
+       int ret, saved_ret = 0;
+
+       assert(dev);
+
+       list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
+               ret = device_unbind(pos);
+               if (ret && !saved_ret)
+                       saved_ret = ret;
+       }
+
+       return saved_ret;
+}
+
+/**
+ * device_chld_remove() - Stop all device's children
+ * @dev:       The device whose children are to be removed
+ * @return 0 on success, -ve on error
+ */
+static int device_chld_remove(struct udevice *dev)
+{
+       struct udevice *pos, *n;
+       int ret;
+
+       assert(dev);
+
+       list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
+               ret = device_remove(pos);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int device_unbind(struct udevice *dev)
+{
+       struct driver *drv;
+       int ret;
+
+       if (!dev)
+               return -EINVAL;
+
+       if (dev->flags & DM_FLAG_ACTIVATED)
+               return -EINVAL;
+
+       drv = dev->driver;
+       assert(drv);
+
+       if (drv->unbind) {
+               ret = drv->unbind(dev);
+               if (ret)
+                       return ret;
+       }
+
+       ret = device_chld_unbind(dev);
+       if (ret)
+               return ret;
+
+       ret = uclass_unbind_device(dev);
+       if (ret)
+               return ret;
+
+       if (dev->parent)
+               list_del(&dev->sibling_node);
+       free(dev);
+
+       return 0;
+}
+
+/**
+ * device_free() - Free memory buffers allocated by a device
+ * @dev:       Device that is to be started
+ */
+void device_free(struct udevice *dev)
+{
+       int size;
+
+       if (dev->driver->priv_auto_alloc_size) {
+               free(dev->priv);
+               dev->priv = NULL;
+       }
+       if (dev->flags & DM_FLAG_ALLOC_PDATA) {
+               free(dev->platdata);
+               dev->platdata = NULL;
+       }
+       size = dev->uclass->uc_drv->per_device_auto_alloc_size;
+       if (size) {
+               free(dev->uclass_priv);
+               dev->uclass_priv = NULL;
+       }
+       if (dev->parent) {
+               size = dev->parent->driver->per_child_auto_alloc_size;
+               if (size) {
+                       free(dev->parent_priv);
+                       dev->parent_priv = NULL;
+               }
+       }
+}
+
+int device_remove(struct udevice *dev)
+{
+       struct driver *drv;
+       int ret;
+
+       if (!dev)
+               return -EINVAL;
+
+       if (!(dev->flags & DM_FLAG_ACTIVATED))
+               return 0;
+
+       drv = dev->driver;
+       assert(drv);
+
+       ret = uclass_pre_remove_device(dev);
+       if (ret)
+               return ret;
+
+       ret = device_chld_remove(dev);
+       if (ret)
+               goto err;
+
+       if (drv->remove) {
+               ret = drv->remove(dev);
+               if (ret)
+                       goto err_remove;
+       }
+
+       if (dev->parent && dev->parent->driver->child_post_remove) {
+               ret = dev->parent->driver->child_post_remove(dev);
+               if (ret) {
+                       dm_warn("%s: Device '%s' failed child_post_remove()",
+                               __func__, dev->name);
+               }
+       }
+
+       device_free(dev);
+
+       dev->seq = -1;
+       dev->flags &= ~DM_FLAG_ACTIVATED;
+
+       return ret;
+
+err_remove:
+       /* We can't put the children back */
+       dm_warn("%s: Device '%s' failed to remove, but children are gone\n",
+               __func__, dev->name);
+err:
+       ret = uclass_post_probe_device(dev);
+       if (ret) {
+               dm_warn("%s: Device '%s' failed to post_probe on error path\n",
+                       __func__, dev->name);
+       }
+
+       return ret;
+}
diff --git a/drivers/core/device.c b/drivers/core/device.c
index ef41a9b..2b2d819 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -24,52 +24,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/**
- * device_chld_unbind() - Unbind all device's children from the device
- *
- * On error, the function continues to unbind all children, and reports the
- * first error.
- *
- * @dev:       The device that is to be stripped of its children
- * @return 0 on success, -ve on error
- */
-static int device_chld_unbind(struct udevice *dev)
-{
-       struct udevice *pos, *n;
-       int ret, saved_ret = 0;
-
-       assert(dev);
-
-       list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
-               ret = device_unbind(pos);
-               if (ret && !saved_ret)
-                       saved_ret = ret;
-       }
-
-       return saved_ret;
-}
-
-/**
- * device_chld_remove() - Stop all device's children
- * @dev:       The device whose children are to be removed
- * @return 0 on success, -ve on error
- */
-static int device_chld_remove(struct udevice *dev)
-{
-       struct udevice *pos, *n;
-       int ret;
-
-       assert(dev);
-
-       list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
-               ret = device_remove(pos);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
 int device_bind(struct udevice *parent, struct driver *drv, const char *name,
                void *platdata, int of_offset, struct udevice **devp)
 {
@@ -165,71 +119,6 @@ int device_bind_by_name(struct udevice *parent, bool 
pre_reloc_only,
                           -1, devp);
 }
 
-int device_unbind(struct udevice *dev)
-{
-       struct driver *drv;
-       int ret;
-
-       if (!dev)
-               return -EINVAL;
-
-       if (dev->flags & DM_FLAG_ACTIVATED)
-               return -EINVAL;
-
-       drv = dev->driver;
-       assert(drv);
-
-       if (drv->unbind) {
-               ret = drv->unbind(dev);
-               if (ret)
-                       return ret;
-       }
-
-       ret = device_chld_unbind(dev);
-       if (ret)
-               return ret;
-
-       ret = uclass_unbind_device(dev);
-       if (ret)
-               return ret;
-
-       if (dev->parent)
-               list_del(&dev->sibling_node);
-       free(dev);
-
-       return 0;
-}
-
-/**
- * device_free() - Free memory buffers allocated by a device
- * @dev:       Device that is to be started
- */
-static void device_free(struct udevice *dev)
-{
-       int size;
-
-       if (dev->driver->priv_auto_alloc_size) {
-               free(dev->priv);
-               dev->priv = NULL;
-       }
-       if (dev->flags & DM_FLAG_ALLOC_PDATA) {
-               free(dev->platdata);
-               dev->platdata = NULL;
-       }
-       size = dev->uclass->uc_drv->per_device_auto_alloc_size;
-       if (size) {
-               free(dev->uclass_priv);
-               dev->uclass_priv = NULL;
-       }
-       if (dev->parent) {
-               size = dev->parent->driver->per_child_auto_alloc_size;
-               if (size) {
-                       free(dev->parent_priv);
-                       dev->parent_priv = NULL;
-               }
-       }
-}
-
 int device_probe(struct udevice *dev)
 {
        struct driver *drv;
@@ -333,63 +222,6 @@ fail:
        return ret;
 }
 
-int device_remove(struct udevice *dev)
-{
-       struct driver *drv;
-       int ret;
-
-       if (!dev)
-               return -EINVAL;
-
-       if (!(dev->flags & DM_FLAG_ACTIVATED))
-               return 0;
-
-       drv = dev->driver;
-       assert(drv);
-
-       ret = uclass_pre_remove_device(dev);
-       if (ret)
-               return ret;
-
-       ret = device_chld_remove(dev);
-       if (ret)
-               goto err;
-
-       if (drv->remove) {
-               ret = drv->remove(dev);
-               if (ret)
-                       goto err_remove;
-       }
-
-       if (dev->parent && dev->parent->driver->child_post_remove) {
-               ret = dev->parent->driver->child_post_remove(dev);
-               if (ret) {
-                       dm_warn("%s: Device '%s' failed child_post_remove()",
-                               __func__, dev->name);
-               }
-       }
-
-       device_free(dev);
-
-       dev->seq = -1;
-       dev->flags &= ~DM_FLAG_ACTIVATED;
-
-       return ret;
-
-err_remove:
-       /* We can't put the children back */
-       dm_warn("%s: Device '%s' failed to remove, but children are gone\n",
-               __func__, dev->name);
-err:
-       ret = uclass_post_probe_device(dev);
-       if (ret) {
-               dm_warn("%s: Device '%s' failed to post_probe on error path\n",
-                       __func__, dev->name);
-       }
-
-       return ret;
-}
-
 void *dev_get_platdata(struct udevice *dev)
 {
        if (!dev) {
diff --git a/include/config_defaults.h b/include/config_defaults.h
index ad08c1d..985f055 100644
--- a/include/config_defaults.h
+++ b/include/config_defaults.h
@@ -20,4 +20,8 @@
 #define CONFIG_ZLIB 1
 #define CONFIG_PARTITIONS 1
 
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_DM_DEVICE_REMOVE
+#endif
+
 #endif
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 7005d03..e58feac 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -74,7 +74,11 @@ int device_probe(struct udevice *dev);
  * @dev: Pointer to device to remove
  * @return 0 if OK, -ve on error (an error here is normally a very bad thing)
  */
+#ifdef CONFIG_DM_DEVICE_REMOVE
 int device_remove(struct udevice *dev);
+#else
+static inline int device_remove(struct udevice *dev) { return 0; }
+#endif
 
 /**
  * device_unbind() - Unbind a device, destroying it
@@ -86,6 +90,12 @@ int device_remove(struct udevice *dev);
  */
 int device_unbind(struct udevice *dev);
 
+#ifdef CONFIG_DM_DEVICE_REMOVE
+void device_free(struct udevice *dev);
+#else
+static inline void device_free(struct udevice *dev) {}
+#endif
+
 /* Cast away any volatile pointer */
 #define DM_ROOT_NON_CONST              (((gd_t *)gd)->dm_root)
 #define DM_UCLASS_ROOT_NON_CONST       (((gd_t *)gd)->uclass_root)
-- 
2.1.0.rc2.206.gedb03e5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to