diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 5f61235439e054d9155418a3dc236922a53eac69..584e9a2bfdecd89cc86aa2898d099abeee1e4fd9 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -129,7 +129,7 @@ struct firmware_buf {
 	phys_addr_t dest_addr;
 	size_t dest_size;
 	void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
-	void (*unmap_fw_mem)(void *virt, void *data);
+	void (*unmap_fw_mem)(void *virt, size_t size, void *data);
 	void *map_data;
 #ifdef CONFIG_FW_LOADER_USER_HELPER
 	bool is_paged_buf;
@@ -161,7 +161,7 @@ struct fw_desc {
 	phys_addr_t dest_addr;
 	size_t dest_size;
 	void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
-	void (*unmap_fw_mem)(void *virt, void *data);
+	void (*unmap_fw_mem)(void *virt, size_t size, void *data);
 	void *map_data;
 	struct module *module;
 	void *context;
@@ -336,7 +336,8 @@ static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf
 		return false;
 	if (kernel_read(file, 0, buf, size) != size) {
 		if (fw_buf->dest_addr)
-			fw_buf->unmap_fw_mem(buf, fw_buf->map_data);
+			fw_buf->unmap_fw_mem(buf, fw_buf->dest_size,
+							fw_buf->map_data);
 		else
 			vfree(buf);
 		return false;
@@ -344,7 +345,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->map_data);
+		fw_buf->unmap_fw_mem(buf, fw_buf->size, fw_buf->map_data);
 	return true;
 }
 
@@ -709,7 +710,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->map_data);
+	buf->unmap_fw_mem(fw_buf, count, buf->map_data);
 
 out:
 	return retval;
@@ -1271,7 +1272,8 @@ 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 *data),
-			void (*unmap_fw_mem)(void *virt, void *data),
+			void (*unmap_fw_mem)(void *virt, size_t size,
+						void *data),
 			void *map_data)
 {
 	struct fw_desc desc;
@@ -1339,7 +1341,7 @@ _request_firmware_nowait(
 	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 *data),
-	void (*unmap_fw_mem)(void *virt, void *data),
+	void (*unmap_fw_mem)(void *virt, size_t size, void *data),
 	void *map_data)
 {
 	struct fw_desc *desc;
@@ -1429,7 +1431,7 @@ request_firmware_nowait_direct(
 	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 *data),
-	void (*unmap_fw_mem)(void *virt, void *data),
+	void (*unmap_fw_mem)(void *virt, size_t size, void *data),
 	void *map_data)
 {
 	return _request_firmware_nowait(module, uevent, name, device, gfp,
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index b9853300cb472a67c5ff2df4cea4cbeb20f054e8..06fcccfdd3c159b471f47800afa512be5713a4ed 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -363,7 +363,6 @@ static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
 	void *region;
 	size_t size = max_addr - min_addr;
 	size_t aligned_size;
-	DEFINE_DMA_ATTRS(attrs);
 
 	/* Don't reallocate due to fragmentation concerns, just sanity check */
 	if (priv->region) {
@@ -378,9 +377,12 @@ static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
 	else
 		aligned_size = ALIGN(size, SZ_1M);
 
-	dma_set_attr(DMA_ATTR_SKIP_ZEROING, &attrs);
+	dma_set_attr(DMA_ATTR_SKIP_ZEROING, &priv->desc->attrs);
+	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &priv->desc->attrs);
+
 	region = dma_alloc_attrs(priv->desc->dev, aligned_size,
-				&priv->region_start, GFP_KERNEL, &attrs);
+				&priv->region_start, GFP_KERNEL,
+				&priv->desc->attrs);
 
 	if (region == NULL) {
 		pil_err(priv->desc, "Failed to allocate relocatable region of size %zx\n",
@@ -523,29 +525,25 @@ static void pil_release_mmap(struct pil_desc *desc)
 #define IOMAP_SIZE SZ_1M
 
 struct pil_map_fw_info {
-	int relocated;
 	void *region;
+	struct dma_attrs attrs;
 	phys_addr_t base_addr;
+	struct device *dev;
 };
 
 static void *map_fw_mem(phys_addr_t paddr, size_t size, void *data)
 {
 	struct pil_map_fw_info *info = data;
 
-	if (info && info->relocated && info->region)
-		return info->region + (paddr - info->base_addr);
-
-	return ioremap(paddr, size);
+	return dma_remap(info->dev, info->region, paddr, size,
+					&info->attrs);
 }
 
-static void unmap_fw_mem(void *vaddr, void *data)
+static void unmap_fw_mem(void *vaddr, size_t size, void *data)
 {
 	struct pil_map_fw_info *info = data;
 
-	if (info && info->relocated && info->region)
-		return;
-
-	iounmap(vaddr);
+	dma_unremap(info->dev, vaddr, size);
 }
 
 static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
@@ -555,9 +553,10 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
 	char fw_name[30];
 	int num = seg->num;
 	struct pil_map_fw_info map_fw_info = {
-		.relocated = seg->relocated,
+		.attrs = desc->attrs,
 		.region = desc->priv->region,
 		.base_addr = desc->priv->region_start,
+		.dev = desc->dev,
 	};
 	void *map_data = desc->map_data ? desc->map_data : &map_fw_info;
 
@@ -612,7 +611,7 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
 
 		memset(buf, 0, size);
 
-		desc->unmap_fw_mem(buf, map_data);
+		desc->unmap_fw_mem(buf, size, map_data);
 
 		count -= orig_size;
 		paddr += orig_size;
@@ -714,6 +713,8 @@ int pil_boot(struct pil_desc *desc)
 		goto release_fw;
 	}
 
+	init_dma_attrs(&desc->attrs);
+
 	ret = pil_init_mmap(desc, mdt);
 	if (ret)
 		goto release_fw;
@@ -765,8 +766,9 @@ out:
 	up_read(&pil_pm_rwsem);
 	if (ret) {
 		if (priv->region) {
-			dma_free_coherent(desc->dev, priv->region_size,
-					priv->region, priv->region_start);
+			dma_free_attrs(desc->dev, priv->region_size,
+					priv->region, priv->region_start,
+					&desc->attrs);
 			priv->region = NULL;
 		}
 		pil_release_mmap(desc);
@@ -796,8 +798,8 @@ void pil_shutdown(struct pil_desc *desc)
 		flush_delayed_work(&priv->proxy);
 
 	if (priv->region) {
-		dma_free_coherent(desc->dev, priv->region_size,
-				priv->region, priv->region_start);
+		dma_free_attrs(desc->dev, priv->region_size,
+				priv->region, priv->region_start, &desc->attrs);
 		priv->region = NULL;
 	}
 }
diff --git a/drivers/soc/qcom/peripheral-loader.h b/drivers/soc/qcom/peripheral-loader.h
index 68b3659e14b3f750aa5cb63087fadac8f9e8993f..9cb791fc32ef1de1a4d96d674083706405650059 100644
--- a/drivers/soc/qcom/peripheral-loader.h
+++ b/drivers/soc/qcom/peripheral-loader.h
@@ -12,6 +12,8 @@
 #ifndef __MSM_PERIPHERAL_LOADER_H
 #define __MSM_PERIPHERAL_LOADER_H
 
+#include <linux/dma-attrs.h>
+
 struct device;
 struct module;
 struct pil_priv;
@@ -25,6 +27,7 @@ struct pil_priv;
  * @proxy_timeout: delay in ms until proxy vote is removed
  * @flags: bitfield for image flags
  * @priv: DON'T USE - internal only
+ * @attrs: DMA attributes to be used during dma allocation.
  * @proxy_unvote_irq: IRQ to trigger a proxy unvote. proxy_timeout
  * is ignored if this is set.
  * @map_fw_mem: Custom function used to map physical address space to virtual.
@@ -41,9 +44,10 @@ struct pil_desc {
 	unsigned long flags;
 #define PIL_SKIP_ENTRY_CHECK	BIT(0)
 	struct pil_priv *priv;
+	struct dma_attrs attrs;
 	unsigned int proxy_unvote_irq;
 	void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
-	void (*unmap_fw_mem)(void *virt, void *data);
+	void (*unmap_fw_mem)(void *virt, size_t size, void *data);
 	void *map_data;
 };
 
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index 89b23a831ce70518445aad9c1331ba557c6b84e6..56672339c6cf4af2a6c13b7a5161fe619bac35b7 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -49,7 +49,8 @@ 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 *data),
-			    void (*unmap_fw_mem)(void *virt, void *data),
+			    void (*unmap_fw_mem)(void *virt, size_t size,
+							void *data),
 			    void *data);
 int request_firmware_nowait_direct(
 	struct module *module, bool uevent,
@@ -57,7 +58,7 @@ int request_firmware_nowait_direct(
 	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 *data),
-	void (*unmap_fw_mem)(void *virt, void *data), void *data);
+	void (*unmap_fw_mem)(void *virt, size_t size, void *data), void *data);
 void release_firmware(const struct firmware *fw);
 int cache_firmware(const char *name);
 int uncache_firmware(const char *name);