staging: android: persistent_ram: Introduce persistent_ram_free()
[firefly-linux-kernel-4.4.55.git] / drivers / staging / android / persistent_ram.c
index ab8bff19dca0f18c54460970612b362add98d1b5..63481dad9b76acaa3a0246f9ec3e1b90cfb0a0f7 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/rslib.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <asm/page.h>
 #include "persistent_ram.h"
 
 struct persistent_ram_buffer {
@@ -349,10 +350,28 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size)
        return vaddr;
 }
 
+static void *persistent_ram_iomap(phys_addr_t start, size_t size)
+{
+       if (!request_mem_region(start, size, "persistent_ram")) {
+               pr_err("request mem region (0x%llx@0x%llx) failed\n",
+                       (unsigned long long)size, (unsigned long long)start);
+               return NULL;
+       }
+
+       return ioremap(start, size);
+}
+
 static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
                struct persistent_ram_zone *prz)
 {
-       prz->vaddr = persistent_ram_vmap(start, size);
+       prz->paddr = start;
+       prz->size = size;
+
+       if (pfn_valid(start >> PAGE_SHIFT))
+               prz->vaddr = persistent_ram_vmap(start, size);
+       else
+               prz->vaddr = persistent_ram_iomap(start, size);
+
        if (!prz->vaddr) {
                pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__,
                        (unsigned long long)size, (unsigned long long)start);
@@ -421,6 +440,18 @@ static int __init persistent_ram_post_init(struct persistent_ram_zone *prz, bool
        return 0;
 }
 
+void persistent_ram_free(struct persistent_ram_zone *prz)
+{
+       if (pfn_valid(prz->paddr >> PAGE_SHIFT)) {
+               vunmap(prz->vaddr);
+       } else {
+               iounmap(prz->vaddr);
+               release_mem_region(prz->paddr, prz->size);
+       }
+       persistent_ram_free_old(prz);
+       kfree(prz);
+}
+
 struct persistent_ram_zone * __init persistent_ram_new(phys_addr_t start,
                                                       size_t size,
                                                       bool ecc)