imagemap_create() names every device it binds by index "imagemap", so two mappings taken on one block device appear as two identically named children and the device tree does not say which partition each covers. The name also comes straight from the caller, whose string has to outlive the device for the driver-model pointer to stay valid.
Derive the name from the partition, by name where one was given and by index otherwise, and hand driver model an allocated copy it releases on unbind. Reviewed-by: Simon Glass <[email protected]> Signed-off-by: Daniel Golle <[email protected]> --- v3: No changes since v2. v2: - The named path no longer copies the caller's name through a fixed-size buffer, which truncated it at 31 characters; the name is duplicated directly and the buffer is only used for the "imagemap%d" index spelling. boot/imagemap.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/boot/imagemap.c b/boot/imagemap.c index 0a156e010ec..d46c1430fb7 100644 --- a/boot/imagemap.c +++ b/boot/imagemap.c @@ -11,6 +11,7 @@ #include <dm.h> #include <imagemap.h> #include <lmb.h> +#include <malloc.h> #include <mapmem.h> #include <memalign.h> #include <part.h> @@ -442,6 +443,9 @@ int imagemap_create(struct udevice *dev, const char *name, struct imagemap_plat *plat; struct disk_partition info; struct udevice *imdev; + char buf[32]; + char *devname; + const char *base; int ret; if (name && *name) @@ -451,10 +455,28 @@ int imagemap_create(struct udevice *dev, const char *name, if (ret < 0) return ret; - ret = device_bind_driver(desc->bdev, "imagemap", - name && *name ? name : "imagemap", &imdev); - if (ret) + /* + * Name the device after the partition it covers, so that two mappings + * on one block device stay distinct in the device tree. + */ + if (name && *name) { + base = name; + } else { + snprintf(buf, sizeof(buf), "imagemap%d", part); + base = buf; + } + + /* device_bind_driver() keeps the pointer, so hand it one DM can own */ + devname = strdup(base); + if (!devname) + return -ENOMEM; + + ret = device_bind_driver(desc->bdev, "imagemap", devname, &imdev); + if (ret) { + free(devname); return ret; + } + device_set_name_alloced(imdev); plat = dev_get_plat(imdev); plat->part_start = info.start; -- 2.56.0
