[U-Boot] [PATCH v2 14/14] devres: compile Devres iif CONFIG_DM_DEVICE_REMOVE is enabled

Masahiro Yamada
2015-07-13T04:17:17Z

Currently, Devres requires additional 16 byte for each allocation,
which is not so insignificant for SPL in some cases.

If CONFIG_DM_DEVICE_REMOVE is disabled, we never remove devices,
so we do not have to manage resources in the first place.
In this case, devres_alloc() can fall back to the simple kzalloc(),
and likewise, devm_*() to non-managed variants.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Suggested-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

drivers/core/Makefile | 4 +--
include/dm/device-internal.h | 13 +++++++
include/dm/device.h | 84 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 5f019e8..37d64c6 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -4,8 +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
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_OF_CONTROL) += simple-bus.o
endif
-obj-$(CONFIG_DM_DEVICE_REMOVE) += device-remove.o
+obj-$(CONFIG_DM_DEVICE_REMOVE) += device-remove.o devres.o
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 409c687..2c8446e 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -118,6 +118,8 @@ static inline void device_free(struct udevice *dev) {}
#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root)

/* device resource management */
+#ifdef CONFIG_DM_DEVICE_REMOVE
+
/**
* devres_release_probe - Release managed resources allocated after probing
* @dev: Device to release resources for
@@ -136,4 +138,15 @@ void devres_release_probe(struct udevice *dev);
*/
void devres_release_all(struct udevice *dev);

+#else /* !CONFIG_DM_DEVICE_REMOVE */
+
+static inline void devres_release_probe(struct udevice *dev)
+{
+}
+
+static inline void devres_release_all(struct udevice *dev)
+{
+}
+
+#endif /* CONFIG_DM_DEVICE_REMOVE */
#endif
diff --git a/include/dm/device.h b/include/dm/device.h
index 1a832a7..33dc470 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -447,6 +447,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_DM_DEVICE_REMOVE
+
#ifdef CONFIG_DEBUG_DEVRES
void *__devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
const char *name);
@@ -623,5 +625,87 @@ static inline void *devm_kcalloc(struct udevice *dev,
*/
void devm_kfree(struct udevice *dev, void *p);

+#else /* !CONFIG_DM_DEVICE_REMOVE */
+
+/*
+ * If CONFIG_DM_DEVICE_REMOVE is not defined, we need not manage resources.
+ * The devres functions fall back to normal allocators.
+ */
+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_DM_DEVICE_REMOVE */

#endif
--
1.9.1