A lazy version of dma_mmap_coherent() implementation for powerpc. The standard mmap is used as a fallback. Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> --- arch/powerpc/include/asm/dma-mapping.h | 22 ++++++++++++++++++++++ arch/powerpc/kernel/dma.c | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index b44aaab..030a4b1 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -105,6 +105,10 @@ struct dma_mapping_ops { struct scatterlist *sg, int nelems, enum dma_data_direction direction); #endif + int (*mmap_coherent)(struct device *hwdev, + struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_handle, + size_t size); }; /* @@ -415,6 +419,24 @@ static inline void dma_sync_single_range_for_device(struct device *dev, } #endif +#define ARCH_HAS_DMA_MMAP_COHERENT +static inline int dma_mmap_coherent(struct device *dev, + struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_handle, + size_t size) +{ + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + + BUG_ON(!dma_ops); + + if (dma_ops->mmap_coherent) + return dma_ops->mmap_coherent(dev, vma, cpu_addr, dma_handle, + size); + else + return dma_direct_ops.mmap_coherent(dev, vma, cpu_addr, + dma_handle, size); +} + static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 20a60d6..d11db99 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -140,6 +140,26 @@ static inline void dma_direct_sync_single_range(struct device *dev, } #endif +static int dma_direct_mmap_coherent(struct device *dev, + struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_handle, + size_t size) +{ + unsigned long pfn; +#ifdef CONFIG_NOT_COHERENT_CACHE + dma_handle -= get_dma_direct_offset(dev); + /* assume dma_handle set via pfn_to_phys() in + * mm/dma-noncoherent.c + */ + pfn = dma_handle >> PAGE_SHIFT; +#else + pfn = page_to_pfn(virt_to_page(cpu_addr)); +#endif + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, + size, vma->vm_page_prot); +} + struct dma_mapping_ops dma_direct_ops = { .alloc_coherent = dma_direct_alloc_coherent, .free_coherent = dma_direct_free_coherent, @@ -154,5 +174,6 @@ struct dma_mapping_ops dma_direct_ops = { .sync_sg_for_cpu = dma_direct_sync_sg, .sync_sg_for_device = dma_direct_sync_sg, #endif + .mmap_coherent = dma_direct_mmap_coherent, }; EXPORT_SYMBOL(dma_direct_ops); -- 1.6.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html