From: Masahiro Yamada Date: Sat, 25 Jul 2015 12:52:37 +0000 (+0900) Subject: devres: make Devres optional with CONFIG_DEVRES X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=e2282d70763ddf06f9b02007445729c841ef4083;p=u-boot.git devres: make Devres optional with CONFIG_DEVRES 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 Suggested-by: Simon Glass Acked-by: Simon Glass --- diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index a002d69d79..8ae0072aa9 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -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 diff --git a/drivers/core/Makefile b/drivers/core/Makefile index 260833e8ee..ccc2fd4e21 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -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 diff --git a/drivers/core/device.c b/drivers/core/device.c index e3a42dc928..caaf231921 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -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; diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index a2bf0579ff..2cd2fe91d8 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -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 diff --git a/include/dm/device.h b/include/dm/device.h index c474f2dabb..53773a8f9d 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -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