Handle the direction flag in arch_sync_dma_for_device() and arch_sync_dma_for_cpu(). When receiving data from the device (DMA_FROM_DEVICE and DMA_BIDIRECTIONAL) purge the data cache in arch_sync_dma_for_cpu(). Run-tested on C8000 workstation. Signed-off-by: Helge Deller <deller@xxxxxx> diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index ba87f791323b..f8337c1820fc 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -446,11 +446,36 @@ 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 addr = (unsigned long) phys_to_virt(paddr); + + switch (dir) { + case DMA_TO_DEVICE: + flush_kernel_dcache_range(addr, size); + break; + case DMA_FROM_DEVICE: + case DMA_BIDIRECTIONAL: + flush_kernel_dcache_range(addr, size); + purge_kernel_dcache_range_asm(addr, addr + size); + break; + default: + BUG(); + } } 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 addr = (unsigned long) phys_to_virt(paddr); + + switch (dir) { + case DMA_TO_DEVICE: + flush_kernel_dcache_range(addr, size); + return; + case DMA_FROM_DEVICE: + case DMA_BIDIRECTIONAL: + purge_kernel_dcache_range_asm(addr, addr + size); + break; + default: + BUG(); + } }