struct device_d has some dynamically allocated members, namely .name and .unique_name. These are normally not freed when a device is freed. Add two functions to free these resources. free_device_res() only frees the allocated members, but not the device itself. This is suitable for cases where the device is embedded in another struct. free_device() frees the allocated members along with the device itself. This can be called when the device itself has been directly allocated. Some users which should use these functions are also fixed in this patch. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- drivers/base/driver.c | 30 ++++++++++++++++++++++++++++++ drivers/of/base.c | 2 +- drivers/of/platform.c | 3 ++- drivers/usb/core/usb.c | 1 + include/driver.h | 4 ++++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/base/driver.c b/drivers/base/driver.c index f54f4d0b37..2347b5c71f 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -270,6 +270,36 @@ int unregister_device(struct device_d *old_dev) } EXPORT_SYMBOL(unregister_device); +/** + * free_device_res - free dynamically allocated device members + * @dev: The device + * + * This frees dynamically allocated resources allocated during device + * lifetime, but not the device itself. + */ +void free_device_res(struct device_d *dev) +{ + free(dev->name); + dev->name = NULL; + free(dev->unique_name); + dev->unique_name = NULL; +} +EXPORT_SYMBOL(free_device_res); + +/** + * free_device - free a device + * @dev: The device + * + * This frees dynamically allocated resources allocated during device + * lifetime and finally the device itself. + */ +void free_device(struct device_d *dev) +{ + free_device_res(dev); + free(dev); +} +EXPORT_SYMBOL(free_device); + /* * Loop over list of deferred devices as long as at least one * device is successfully probed. Devices that again request diff --git a/drivers/of/base.c b/drivers/of/base.c index 80465d6d50..2591610c3f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2383,7 +2383,7 @@ static void of_platform_device_create_root(struct device_node *np) ret = platform_device_register(dev); if (ret) - free(dev); + free_device(dev); } static const struct of_device_id reserved_mem_matches[] = { diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 3a82809cb3..0e718469db 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -155,7 +155,7 @@ struct device_d *of_platform_device_create(struct device_node *np, np->dev = NULL; - free(dev); + free_device(dev); if (num_reg) free(res); return NULL; @@ -278,6 +278,7 @@ static struct device_d *of_amba_device_create(struct device_node *np) return &dev->dev; amba_err_free: + free_device_res(&dev->dev); free(dev); return NULL; } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4eede13a11..34a0f004f7 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -534,6 +534,7 @@ void usb_free_device(struct usb_device *usbdev) { dma_free(usbdev->descriptor); dma_free(usbdev->setup_packet); + free_device_res(&usbdev->dev); free(usbdev); } diff --git a/include/driver.h b/include/driver.h index 4f97b943c8..93de4f676e 100644 --- a/include/driver.h +++ b/include/driver.h @@ -141,6 +141,10 @@ void device_detect_all(void); */ int unregister_device(struct device_d *); +void free_device_res(struct device_d *dev); +void free_device(struct device_d *dev); + + /* Iterate over a devices children */ #define device_for_each_child(dev, child) \ -- 2.30.2 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox