summaryrefslogtreecommitdiff
path: root/drivers/base/dma-mapping.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/dma-mapping.c')
-rw-r--r--drivers/base/dma-mapping.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index d95c5971c225..016f6f5f1e5e 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -309,7 +309,12 @@ void *dma_common_contiguous_remap(struct page *page, size_t size,
void *ptr;
unsigned long pfn;
- pages = kmalloc(sizeof(struct page *) << get_order(size), GFP_KERNEL);
+ pages = kmalloc(sizeof(struct page *) << get_order(size),
+ GFP_KERNEL | __GFP_NOWARN);
+
+ if (!pages)
+ pages = vmalloc(sizeof(struct page *) << get_order(size));
+
if (!pages)
return NULL;
@@ -318,20 +323,24 @@ void *dma_common_contiguous_remap(struct page *page, size_t size,
ptr = dma_common_pages_remap(pages, size, vm_flags, prot, caller);
- kfree(pages);
+ kvfree(pages);
return ptr;
}
/*
+ area->pages = pages;
+
* unmaps a range previously mapped by dma_common_*_remap
*/
-void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
+void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags,
+ bool no_warn)
{
struct vm_struct *area = find_vm_area(cpu_addr);
if (!area || (area->flags & vm_flags) != vm_flags) {
- WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
+ WARN(!no_warn, "trying to free invalid coherent area: %p\n",
+ cpu_addr);
return;
}