|
@@ -6,6 +6,7 @@
|
|
|
#include <linux/scatterlist.h>
|
|
|
#include <linux/dma-debug.h>
|
|
|
#include <linux/dma-attrs.h>
|
|
|
+#include <asm-generic/dma-coherent.h>
|
|
|
|
|
|
static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
|
|
|
size_t size,
|
|
@@ -237,4 +238,61 @@ dma_get_sgtable_attrs(struct device *dev, struct sg_table *sgt, void *cpu_addr,
|
|
|
|
|
|
#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, NULL)
|
|
|
|
|
|
+#ifndef arch_dma_alloc_attrs
|
|
|
+#define arch_dma_alloc_attrs(dev, flag) (true)
|
|
|
+#endif
|
|
|
+
|
|
|
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
|
|
|
+ dma_addr_t *dma_handle, gfp_t flag,
|
|
|
+ struct dma_attrs *attrs)
|
|
|
+{
|
|
|
+ struct dma_map_ops *ops = get_dma_ops(dev);
|
|
|
+ void *cpu_addr;
|
|
|
+
|
|
|
+ BUG_ON(!ops);
|
|
|
+
|
|
|
+ if (dma_alloc_from_coherent(dev, size, dma_handle, &cpu_addr))
|
|
|
+ return cpu_addr;
|
|
|
+
|
|
|
+ if (!arch_dma_alloc_attrs(&dev, &flag))
|
|
|
+ return NULL;
|
|
|
+ if (!ops->alloc)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
|
|
|
+ debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
|
|
|
+ return cpu_addr;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void dma_free_attrs(struct device *dev, size_t size,
|
|
|
+ void *cpu_addr, dma_addr_t dma_handle,
|
|
|
+ struct dma_attrs *attrs)
|
|
|
+{
|
|
|
+ struct dma_map_ops *ops = get_dma_ops(dev);
|
|
|
+
|
|
|
+ BUG_ON(!ops);
|
|
|
+ WARN_ON(irqs_disabled());
|
|
|
+
|
|
|
+ if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (!ops->free)
|
|
|
+ return;
|
|
|
+
|
|
|
+ debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
|
|
|
+ ops->free(dev, size, cpu_addr, dma_handle, attrs);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
|
|
|
+ dma_addr_t *dma_handle, gfp_t flag)
|
|
|
+{
|
|
|
+ return dma_alloc_attrs(dev, size, dma_handle, flag, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+static inline void dma_free_coherent(struct device *dev, size_t size,
|
|
|
+ void *cpu_addr, dma_addr_t dma_handle)
|
|
|
+{
|
|
|
+ return dma_free_attrs(dev, size, cpu_addr, dma_handle, NULL);
|
|
|
+}
|
|
|
+
|
|
|
#endif
|