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:
parent
53adc478c8
commit
9c0b572b23
2 changed files with 39 additions and 25 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue