Commit a6933571 authored by Christoph Hellwig's avatar Christoph Hellwig

dma-mapping: simplify dma_init_coherent_memory

Return the allocated dma_coherent_mem structure, set the
use_dma_pfn_offset and print the failure warning inside of
dma_init_coherent_memory instead of leaving that to the callers.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Tested-by: default avatarDillon Min <dillon.minfei@gmail.com>
parent 70d6aa0e
...@@ -37,51 +37,44 @@ static inline dma_addr_t dma_get_device_base(struct device *dev, ...@@ -37,51 +37,44 @@ static inline dma_addr_t dma_get_device_base(struct device *dev,
return mem->device_base; return mem->device_base;
} }
static int dma_init_coherent_memory(phys_addr_t phys_addr, static struct dma_coherent_mem *dma_init_coherent_memory(phys_addr_t phys_addr,
dma_addr_t device_addr, size_t size, dma_addr_t device_addr, size_t size, bool use_dma_pfn_offset)
struct dma_coherent_mem **mem)
{ {
struct dma_coherent_mem *dma_mem = NULL; struct dma_coherent_mem *dma_mem;
void *mem_base = NULL;
int pages = size >> PAGE_SHIFT; int pages = size >> PAGE_SHIFT;
int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
int ret; void *mem_base;
if (!size) { if (!size)
ret = -EINVAL; return ERR_PTR(-EINVAL);
goto out;
}
mem_base = memremap(phys_addr, size, MEMREMAP_WC); mem_base = memremap(phys_addr, size, MEMREMAP_WC);
if (!mem_base) { if (!mem_base)
ret = -EINVAL; return ERR_PTR(-EINVAL);
goto out;
}
dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
if (!dma_mem) { if (!dma_mem)
ret = -ENOMEM; goto out_unmap_membase;
goto out;
}
dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!dma_mem->bitmap) { if (!dma_mem->bitmap)
ret = -ENOMEM; goto out_free_dma_mem;
goto out;
}
dma_mem->virt_base = mem_base; dma_mem->virt_base = mem_base;
dma_mem->device_base = device_addr; dma_mem->device_base = device_addr;
dma_mem->pfn_base = PFN_DOWN(phys_addr); dma_mem->pfn_base = PFN_DOWN(phys_addr);
dma_mem->size = pages; dma_mem->size = pages;
dma_mem->use_dev_dma_pfn_offset = use_dma_pfn_offset;
spin_lock_init(&dma_mem->spinlock); spin_lock_init(&dma_mem->spinlock);
*mem = dma_mem; return dma_mem;
return 0;
out: out_free_dma_mem:
kfree(dma_mem); kfree(dma_mem);
if (mem_base) out_unmap_membase:
memunmap(mem_base); memunmap(mem_base);
return ret; pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %zd MiB\n",
&phys_addr, size / SZ_1M);
return ERR_PTR(-ENOMEM);
} }
static void dma_release_coherent_memory(struct dma_coherent_mem *mem) static void dma_release_coherent_memory(struct dma_coherent_mem *mem)
...@@ -130,9 +123,9 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, ...@@ -130,9 +123,9 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
struct dma_coherent_mem *mem; struct dma_coherent_mem *mem;
int ret; int ret;
ret = dma_init_coherent_memory(phys_addr, device_addr, size, &mem); mem = dma_init_coherent_memory(phys_addr, device_addr, size, false);
if (ret) if (IS_ERR(mem))
return ret; return PTR_ERR(mem);
ret = dma_assign_coherent_memory(dev, mem); ret = dma_assign_coherent_memory(dev, mem);
if (ret) if (ret)
...@@ -319,21 +312,16 @@ static struct reserved_mem *dma_reserved_default_memory __initdata; ...@@ -319,21 +312,16 @@ static struct reserved_mem *dma_reserved_default_memory __initdata;
static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
{ {
struct dma_coherent_mem *mem = rmem->priv; if (!rmem->priv) {
int ret; struct dma_coherent_mem *mem;
if (!mem) { mem = dma_init_coherent_memory(rmem->base, rmem->base,
ret = dma_init_coherent_memory(rmem->base, rmem->base, rmem->size, true);
rmem->size, &mem); if (IS_ERR(mem))
if (ret) { return PTR_ERR(mem);
pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n", rmem->priv = mem;
&rmem->base, (unsigned long)rmem->size / SZ_1M);
return ret;
}
} }
mem->use_dev_dma_pfn_offset = true; dma_assign_coherent_memory(dev, rmem->priv);
rmem->priv = mem;
dma_assign_coherent_memory(dev, mem);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment