diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 345b3d5080d3..bf5d577e5292 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -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); diff --git a/include/linux/firmware.h b/include/linux/firmware.h index bb31b5ad09f7..7a49a0976f06 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -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; }