pmem: add support for reusable pmem

Individual pmem devices can now be marked as reusable. The
memory will be reused through fmem.

Change-Id: Id71c2e0c42f093420c241771d7a2620ed2accfc4
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c
index 8d9a375..7ee7c11 100644
--- a/drivers/misc/pmem.c
+++ b/drivers/misc/pmem.c
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/fs.h>
 #include <linux/file.h>
+#include <linux/fmem.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <linux/debugfs.h>
@@ -243,6 +244,10 @@
 	 * map and unmap as needed
 	 */
 	int map_on_demand;
+	/*
+	 * memory will be reused through fmem
+	 */
+	int reusable;
 };
 #define to_pmem_info_id(a) (container_of(a, struct pmem_info, kobj)->id)
 
@@ -2793,19 +2798,26 @@
 	pr_info("allocating %lu bytes at %p (%lx physical) for %s\n",
 		pmem[id].size, pmem[id].vbase, pmem[id].base, pmem[id].name);
 
-	pmem[id].map_on_demand = pdata->map_on_demand;
+	pmem[id].reusable = pdata->reusable;
+	/* reusable pmem requires map on demand */
+	pmem[id].map_on_demand = pdata->map_on_demand || pdata->reusable;
 	if (pmem[id].map_on_demand) {
-		pmem_vma = get_vm_area(pmem[id].size, VM_IOREMAP);
-		if (!pmem_vma) {
-			pr_err("pmem: Failed to allocate virtual space for "
+		if (pmem[id].reusable) {
+			const struct fmem_data *fmem_info = fmem_get_info();
+			pmem[id].area = fmem_info->area;
+		} else {
+			pmem_vma = get_vm_area(pmem[id].size, VM_IOREMAP);
+			if (!pmem_vma) {
+				pr_err("pmem: Failed to allocate virtual space for "
 					"%s\n", pdata->name);
-			goto out_put_kobj;
-		}
-		pr_err("pmem: Reserving virtual address range %lx - %lx for"
+				goto out_put_kobj;
+			}
+			pr_err("pmem: Reserving virtual address range %lx - %lx for"
 				" %s\n", (unsigned long) pmem_vma->addr,
 				(unsigned long) pmem_vma->addr + pmem[id].size,
 				pdata->name);
-		pmem[id].area = pmem_vma;
+			pmem[id].area = pmem_vma;
+		}
 	} else
 		pmem[id].area = NULL;
 
diff --git a/include/linux/android_pmem.h b/include/linux/android_pmem.h
index 3c4dd79..ab96379 100644
--- a/include/linux/android_pmem.h
+++ b/include/linux/android_pmem.h
@@ -171,6 +171,10 @@
 	 * indicates that this region should be mapped/unmaped as needed
 	 */
 	int map_on_demand;
+	/*
+	 * indicates this pmem may be reused via fmem
+	 */
+	int reusable;
 };
 
 int pmem_setup(struct android_pmem_platform_data *pdata,