remoteproc: Keep local copy of firmware name
authorMatt Redfearn <matt.redfearn@imgtec.com>
Mon, 17 Oct 2016 15:48:58 +0000 (16:48 +0100)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Tue, 18 Oct 2016 22:03:35 +0000 (15:03 -0700)
Storage of the firmware name was inconsistent, either storing a pointer
to a name stored with unknown ownership, or a variable length tacked
onto the end of the struct proc allocated in rproc_alloc.

In preparation for allowing the firmware of an already allocated struct
rproc to be changed, instead always keep a locally maintained copy of
the firmware name.

Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/remoteproc/remoteproc_core.c
include/linux/remoteproc.h

index c6bfb3496684efde7dc55d777e392445490db585..ccc2a73e94dd99197ca9bc7bf11cfe2be5f99300 100644 (file)
@@ -1273,6 +1273,7 @@ static void rproc_type_release(struct device *dev)
        if (rproc->index >= 0)
                ida_simple_remove(&rproc_dev_index, rproc->index);
 
+       kfree(rproc->firmware);
        kfree(rproc);
 }
 
@@ -1310,31 +1311,31 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
 {
        struct rproc *rproc;
        char *p, *template = "rproc-%s-fw";
-       int name_len = 0;
+       int name_len;
 
        if (!dev || !name || !ops)
                return NULL;
 
-       if (!firmware)
+       if (!firmware) {
                /*
-                * Make room for default firmware name (minus %s plus '\0').
                 * If the caller didn't pass in a firmware name then
-                * construct a default name.  We're already glomming 'len'
-                * bytes onto the end of the struct rproc allocation, so do
-                * a few more for the default firmware name (but only if
-                * the caller doesn't pass one).
+                * construct a default name.
                 */
                name_len = strlen(name) + strlen(template) - 2 + 1;
-
-       rproc = kzalloc(sizeof(*rproc) + len + name_len, GFP_KERNEL);
-       if (!rproc)
-               return NULL;
-
-       if (!firmware) {
-               p = (char *)rproc + sizeof(struct rproc) + len;
+               p = kmalloc(name_len, GFP_KERNEL);
+               if (!p)
+                       return NULL;
                snprintf(p, name_len, template, name);
        } else {
-               p = (char *)firmware;
+               p = kstrdup(firmware, GFP_KERNEL);
+               if (!p)
+                       return NULL;
+       }
+
+       rproc = kzalloc(sizeof(struct rproc) + len, GFP_KERNEL);
+       if (!rproc) {
+               kfree(p);
+               return NULL;
        }
 
        rproc->firmware = p;
index 930023b7c825f6f69f72da95ec18279290c0ebf7..940e4cf2ac487b27db57dfad6be3d130f94962c2 100644 (file)
@@ -415,7 +415,7 @@ struct rproc {
        struct list_head node;
        struct iommu_domain *domain;
        const char *name;
-       const char *firmware;
+       char *firmware;
        void *priv;
        const struct rproc_ops *ops;
        struct device dev;