firmware_class: Allow private data in [unmap|map]_fw_mem

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>
This commit is contained in:
Vikram Mulukutla 2014-04-10 20:23:30 -07:00 committed by David Keitel
parent 53adc478c8
commit 9c0b572b23
2 changed files with 39 additions and 25 deletions

View file

@ -146,8 +146,9 @@ struct firmware_buf {
size_t size; size_t size;
phys_addr_t dest_addr; phys_addr_t dest_addr;
size_t dest_size; size_t dest_size;
void * (*map_fw_mem)(phys_addr_t phys, size_t size); void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
void (*unmap_fw_mem)(void *virt); void (*unmap_fw_mem)(void *virt, void *data);
void *map_data;
#ifdef CONFIG_FW_LOADER_USER_HELPER #ifdef CONFIG_FW_LOADER_USER_HELPER
bool is_paged_buf; bool is_paged_buf;
bool need_uevent; bool need_uevent;
@ -177,8 +178,9 @@ struct fw_desc {
unsigned int opt_flags; unsigned int opt_flags;
phys_addr_t dest_addr; phys_addr_t dest_addr;
size_t dest_size; size_t dest_size;
void * (*map_fw_mem)(phys_addr_t phys, size_t size); void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
void (*unmap_fw_mem)(void *virt); void (*unmap_fw_mem)(void *virt, void *data);
void *map_data;
struct module *module; struct module *module;
void *context; void *context;
void (*cont)(const struct firmware *fw, 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) if (fw_buf->dest_addr)
buf = fw_buf->map_fw_mem(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 else
buf = vmalloc(size); buf = vmalloc(size);
if (!buf) 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->data = buf;
fw_buf->size = size; fw_buf->size = size;
if (fw_buf->dest_addr) if (fw_buf->dest_addr)
fw_buf->unmap_fw_mem(buf); fw_buf->unmap_fw_mem(buf, fw_buf->map_data);
return 0; return 0;
fail: fail:
if (fw_buf->dest_addr) if (fw_buf->dest_addr)
fw_buf->unmap_fw_mem(buf); fw_buf->unmap_fw_mem(buf, fw_buf->map_data);
else else
vfree(buf); vfree(buf);
return rc; return rc;
@ -770,7 +772,8 @@ static int __firmware_data_rw(struct firmware_priv *fw_priv, char *buffer,
goto out; 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) { if (!fw_buf) {
pr_debug("%s: Failed ioremap.\n", __func__); pr_debug("%s: Failed ioremap.\n", __func__);
retval = -ENOMEM; retval = -ENOMEM;
@ -783,7 +786,7 @@ static int __firmware_data_rw(struct firmware_priv *fw_priv, char *buffer,
memcpy(fw_buf, buffer, count); memcpy(fw_buf, buffer, count);
*offset += count; *offset += count;
buf->unmap_fw_mem(fw_buf); buf->unmap_fw_mem(fw_buf, buf->map_data);
out: out:
return retval; return retval;
@ -1213,6 +1216,7 @@ _request_firmware_prepare(struct firmware **firmware_p, struct fw_desc *desc)
buf->dest_size = desc->dest_size; buf->dest_size = desc->dest_size;
buf->map_fw_mem = desc->map_fw_mem; buf->map_fw_mem = desc->map_fw_mem;
buf->unmap_fw_mem = desc->unmap_fw_mem; buf->unmap_fw_mem = desc->unmap_fw_mem;
buf->map_data = desc->map_data;
firmware->priv = buf; firmware->priv = buf;
return 1; return 1;
} }
@ -1430,8 +1434,10 @@ EXPORT_SYMBOL_GPL(request_firmware_direct);
int int
request_firmware_into_buf(const char *name, struct device *device, request_firmware_into_buf(const char *name, struct device *device,
phys_addr_t dest_addr, size_t dest_size, phys_addr_t dest_addr, size_t dest_size,
void * (*map_fw_mem)(phys_addr_t phys, size_t size), void * (*map_fw_mem)(phys_addr_t phys, size_t size,
void (*unmap_fw_mem)(void *virt)) void *data),
void (*unmap_fw_mem)(void *virt, void *data),
void *map_data)
{ {
struct fw_desc desc; struct fw_desc desc;
const struct firmware *fp = NULL; 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.dest_size = dest_size;
desc.map_fw_mem = map_fw_mem; desc.map_fw_mem = map_fw_mem;
desc.unmap_fw_mem = unmap_fw_mem; desc.unmap_fw_mem = unmap_fw_mem;
desc.map_data = map_data;
ret = _request_firmware(&desc); ret = _request_firmware(&desc);
if (ret) if (ret)
@ -1496,8 +1503,9 @@ _request_firmware_nowait(
const char *name, struct device *device, gfp_t gfp, void *context, const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context), void (*cont)(const struct firmware *fw, void *context),
bool nocache, phys_addr_t dest_addr, size_t dest_size, bool nocache, phys_addr_t dest_addr, size_t dest_size,
void * (*map_fw_mem)(phys_addr_t phys, size_t size), void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
void (*unmap_fw_mem)(void *virt)) void (*unmap_fw_mem)(void *virt, void *data),
void *map_data)
{ {
struct fw_desc *desc; struct fw_desc *desc;
@ -1519,6 +1527,7 @@ _request_firmware_nowait(
desc->dest_size = dest_size; desc->dest_size = dest_size;
desc->map_fw_mem = map_fw_mem; desc->map_fw_mem = map_fw_mem;
desc->unmap_fw_mem = unmap_fw_mem; desc->unmap_fw_mem = unmap_fw_mem;
desc->map_data = map_data;
desc->opt_flags = FW_OPT_FALLBACK | FW_OPT_NOWAIT; desc->opt_flags = FW_OPT_FALLBACK | FW_OPT_NOWAIT;
if (uevent) if (uevent)
@ -1569,7 +1578,7 @@ request_firmware_nowait(
void (*cont)(const struct firmware *fw, void *context)) void (*cont)(const struct firmware *fw, void *context))
{ {
return _request_firmware_nowait(module, uevent, name, device, gfp, 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); 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, const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context), void (*cont)(const struct firmware *fw, void *context),
phys_addr_t dest_addr, size_t dest_size, phys_addr_t dest_addr, size_t dest_size,
void * (*map_fw_mem)(phys_addr_t phys, size_t size), void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
void (*unmap_fw_mem)(void *virt)) void (*unmap_fw_mem)(void *virt, void *data),
void *map_data)
{ {
return _request_firmware_nowait(module, uevent, name, device, gfp, return _request_firmware_nowait(module, uevent, name, device, gfp,
context, cont, true, dest_addr, 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); EXPORT_SYMBOL_GPL(request_firmware_nowait_into_buf);

View 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, int request_firmware_into_buf(const char *name, struct device *device,
phys_addr_t dest_addr, size_t dest_size, phys_addr_t dest_addr, size_t dest_size,
void * (*map_fw_mem)(phys_addr_t phys, void * (*map_fw_mem)(phys_addr_t phys,
size_t size), size_t size, void *data),
void (*unmap_fw_mem)(void *virt)); void (*unmap_fw_mem)(void *virt, void *data),
void *data);
int request_firmware_nowait_into_buf( int request_firmware_nowait_into_buf(
struct module *module, bool uevent, struct module *module, bool uevent,
const char *name, struct device *device, gfp_t gfp, void *context, const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context), void (*cont)(const struct firmware *fw, void *context),
phys_addr_t dest_addr, size_t dest_size, phys_addr_t dest_addr, size_t dest_size,
void * (*map_fw_mem)(phys_addr_t phys, size_t size), void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
void (*unmap_fw_mem)(void *virt)); void (*unmap_fw_mem)(void *virt, void *data), void *data);
void release_firmware(const struct firmware *fw); void release_firmware(const struct firmware *fw);
#else #else
static inline int request_firmware(const struct firmware **fw, 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, phys_addr_t dest_addr,
size_t dest_size, size_t dest_size,
void * (*map_fw_mem)(phys_addr_t phys, void * (*map_fw_mem)(phys_addr_t phys,
size_t size), size_t size, void *data),
void (*unmap_fw_mem)(void *virt)) void (*unmap_fw_mem)(void *virt,
void *data),
void *data)
{ {
return -EINVAL; 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, const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context), void (*cont)(const struct firmware *fw, void *context),
phys_addr_t dest_addr, size_t dest_size, phys_addr_t dest_addr, size_t dest_size,
void * (*map_fw_mem)(phys_addr_t phys, size_t size), void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data),
void (*unmap_fw_mem)(void *virt)) void (*unmap_fw_mem)(void *virt, void *data), void *data)
{ {
return -EINVAL; return -EINVAL;
} }