A lazy version of dma_mmap_coherent() implementation for Sparc. Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> --- arch/sparc/include/asm/dma-mapping.h | 17 +++++++++++++++++ arch/sparc/kernel/dma.c | 1 + arch/sparc/kernel/dma.h | 3 +++ arch/sparc/kernel/ioport.c | 16 ++++++++++++++++ 4 files changed, 37 insertions(+), 0 deletions(-) diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 204e4bf..dd9d102 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -41,6 +41,8 @@ struct dma_ops { void (*sync_sg_for_device)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir); + int (*mmap_coherent)(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size); }; extern const struct dma_ops *dma_ops; @@ -148,6 +150,21 @@ static inline void dma_sync_single_range_for_device(struct device *dev, dma_sync_single_for_device(dev, dma_handle+offset, size, dir); } +#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 handle, + size_t size) +{ + unsigned long pfn; + + if (dma_ops->mmap_coherent) + return dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size); + pfn = page_to_pfn(virt_to_page(cpu_addr)); + return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, + size, vma->vm_page_prot); +} + static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c index 524c32f..85cf6de 100644 --- a/arch/sparc/kernel/dma.c +++ b/arch/sparc/kernel/dma.c @@ -172,6 +172,7 @@ static const struct dma_ops dma32_dma_ops = { .sync_single_for_device = dma32_sync_single_for_device, .sync_sg_for_cpu = dma32_sync_sg_for_cpu, .sync_sg_for_device = dma32_sync_sg_for_device, + .mmap_coherent = dma32_mmap_coherent, }; const struct dma_ops *dma_ops = &dma32_dma_ops; diff --git a/arch/sparc/kernel/dma.h b/arch/sparc/kernel/dma.h index f8d8951..0f2e61f 100644 --- a/arch/sparc/kernel/dma.h +++ b/arch/sparc/kernel/dma.h @@ -12,3 +12,6 @@ void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, size_t size, int direction); void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t size, int direction); + +int dma32_mmap_coherent(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size); diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 87ea0d0..ff21189 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -661,6 +661,22 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, EXPORT_SYMBOL(pci_dma_sync_sg_for_device); #endif /* CONFIG_PCI */ +/* used in dma.c */ +int dma32_mmap_coherent(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size) +{ + struct resource *res; + struct page *pg; + + res = _sparc_find_resource(&_sparc_dvma, (unsigned long)cpu_addr); + if (!res) + return -ENXIO; + pg = virt_to_page(res->start); + return remap_pfn_range(vma, vma->vm_start, + page_to_pfn(pg) + vma->vm_pgoff, + size, vma->vm_page_prot); +} + #ifdef CONFIG_PROC_FS static int -- 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