From a2040facd23b88082b9b40f0aa9bcfd495eab88e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:23 -0600 Subject: dm: core: Allow device names to be freed automatically Some devices have a name that is stored in allocated memory. At present there is no mechanism to free this memory when the device is unbound. Add a device flag to track whether a name is allocated and a function to add the flag. Free the memory when the device is unbound. Signed-off-by: Simon Glass --- drivers/core/device-remove.c | 2 ++ drivers/core/device.c | 6 ++++++ include/dm/device.h | 16 ++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index e1714b2202b..0e56b23fbbf 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -112,6 +112,8 @@ int device_unbind(struct udevice *dev) devres_release_all(dev); + if (dev->flags & DM_NAME_ALLOCED) + free((char *)dev->name); free(dev); return 0; diff --git a/drivers/core/device.c b/drivers/core/device.c index 2b12ce7835f..5c2dc7021fb 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -706,12 +706,18 @@ bool device_is_last_sibling(struct udevice *dev) return list_is_last(&dev->sibling_node, &parent->child_head); } +void device_set_name_alloced(struct udevice *dev) +{ + dev->flags |= DM_NAME_ALLOCED; +} + int device_set_name(struct udevice *dev, const char *name) { name = strdup(name); if (!name) return -ENOMEM; dev->name = name; + device_set_name_alloced(dev); return 0; } diff --git a/include/dm/device.h b/include/dm/device.h index 8970fc015c7..e9a8ec72c90 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -41,6 +41,9 @@ struct driver_info; /* Device is bound */ #define DM_FLAG_BOUND (1 << 6) +/* Device name is allocated and should be freed on unbind() */ +#define DM_NAME_ALLOCED (1 << 7) + /** * struct udevice - An instance of a driver * @@ -523,6 +526,9 @@ bool device_is_last_sibling(struct udevice *dev); * this is unnecessary but for probed devices which don't get a useful name * this function can be helpful. * + * The name is allocated and will be freed automatically when the device is + * unbound. + * * @dev: Device to update * @name: New name (this string is allocated new memory and attached to * the device) @@ -531,6 +537,16 @@ bool device_is_last_sibling(struct udevice *dev); */ int device_set_name(struct udevice *dev, const char *name); +/** + * device_set_name_alloced() - note that a device name is allocated + * + * This sets the DM_NAME_ALLOCED flag for the device, so that when it is + * unbound the name will be freed. This avoids memory leaks. + * + * @dev: Device to update + */ +void device_set_name_alloced(struct udevice *dev); + /** * device_is_on_pci_bus - Test if a device is on a PCI bus * -- cgit v1.2.3