// SPDX-License-Identifier: GPL-2.0 #include #include #include #include #include #include #include #include #include #include void arch_dma_prep_coherent(struct page *page, size_t size) { void *ptr = page_address(page); memset(ptr, 0, size); dma_wbinv_range(page_to_phys(page), page_to_phys(page) + size); } static inline void cache_op(phys_addr_t paddr, size_t size, void (*fn)(unsigned long start, unsigned long end)) { unsigned long start = (unsigned long)paddr; fn(start, start + size); } void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: cache_op(paddr, size, dma_wb_range); break; case DMA_FROM_DEVICE: case DMA_BIDIRECTIONAL: cache_op(paddr, size, dma_wbinv_range); break; default: BUG(); } } EXPORT_SYMBOL_GPL(arch_sync_dma_for_device); void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: return; case DMA_FROM_DEVICE: case DMA_BIDIRECTIONAL: cache_op(paddr, size, dma_wbinv_range); break; default: BUG(); } } EXPORT_SYMBOL_GPL(arch_sync_dma_for_cpu); pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, unsigned long attrs) { if (attrs & DMA_ATTR_WRITE_COMBINE) return pgprot_writecombine(prot); return pgprot_noncached(prot); }