
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