devres: make Devres optional with CONFIG_DEVRES
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Sat, 25 Jul 2015 12:52:37 +0000 (21:52 +0900)
committerSimon Glass <sjg@chromium.org>
Thu, 6 Aug 2015 13:44:29 +0000 (07:44 -0600)
Currently, Devres requires additional 16 byte for each allocation,
which is not so insignificant in some cases.

Add CONFIG_DEVRES to make this framework optional.
If the option is disabled, devres functions fall back to
non-managed variants.  For example, devres_alloc() to kzalloc(),
devm_kmalloc() to kmalloc(), etc.

Because devres_head is also surrounded by an ifdef conditional,
there is no memory overhead when CONFIG_DEVRES is disabled.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Suggested-by: Simon Glass <sjg@chromium.org>
Acked-by: Simon Glass <sjg@chromium.org>
drivers/core/Kconfig
drivers/core/Makefile
drivers/core/device.c
include/dm/device-internal.h
include/dm/device.h

index a002d69d79da54aa7381a8014cd6cf3e96d5d25a..8ae0072aa90166f89f742bb4d2438d97bb72aa8f 100644 (file)
@@ -79,9 +79,22 @@ config SYSCON
          by this uclass, including accessing registers via regmap and
          assigning a unique number to each.
 
+config DEVRES
+       bool "Managed device resources"
+       depends on DM
+       help
+         This option enables the Managed device resources core support.
+         Device resources managed by the devres framework are automatically
+         released whether initialization fails half-way or the device gets
+         detached.
+
+         If this option is disabled, devres functions fall back to
+         non-managed variants.  For example, devres_alloc() to kzalloc(),
+         devm_kmalloc() to kmalloc(), etc.
+
 config DEBUG_DEVRES
        bool "Managed device resources verbose debug messages"
-       depends on DM
+       depends on DEVRES
        help
          If this option is enabled, devres debug messages are printed.
          Select this if you are having a problem with devres or want to
index 260833e8ee859df7b8452701f88ba44073dc5779..ccc2fd4e21ae1f9ab53fd3c181e06007f5e7d8c5 100644 (file)
@@ -4,7 +4,8 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y  += device.o lists.o root.o uclass.o util.o devres.o
+obj-y  += device.o lists.o root.o uclass.o util.o
+obj-$(CONFIG_DEVRES) += devres.o
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_OF_CONTROL) += simple-bus.o
 endif
index e3a42dc928f0cc311863c3e356fd0cee5a870fb8..caaf2319214a58ca56387232d74c2bd3213bab7d 100644 (file)
@@ -47,7 +47,9 @@ int device_bind(struct udevice *parent, const struct driver *drv,
        INIT_LIST_HEAD(&dev->sibling_node);
        INIT_LIST_HEAD(&dev->child_head);
        INIT_LIST_HEAD(&dev->uclass_node);
+#ifdef CONFIG_DEVRES
        INIT_LIST_HEAD(&dev->devres_head);
+#endif
        dev->platdata = platdata;
        dev->name = name;
        dev->of_offset = of_offset;
index a2bf0579ff58188b745a00c312b34753e543bb9e..2cd2fe91d85f94cd2265ced8422c90d6f93e1a6f 100644 (file)
@@ -156,6 +156,8 @@ fdt_addr_t simple_bus_translate(struct udevice *dev, fdt_addr_t addr);
 #define DM_UCLASS_ROOT_NON_CONST       (((gd_t *)gd)->uclass_root)
 
 /* device resource management */
+#ifdef CONFIG_DEVRES
+
 /**
  * devres_release_probe - Release managed resources allocated after probing
  * @dev: Device to release resources for
@@ -174,4 +176,15 @@ void devres_release_probe(struct udevice *dev);
  */
 void devres_release_all(struct udevice *dev);
 
+#else /* ! CONFIG_DEVRES */
+
+static inline void devres_release_probe(struct udevice *dev)
+{
+}
+
+static inline void devres_release_all(struct udevice *dev)
+{
+}
+
+#endif /* ! CONFIG_DEVRES */
 #endif
index c474f2dabba3f35ae4f72ae8766799e5b43255d6..53773a8f9d9c9b1e7f83e03e9ee5b2ea96fa6c4b 100644 (file)
@@ -98,7 +98,9 @@ struct udevice {
        uint32_t flags;
        int req_seq;
        int seq;
+#ifdef CONFIG_DEVRES
        struct list_head devres_head;
+#endif
 };
 
 /* Maximum sequence number supported */
@@ -472,6 +474,8 @@ bool device_is_last_sibling(struct udevice *dev);
 typedef void (*dr_release_t)(struct udevice *dev, void *res);
 typedef int (*dr_match_t)(struct udevice *dev, void *res, void *match_data);
 
+#ifdef CONFIG_DEVRES
+
 #ifdef CONFIG_DEBUG_DEVRES
 void *__devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
                     const char *name);
@@ -648,5 +652,83 @@ static inline void *devm_kcalloc(struct udevice *dev,
  */
 void devm_kfree(struct udevice *dev, void *p);
 
+#else /* ! CONFIG_DEVRES */
+
+static inline void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
+{
+       return kzalloc(size, gfp);
+}
+
+static inline void devres_free(void *res)
+{
+       kfree(res);
+}
+
+static inline void devres_add(struct udevice *dev, void *res)
+{
+}
+
+static inline void *devres_find(struct udevice *dev, dr_release_t release,
+                               dr_match_t match, void *match_data)
+{
+       return NULL;
+}
+
+static inline void *devres_get(struct udevice *dev, void *new_res,
+                              dr_match_t match, void *match_data)
+{
+       return NULL;
+}
+
+static inline void *devres_remove(struct udevice *dev, dr_release_t release,
+                                 dr_match_t match, void *match_data)
+{
+       return NULL;
+}
+
+static inline int devres_destroy(struct udevice *dev, dr_release_t release,
+                                dr_match_t match, void *match_data)
+{
+       return 0;
+}
+
+static inline int devres_release(struct udevice *dev, dr_release_t release,
+                                dr_match_t match, void *match_data)
+{
+       return 0;
+}
+
+static inline void *devm_kmalloc(struct udevice *dev, size_t size, gfp_t gfp)
+{
+       return kmalloc(size, gfp);
+}
+
+static inline void *devm_kzalloc(struct udevice *dev, size_t size, gfp_t gfp)
+{
+       return kzalloc(size, gfp);
+}
+
+static inline void *devm_kmaloc_array(struct udevice *dev,
+                                     size_t n, size_t size, gfp_t flags)
+{
+       /* TODO: add kmalloc_array() to linux/compat.h */
+       if (size != 0 && n > SIZE_MAX / size)
+               return NULL;
+       return kmalloc(n * size, flags);
+}
+
+static inline void *devm_kcalloc(struct udevice *dev,
+                                size_t n, size_t size, gfp_t flags)
+{
+       /* TODO: add kcalloc() to linux/compat.h */
+       return kmalloc(n * size, flags | __GFP_ZERO);
+}
+
+static inline void devm_kfree(struct udevice *dev, void *p)
+{
+       kfree(p);
+}
+
+#endif /* ! CONFIG_DEVRES */
 
 #endif