|
@@ -380,7 +380,8 @@ void persistent_ram_zap(struct persistent_ram_zone *prz)
|
|
|
persistent_ram_update_header_ecc(prz);
|
|
|
}
|
|
|
|
|
|
-static void *persistent_ram_vmap(phys_addr_t start, size_t size)
|
|
|
+static void *persistent_ram_vmap(phys_addr_t start, size_t size,
|
|
|
+ unsigned int memtype)
|
|
|
{
|
|
|
struct page **pages;
|
|
|
phys_addr_t page_start;
|
|
@@ -392,7 +393,10 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size)
|
|
|
page_start = start - offset_in_page(start);
|
|
|
page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE);
|
|
|
|
|
|
- prot = pgprot_noncached(PAGE_KERNEL);
|
|
|
+ if (memtype)
|
|
|
+ prot = pgprot_noncached(PAGE_KERNEL);
|
|
|
+ else
|
|
|
+ prot = pgprot_writecombine(PAGE_KERNEL);
|
|
|
|
|
|
pages = kmalloc_array(page_count, sizeof(struct page *), GFP_KERNEL);
|
|
|
if (!pages) {
|
|
@@ -411,8 +415,11 @@ 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)
|
|
|
+static void *persistent_ram_iomap(phys_addr_t start, size_t size,
|
|
|
+ unsigned int memtype)
|
|
|
{
|
|
|
+ void *va;
|
|
|
+
|
|
|
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);
|
|
@@ -422,19 +429,24 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size)
|
|
|
buffer_start_add = buffer_start_add_locked;
|
|
|
buffer_size_add = buffer_size_add_locked;
|
|
|
|
|
|
- return ioremap(start, size);
|
|
|
+ if (memtype)
|
|
|
+ va = ioremap(start, size);
|
|
|
+ else
|
|
|
+ va = ioremap_wc(start, size);
|
|
|
+
|
|
|
+ return va;
|
|
|
}
|
|
|
|
|
|
static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
|
|
|
- struct persistent_ram_zone *prz)
|
|
|
+ struct persistent_ram_zone *prz, int memtype)
|
|
|
{
|
|
|
prz->paddr = start;
|
|
|
prz->size = size;
|
|
|
|
|
|
if (pfn_valid(start >> PAGE_SHIFT))
|
|
|
- prz->vaddr = persistent_ram_vmap(start, size);
|
|
|
+ prz->vaddr = persistent_ram_vmap(start, size, memtype);
|
|
|
else
|
|
|
- prz->vaddr = persistent_ram_iomap(start, size);
|
|
|
+ prz->vaddr = persistent_ram_iomap(start, size, memtype);
|
|
|
|
|
|
if (!prz->vaddr) {
|
|
|
pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__,
|
|
@@ -500,7 +512,8 @@ void persistent_ram_free(struct persistent_ram_zone *prz)
|
|
|
}
|
|
|
|
|
|
struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
|
|
- u32 sig, struct persistent_ram_ecc_info *ecc_info)
|
|
|
+ u32 sig, struct persistent_ram_ecc_info *ecc_info,
|
|
|
+ unsigned int memtype)
|
|
|
{
|
|
|
struct persistent_ram_zone *prz;
|
|
|
int ret = -ENOMEM;
|
|
@@ -511,7 +524,7 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
|
|
|
goto err;
|
|
|
}
|
|
|
|
|
|
- ret = persistent_ram_buffer_map(start, size, prz);
|
|
|
+ ret = persistent_ram_buffer_map(start, size, prz, memtype);
|
|
|
if (ret)
|
|
|
goto err;
|
|
|
|