diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index f0493028fc75226a62f15683bb99f2ba9964820b..5f61235439e054d9155418a3dc236922a53eac69 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -128,8 +128,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;
struct page **pages;
@@ -159,8 +160,9 @@ struct fw_desc {
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 module *module;
void *context;
void (*cont)(const struct firmware *fw, void *context);
@@ -327,14 +329,14 @@ static bool 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)
return false;
if (kernel_read(file, 0, buf, size) != size) {
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 false;
@@ -342,7 +344,7 @@ static bool 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 true;
}
@@ -693,7 +695,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;
@@ -706,7 +709,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;
@@ -1103,6 +1106,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;
}
@@ -1265,8 +1269,10 @@ request_firmware(const struct firmware **firmware_p, const char *name,
int
request_firmware_direct(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;
@@ -1287,6 +1293,7 @@ request_firmware_direct(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)
@@ -1331,8 +1338,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;
@@ -1356,6 +1364,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;
if (!try_module_get(module)) {
kfree(desc);
@@ -1400,7 +1409,7 @@ request_firmware_nowait(
{
return _request_firmware_nowait(module, uevent, name, device, gfp,
- context, cont, false, 0, 0, NULL, NULL);
+ context, cont, false, 0, 0, NULL, NULL, NULL);
}
/**
@@ -1419,12 +1428,14 @@ request_firmware_nowait_direct(
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);
}
/**
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index 6e6f50cfc53264e0f435b154fac64490d3bad4ee..3590ffca61984454cc33e797b74f488b20ad9f7a 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -531,12 +531,12 @@ static void pil_release_mmap(struct pil_desc *desc)
#define IOMAP_SIZE SZ_1M
-static void *map_fw_mem(phys_addr_t paddr, size_t size)
+static void *map_fw_mem(phys_addr_t paddr, size_t size, void *data)
{
return ioremap(paddr, size);
}
-static void unmap_fw_mem(void *vaddr)
+static void unmap_fw_mem(void *vaddr, void *data)
{
iounmap(vaddr);
}
@@ -553,7 +553,7 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
desc->name, num);
ret = request_firmware_direct(fw_name, desc->dev, seg->paddr,
seg->filesz, desc->map_fw_mem,
- desc->unmap_fw_mem);
+ desc->unmap_fw_mem, NULL);
if (ret < 0) {
pil_err(desc, "Failed to locate blob %s or blob is too big.\n",
fw_name);
diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h
index 4dc198128bb4f58cce0828b5a4758e378780aae9..0a50ef5aefc1dcb9f92c4245590ef9482641da7e 100644
--- a/drivers/soc/qcom/peripheral-loader.h
+++ b/drivers/soc/qcom/peripheral-loader.h
@@ -42,8 +42,8 @@ struct pil_desc {
#define PIL_SKIP_ENTRY_CHECK BIT(0)
struct pil_priv *priv;
unsigned int proxy_unvote_irq;
- 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);
};
/**
diff --git a/drivers/soc/qcom/pil-femto-modem.c b/drivers/soc/qcom/pil-femto-modem.c
index e2bea490f16837b461f4984203a9dc065bf58714..579cc20eb6acf18bb039a8f2b013d5c492b1ef7c 100644
--- a/drivers/soc/qcom/pil-femto-modem.c
+++ b/drivers/soc/qcom/pil-femto-modem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -122,7 +122,7 @@ struct femto_modem_data {
#define POLL_INTERVAL_US 50
#define TIMEOUT_US 1000000
-static void *pil_femto_modem_map_fw_mem(phys_addr_t paddr, size_t size)
+static void *pil_femto_modem_map_fw_mem(phys_addr_t paddr, size_t size, void *d)
{
/* Due to certain memory areas on the platform requiring 32-bit wide
* accesses, we must cache the firmware to avoid bus errors.
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index ddca055c712a4ebafea0d70302262227a599b995..89b23a831ce70518445aad9c1331ba557c6b84e6 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -48,15 +48,16 @@ int request_firmware_nowait(
int request_firmware_direct(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_direct(
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);
int cache_firmware(const char *name);
int uncache_firmware(const char *name);
@@ -72,8 +73,9 @@ static inline int request_firmware_direct(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)
{
return -EINVAL;
}
@@ -89,8 +91,8 @@ static inline int request_firmware_nowait_direct(
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;
}