@@ -33,8 +33,12 @@ void flush_cache_mm(struct mm_struct *mm);
void flush_kernel_dcache_page_addr(const void *addr);
+#define clean_kernel_dcache_range(start,size) \
+ flush_kernel_dcache_range((start), (size))
#define flush_kernel_dcache_range(start,size) \
- flush_kernel_dcache_range_asm((start), (start)+(size));
+ flush_kernel_dcache_range_asm((start), (start)+(size))
+#define purge_kernel_dcache_range(start,size) \
+ purge_kernel_dcache_range_asm((start), (start)+(size))
#define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1
void flush_kernel_vmap_range(void *vaddr, int size);
@@ -446,11 +446,32 @@ void arch_dma_free(struct device *dev, size_t size, void *vaddr,
void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
- flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size);
+ unsigned long virt = (unsigned long)phys_to_virt(paddr);
+
+ switch (dir) {
+ case DMA_TO_DEVICE:
+ clean_kernel_dcache_range(virt, size);
+ break;
+ case DMA_FROM_DEVICE:
+ clean_kernel_dcache_range(virt, size);
+ break;
+ case DMA_BIDIRECTIONAL:
+ flush_kernel_dcache_range(virt, size);
+ break;
+ }
}
void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
- flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size);
+ unsigned long virt = (unsigned long)phys_to_virt(paddr);
+
+ switch (dir) {
+ case DMA_TO_DEVICE:
+ break;
+ case DMA_FROM_DEVICE:
+ case DMA_BIDIRECTIONAL:
+ purge_kernel_dcache_range(virt, size);
+ break;
+ }
}