ARM: dma-mapping: simplify dma_cache_maint_page
[sfrench/cifs-2.6.git] / arch / arm / mm / dma-mapping.c
index 26325cb5d368e504e6eb7c669b28ac3ed023e3c6..0d68d2c83cdab66f95c4c3b64ed807510c432b75 100644 (file)
@@ -404,7 +404,7 @@ EXPORT_SYMBOL(dma_free_coherent);
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
-void dma_cache_maint(const void *start, size_t size, int direction)
+static void dma_cache_maint(const void *start, size_t size, int direction)
 {
        void (*inner_op)(const void *, const void *);
        void (*outer_op)(unsigned long, unsigned long);
@@ -431,12 +431,62 @@ void dma_cache_maint(const void *start, size_t size, int direction)
        inner_op(start, start + size);
        outer_op(__pa(start), __pa(start) + size);
 }
-EXPORT_SYMBOL(dma_cache_maint);
 
-static void dma_cache_maint_contiguous(struct page *page, unsigned long offset,
-                                      size_t size, int direction)
+void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
+       enum dma_data_direction dir)
+{
+       dma_cache_maint(kaddr, size, dir);
+}
+EXPORT_SYMBOL(___dma_single_cpu_to_dev);
+
+void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
+       enum dma_data_direction dir)
+{
+       /* nothing to do */
+}
+EXPORT_SYMBOL(___dma_single_dev_to_cpu);
+
+static void dma_cache_maint_page(struct page *page, unsigned long offset,
+       size_t size, void (*op)(const void *, const void *))
+{
+       /*
+        * A single sg entry may refer to multiple physically contiguous
+        * pages.  But we still need to process highmem pages individually.
+        * If highmem is not configured then the bulk of this loop gets
+        * optimized out.
+        */
+       size_t left = size;
+       do {
+               size_t len = left;
+               void *vaddr;
+
+               if (PageHighMem(page)) {
+                       if (len + offset > PAGE_SIZE) {
+                               if (offset >= PAGE_SIZE) {
+                                       page += offset / PAGE_SIZE;
+                                       offset %= PAGE_SIZE;
+                               }
+                               len = PAGE_SIZE - offset;
+                       }
+                       vaddr = kmap_high_get(page);
+                       if (vaddr) {
+                               vaddr += offset;
+                               op(vaddr, vaddr + len);
+                               kunmap_high(page);
+                       }
+               } else {
+                       vaddr = page_address(page) + offset;
+                       op(vaddr, vaddr + len);
+               }
+               offset = 0;
+               page++;
+               left -= len;
+       } while (left);
+}
+
+void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
+       size_t size, enum dma_data_direction dir)
 {
-       void *vaddr;
        unsigned long paddr;
        void (*inner_op)(const void *, const void *);
        void (*outer_op)(unsigned long, unsigned long);
@@ -458,48 +508,19 @@ static void dma_cache_maint_contiguous(struct page *page, unsigned long offset,
                BUG();
        }
 
-       if (!PageHighMem(page)) {
-               vaddr = page_address(page) + offset;
-               inner_op(vaddr, vaddr + size);
-       } else {
-               vaddr = kmap_high_get(page);
-               if (vaddr) {
-                       vaddr += offset;
-                       inner_op(vaddr, vaddr + size);
-                       kunmap_high(page);
-               }
-       }
+       dma_cache_maint_page(page, off, size, inner_op);
 
-       paddr = page_to_phys(page) + offset;
+       paddr = page_to_phys(page) + off;
        outer_op(paddr, paddr + size);
 }
+EXPORT_SYMBOL(___dma_page_cpu_to_dev);
 
-void dma_cache_maint_page(struct page *page, unsigned long offset,
-                         size_t size, int dir)
+void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
+       size_t size, enum dma_data_direction dir)
 {
-       /*
-        * A single sg entry may refer to multiple physically contiguous
-        * pages.  But we still need to process highmem pages individually.
-        * If highmem is not configured then the bulk of this loop gets
-        * optimized out.
-        */
-       size_t left = size;
-       do {
-               size_t len = left;
-               if (PageHighMem(page) && len + offset > PAGE_SIZE) {
-                       if (offset >= PAGE_SIZE) {
-                               page += offset / PAGE_SIZE;
-                               offset %= PAGE_SIZE;
-                       }
-                       len = PAGE_SIZE - offset;
-               }
-               dma_cache_maint_contiguous(page, offset, len, dir);
-               offset = 0;
-               page++;
-               left -= len;
-       } while (left);
+       /* nothing to do */
 }
-EXPORT_SYMBOL(dma_cache_maint_page);
+EXPORT_SYMBOL(___dma_page_dev_to_cpu);
 
 /**
  * dma_map_sg - map a set of SG buffers for streaming mode DMA
@@ -573,8 +594,12 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
        int i;
 
        for_each_sg(sg, s, nents, i) {
-               dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
-                                       sg_dma_len(s), dir);
+               if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
+                                           sg_dma_len(s), dir))
+                       continue;
+
+               __dma_page_dev_to_cpu(sg_page(s), s->offset,
+                                     s->length, dir);
        }
 }
 EXPORT_SYMBOL(dma_sync_sg_for_cpu);
@@ -597,9 +622,8 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
                                        sg_dma_len(s), dir))
                        continue;
 
-               if (!arch_is_coherent())
-                       dma_cache_maint_page(sg_page(s), s->offset,
-                                            s->length, dir);
+               __dma_page_cpu_to_dev(sg_page(s), s->offset,
+                                     s->length, dir);
        }
 }
 EXPORT_SYMBOL(dma_sync_sg_for_device);