[PATCH 5/8] sparc: implement dma_mmap_coherent()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel]     [Kernel Newbies]     [x86 Platform Driver]     [Netdev]     [Linux Wireless]     [Netfilter]     [Bugtraq]     [Linux Filesystems]     [Yosemite Discussion]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux