From: Florian Fainelli <florian.fainelli@xxxxxxxxxxxx> In preparation for allowing support for Broadcom's eXtended Kseg0/1 feature, allow platforms to override how coherent DMA mappings are done by providing plat_map_coherent() and plat_unmap_coherent() hooks, which default to the current implementation with CAC/UNCAC unless changed. Signed-off-by: Florian Fainelli <f.fainelli@xxxxxxxxx> --- arch/mips/include/asm/mach-generic/dma-coherence.h | 16 ++++++++++++++++ arch/mips/mm/dma-default.c | 10 +++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index e6e7dfa15801..42a1546e7d10 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h @@ -98,4 +98,20 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) #endif #endif /* CONFIG_SWIOTLB */ +#ifndef plat_map_coherent +static inline int plat_map_coherent(dma_addr_t handle, void *cac_va, size_t size, + void **uncac_va, gfp_t gfp) +{ + *uncac_va = UNCAC_ADDR(cac_va); + return 0; +} +#endif + +#ifndef plat_unmap_coherent +static inline void *plat_unmap_coherent(void *addr) +{ + return CAC_ADDR(addr); +} +#endif + #endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */ diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index e3e94d05f0fd..f82f00dcc841 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -151,7 +151,11 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, if (!(attrs & DMA_ATTR_NON_CONSISTENT) && !plat_device_is_coherent(dev)) { dma_cache_wback_inv((unsigned long) ret, size); - ret = UNCAC_ADDR(ret); + if (plat_map_coherent(*dma_handle, ret, PFN_ALIGN(size), + &ret, gfp)) { + free_pages((unsigned long)ret, size); + ret = NULL; + } } return ret; @@ -167,7 +171,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); if (!(attrs & DMA_ATTR_NON_CONSISTENT) && !plat_device_is_coherent(dev)) - addr = CAC_ADDR(addr); + addr = (unsigned long)plat_unmap_coherent(vaddr); page = virt_to_page((void *) addr); @@ -187,7 +191,7 @@ static int mips_dma_mmap(struct device *dev, struct vm_area_struct *vma, int ret = -ENXIO; if (!plat_device_is_coherent(dev)) - addr = CAC_ADDR(addr); + addr = (unsigned long)plat_unmap_coherent((void *)addr); pfn = page_to_pfn(virt_to_page((void *)addr)); -- 2.7.4