@@ -170,3 +170,53 @@ int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
return 0;
}
EXPORT_SYMBOL(dma_release_from_coherent);
+
+int dma_preallocate_coherent_memory(struct device *dev, size_t size, gfp_t gfp,
+ int flags)
+{
+ int pages = size >> PAGE_SHIFT;
+ int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
+ dma_addr_t dma_handle;
+ void *buf;
+
+ if (!(flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) || !dev)
+ return -EINVAL;
+
+ if (!size)
+ return 0;
+
+ buf = dma_alloc_coherent(NULL, size, &dma_handle, gfp);
+ if (!buf)
+ return -ENOMEM;
+
+ dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem) + bitmap_size, gfp);
+ if (!dev->dma_mem)
+ goto ealloc;
+
+ dev->dma_mem->virt_base = buf;
+ dev->dma_mem->device_base = dma_handle;
+ dev->dma_mem->size = pages;
+ dev->dma_mem->flags = flags;
+
+ return 0;
+
+ealloc:
+ dma_free_coherent(dev, size, buf, dma_handle);
+
+ return -ENOMEM;
+}
+EXPORT_SYMBOL(dma_preallocate_coherent_memory);
+
+void dma_release_preallocated_memory(struct device *dev)
+{
+ struct dma_coherent_mem *mem = dev->dma_mem;
+
+ if (!mem)
+ return;
+
+ dev->dma_mem = NULL;
+ dma_free_coherent(dev, mem->size << PAGE_SHIFT, mem->virt_base,
+ mem->device_base);
+ kfree(mem);
+}
+EXPORT_SYMBOL(dma_release_preallocated_memory);
@@ -21,6 +21,8 @@ void dma_release_declared_memory(struct device *dev);
void *dma_mark_declared_memory_occupied(struct device *dev,
dma_addr_t device_addr, size_t size);
+int dma_preallocate_coherent_memory(struct device *dev, size_t size, gfp_t gfp, int flags);
+void dma_release_preallocated_memory(struct device *dev);
#else
#define dma_alloc_from_coherent(dev, size, handle, ret) (0)
#define dma_release_from_coherent(dev, order, vaddr) (0)
@@ -177,6 +177,18 @@ dma_mark_declared_memory_occupied(struct device *dev,
{
return ERR_PTR(-EBUSY);
}
+
+static inline int
+dma_preallocate_coherent_memory(struct device *dev, size_t size, gfp_t gfp, int flags)
+{
+ return -EINVAL;
+}
+
+static inline void
+dma_release_preallocated_memory(struct device *dev)
+{
+}
+
#endif
/*