OSDN Git Service

firmware_class: Allow private data in [unmap|map]_fw_mem
authorVikram Mulukutla <markivx@codeaurora.org>
Fri, 11 Apr 2014 03:23:30 +0000 (20:23 -0700)
committerDavid Keitel <dkeitel@codeaurora.org>
Tue, 22 Mar 2016 18:07:36 +0000 (11:07 -0700)
Some callers of request_firmware_direct may need additional
context to be able to map firmware memory. Allow private data
to be passed in with request_firmware_direct, and send this
data along with the [unmap|map]_fw_mem callbacks.

Change-Id: I05a15eb46cc663a4476b784e30e80182a28e10c3
Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
[joshc: dropped PIL portions, fixed trivial conflict in firmware.h due
to API rename]
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
[vmulukut: adjusted for upstream merge conflicts]
Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
drivers/base/firmware_class.c
include/linux/firmware.h

index 345b3d5..bf5d577 100644 (file)
@@ -146,8 +146,9 @@ struct firmware_buf {
        size_t size;
        phys_addr_t dest_addr;
        size_t dest_size;
-       void * (*map_fw_mem)(phys_addr_t phys, size_t size);
-       void (*unmap_fw_mem)(void *virt);
+       void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
+       void (*unmap_fw_mem)(void *virt, void *data);
+       void *map_data;
 #ifdef CONFIG_FW_LOADER_USER_HELPER
        bool is_paged_buf;
        bool need_uevent;
@@ -177,8 +178,9 @@ struct fw_desc {
        unsigned int opt_flags;
        phys_addr_t dest_addr;
        size_t dest_size;
-       void * (*map_fw_mem)(phys_addr_t phys, size_t size);
-       void (*unmap_fw_mem)(void *virt);
+       void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
+       void (*unmap_fw_mem)(void *virt, void *data);
+       void *map_data;
        struct module *module;
        void *context;
        void (*cont)(const struct firmware *fw, void *context);
@@ -332,7 +334,7 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
 
        if (fw_buf->dest_addr)
                buf = fw_buf->map_fw_mem(fw_buf->dest_addr,
-                                          fw_buf->dest_size);
+                                          fw_buf->dest_size, fw_buf->map_data);
        else
                buf = vmalloc(size);
        if (!buf)
@@ -349,11 +351,11 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
        fw_buf->data = buf;
        fw_buf->size = size;
        if (fw_buf->dest_addr)
-               fw_buf->unmap_fw_mem(buf);
+               fw_buf->unmap_fw_mem(buf, fw_buf->map_data);
        return 0;
 fail:
        if (fw_buf->dest_addr)
-               fw_buf->unmap_fw_mem(buf);
+               fw_buf->unmap_fw_mem(buf, fw_buf->map_data);
        else
                vfree(buf);
        return rc;
@@ -770,7 +772,8 @@ static int __firmware_data_rw(struct firmware_priv *fw_priv, char *buffer,
                goto out;
        }
 
-       fw_buf = buf->map_fw_mem(buf->dest_addr + *offset, count);
+       fw_buf = buf->map_fw_mem(buf->dest_addr + *offset, count,
+                                       buf->map_data);
        if (!fw_buf) {
                pr_debug("%s: Failed ioremap.\n", __func__);
                retval = -ENOMEM;
@@ -783,7 +786,7 @@ static int __firmware_data_rw(struct firmware_priv *fw_priv, char *buffer,
                memcpy(fw_buf, buffer, count);
 
        *offset += count;
-       buf->unmap_fw_mem(fw_buf);
+       buf->unmap_fw_mem(fw_buf, buf->map_data);
 
 out:
        return retval;
@@ -1213,6 +1216,7 @@ _request_firmware_prepare(struct firmware **firmware_p, struct fw_desc *desc)
                buf->dest_size = desc->dest_size;
                buf->map_fw_mem = desc->map_fw_mem;
                buf->unmap_fw_mem = desc->unmap_fw_mem;
+               buf->map_data = desc->map_data;
                firmware->priv = buf;
                return 1;
        }
@@ -1430,8 +1434,10 @@ EXPORT_SYMBOL_GPL(request_firmware_direct);
 int
 request_firmware_into_buf(const char *name, struct device *device,
                        phys_addr_t dest_addr, size_t dest_size,
-                       void * (*map_fw_mem)(phys_addr_t phys, size_t size),
-                       void (*unmap_fw_mem)(void *virt))
+                       void * (*map_fw_mem)(phys_addr_t phys, size_t size,
+                                               void *data),
+                       void (*unmap_fw_mem)(void *virt, void *data),
+                       void *map_data)
 {
        struct fw_desc desc;
        const struct firmware *fp = NULL;
@@ -1450,6 +1456,7 @@ request_firmware_into_buf(const char *name, struct device *device,
        desc.dest_size = dest_size;
        desc.map_fw_mem = map_fw_mem;
        desc.unmap_fw_mem = unmap_fw_mem;
+       desc.map_data = map_data;
 
        ret = _request_firmware(&desc);
        if (ret)
@@ -1496,8 +1503,9 @@ _request_firmware_nowait(
        const char *name, struct device *device, gfp_t gfp, void *context,
        void (*cont)(const struct firmware *fw, void *context),
        bool nocache, phys_addr_t dest_addr, size_t dest_size,
-       void * (*map_fw_mem)(phys_addr_t phys, size_t size),
-       void (*unmap_fw_mem)(void *virt))
+       void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
+       void (*unmap_fw_mem)(void *virt, void *data),
+       void *map_data)
 {
        struct fw_desc *desc;
 
@@ -1519,6 +1527,7 @@ _request_firmware_nowait(
        desc->dest_size = dest_size;
        desc->map_fw_mem = map_fw_mem;
        desc->unmap_fw_mem = unmap_fw_mem;
+       desc->map_data = map_data;
        desc->opt_flags = FW_OPT_FALLBACK | FW_OPT_NOWAIT;
 
        if (uevent)
@@ -1569,7 +1578,7 @@ request_firmware_nowait(
        void (*cont)(const struct firmware *fw, void *context))
 {
        return _request_firmware_nowait(module, uevent, name, device, gfp,
-                                       context, cont, false, 0, 0, NULL, NULL);
+                               context, cont, false, 0, 0, NULL, NULL, NULL);
 }
 EXPORT_SYMBOL(request_firmware_nowait);
 
@@ -1589,12 +1598,14 @@ request_firmware_nowait_into_buf(
        const char *name, struct device *device, gfp_t gfp, void *context,
        void (*cont)(const struct firmware *fw, void *context),
        phys_addr_t dest_addr, size_t dest_size,
-       void * (*map_fw_mem)(phys_addr_t phys, size_t size),
-       void (*unmap_fw_mem)(void *virt))
+       void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
+       void (*unmap_fw_mem)(void *virt, void *data),
+       void *map_data)
 {
        return _request_firmware_nowait(module, uevent, name, device, gfp,
                                        context, cont, true, dest_addr,
-                                       dest_size, map_fw_mem, unmap_fw_mem);
+                                       dest_size, map_fw_mem, unmap_fw_mem,
+                                       map_data);
 }
 EXPORT_SYMBOL_GPL(request_firmware_nowait_into_buf);
 
index bb31b5a..7a49a09 100644 (file)
@@ -51,15 +51,16 @@ int request_firmware_direct(const struct firmware **fw, const char *name,
 int request_firmware_into_buf(const char *name, struct device *device,
                            phys_addr_t dest_addr, size_t dest_size,
                            void * (*map_fw_mem)(phys_addr_t phys,
-                                                size_t size),
-                           void (*unmap_fw_mem)(void *virt));
+                                                size_t size, void *data),
+                           void (*unmap_fw_mem)(void *virt, void *data),
+                           void *data);
 int request_firmware_nowait_into_buf(
        struct module *module, bool uevent,
        const char *name, struct device *device, gfp_t gfp, void *context,
        void (*cont)(const struct firmware *fw, void *context),
        phys_addr_t dest_addr, size_t dest_size,
-       void * (*map_fw_mem)(phys_addr_t phys, size_t size),
-       void (*unmap_fw_mem)(void *virt));
+       void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
+       void (*unmap_fw_mem)(void *virt, void *data), void *data);
 void release_firmware(const struct firmware *fw);
 #else
 static inline int request_firmware(const struct firmware **fw,
@@ -73,8 +74,10 @@ static inline int request_firmware_into_buf(const char *name,
                                          phys_addr_t dest_addr,
                                          size_t dest_size,
                                          void * (*map_fw_mem)(phys_addr_t phys,
-                                                              size_t size),
-                                         void (*unmap_fw_mem)(void *virt))
+                                                      size_t size, void *data),
+                                         void (*unmap_fw_mem)(void *virt,
+                                                              void *data),
+                                         void *data)
 {
        return -EINVAL;
 }
@@ -90,8 +93,8 @@ static inline int request_firmware_nowait_into_buf(
        const char *name, struct device *device, gfp_t gfp, void *context,
        void (*cont)(const struct firmware *fw, void *context),
        phys_addr_t dest_addr, size_t dest_size,
-       void * (*map_fw_mem)(phys_addr_t phys, size_t size),
-       void (*unmap_fw_mem)(void *virt))
+       void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
+       void (*unmap_fw_mem)(void *virt, void *data), void *data)
 {
        return -EINVAL;
 }