diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 4985466..17a3064 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -106,6 +106,14 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 671ce1e..d4a8326 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -37,6 +37,21 @@ void dma_free_coherent(struct device *hw
EXPORT_SYMBOL(dma_free_coherent);
+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;
+
+ /* bus is equivalent with phys */
+ pfn = ((unsigned long)handle) >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
/*
* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
index f6b3c72..2b591e4 100644
--- a/arch/mips/mm/dma-coherent.c
+++ b/arch/mips/mm/dma-coherent.c
@@ -59,6 +59,24 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+ __attribute__((alias("dma_mmap_noncoherent")));
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
index 8da19fd..db453eb 100644
--- a/arch/mips/mm/dma-ip27.c
+++ b/arch/mips/mm/dma-ip27.c
@@ -64,6 +64,27 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
index ec54ed0..7cf348e 100644
--- a/arch/mips/mm/dma-ip32.c
+++ b/arch/mips/mm/dma-ip32.c
@@ -95,6 +95,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
index cd4ea84..64ac8fd 100644
--- a/arch/mips/mm/dma-noncoherent.c
+++ b/arch/mips/mm/dma-noncoherent.c
@@ -79,6 +79,29 @@ void dma_free_coherent(struct device *de
EXPORT_SYMBOL(dma_free_coherent);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+EXPORT_SYMBOL(dma_mmap_noncoherent);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap_noncoherent(dev, vma,
+ (void *)CAC_ADDR((unsigned long)cpu_addr),
+ handle, size);
+}
+
+EXPORT_SYMBOL(dma_mmap_coherent);
+
static inline void __dma_sync(unsigned long addr, size_t size,
enum dma_data_direction direction)
{diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index a6caf10..76481b3 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -396,6 +396,23 @@ static void pa11_dma_free_consistent (st
free_pages((unsigned long)__va(dma_handle), order);
}
+static int pa11_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static int pa11_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return pa11_mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
{
if (direction == DMA_NONE) {@@ -509,6 +526,8 @@ struct hppa_dma_ops pcxl_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = pa11_mmap_coherent,
+ .mmap_noncoherent = pa11_mmap_noncoherent,
};
static void *fail_alloc_consistent(struct device *dev, size_t size,@@ -537,6 +556,12 @@ static void pa11_dma_free_noncoherent(st
return;
}
+static int fail_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ return -ENXIO;
+}
+
struct hppa_dma_ops pcx_dma_ops = {
.dma_supported = pa11_dma_supported,
.alloc_consistent = fail_alloc_consistent,@@ -550,6 +575,8 @@ struct hppa_dma_ops pcx_dma_ops = {
.dma_sync_single_for_device = pa11_dma_sync_single_for_device,
.dma_sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.dma_sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .mmap_coherent = fail_mmap_coherent,
+ .mmap_noncoherent = fail_mmap_coherent,
};
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index ee73e30..097a0bf 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -59,6 +59,15 @@ void consistent_free(void *vaddr, size_t
}
}
+int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size)
+{
+ vaddr = (void *)P1SEGADDR((unsigned long)vaddr);
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(virt_to_page(vaddr)) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
void consistent_sync(void *vaddr, size_t size, int direction)
{
void * p1addr = (void*) P1SEGADDR((unsigned long)vaddr);@@ -80,5 +89,6 @@ void consistent_sync(void *vaddr, size_t
EXPORT_SYMBOL(consistent_alloc);
EXPORT_SYMBOL(consistent_free);
+EXPORT_SYMBOL(consistent_mmap);
EXPORT_SYMBOL(consistent_sync);
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index f9ff297..46e1fc3 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -508,6 +508,22 @@ void pci_free_consistent(struct pci_dev
free_pages(pgp, get_order(n));
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+ /* calculate pfn from bus address */
+ pfn = pfn_base + (((unsigned long)handle - phys_base) >> PAGE_SHIFT);
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+
/* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 4b376fa..a48766a 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -198,6 +198,7 @@ EXPORT_SYMBOL(insl);
EXPORT_SYMBOL(outsl);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c
index 82e5455..50e4691 100644
--- a/arch/sparc64/kernel/pci_iommu.c
+++ b/arch/sparc64/kernel/pci_iommu.c
@@ -290,6 +290,18 @@ static void pci_4u_free_consistent(struc
free_pages((unsigned long)cpu, order);
}
+/* Mmap a consistent area allocated via pci_alloc_consistent */
+int pci_mmap_consistent(struct pci_dev *pdev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr));
+
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
/* Map a single buffer at PTR of SZ bytes for PCI DMA
* in streaming mode.
*/diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 62d8a99..609abca 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -223,6 +223,7 @@ EXPORT_SYMBOL(isa_chain);
EXPORT_SYMBOL(pci_memspace_mask);
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
+EXPORT_SYMBOL(pci_mmap_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_map_sg);
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index a9275c9..93f9120 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -166,6 +166,22 @@ void dma_free_coherent(struct device *de
}
EXPORT_SYMBOL(dma_free_coherent);
+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,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
int dma_supported(struct device *dev, u64 mask)
{
if (dma_ops->dma_supported)diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index 62d0d66..a2dc0a5 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -50,8 +50,20 @@ #define dma_mapping_error(addr) (0)
#endif /* !CONFIG_PCI */
+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 = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(dev) (1)
int dma_set_mask(struct device *dev, u64 mask);diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index cbf1a98..d2a629e 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -12,6 +12,7 @@ #include <asm/scatterlist.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_PCI
void *dma_alloc_coherent(struct device *dev, size_t size,
@@ -19,6 +20,18 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+
+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 = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
#else
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,@@ -34,6 +47,15 @@ dma_free_coherent(struct device *dev, si
{
BUG();
}
+
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index e9fc1d4..7cd67fb 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -9,12 +9,16 @@ #include <asm/io.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
extern unsigned long __nongprelbss dma_coherent_mem_start;
extern unsigned long __nongprelbss dma_coherent_mem_end;
void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
/*
* These macros should be used after a pci_map_sg call has been done
diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h
index a7f1a55..fcf656e 100644
--- a/include/asm-generic/dma-mapping-broken.h
+++ b/include/asm-generic/dma-mapping-broken.h
@@ -19,4 +19,12 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
#endif /* _ASM_GENERIC_DMA_MAPPING_H */diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 1b35620..95d31d0 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -37,9 +37,13 @@ static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t flag)
{
+#ifdef CONFIG_MMU
BUG_ON(dev->bus != &pci_bus_type);
return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
+#else
+ return -ENXIO;
+#endif
}
static inline void@@ -51,6 +55,15 @@ dma_free_coherent(struct device *dev, si
pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG_ON(dev->bus != &pci_bus_type);
+
+ return pci_mmap_consistent(to_pci_dev(dev), vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)@@ -181,6 +194,14 @@ dma_free_coherent(struct device *dev, si
BUG();
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ BUG();
+ return -ENXIO;
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction direction)@@ -267,6 +288,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#define dma_is_consistent(d) (1)
static inline int
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index 9cf20ca..144b5c7 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -10,6 +10,7 @@ #include <asm/bug.h>
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag);
@@ -17,6 +18,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+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 = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index df67d40..d441031 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -12,6 +12,20 @@ #define dma_alloc_coherent platform_dma_
#define dma_alloc_noncoherent platform_dma_alloc_coherent /* coherent mem. is cheap */
#define dma_free_coherent platform_dma_free_coherent
#define dma_free_noncoherent platform_dma_free_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 = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+#define dma_mmap_noncoherent dma_mmap_coherent
+
#define dma_map_single platform_dma_map_single
#define dma_map_sg platform_dma_map_sg
#define dma_unmap_single platform_dma_unmap_singlediff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
index a7fa030..d00e400 100644
--- a/include/asm-m32r/dma-mapping.h
+++ b/include/asm-m32r/dma-mapping.h
@@ -1,23 +1 @@
-#ifndef _ASM_M32R_DMA_MAPPING_H
-#define _ASM_M32R_DMA_MAPPING_H
-
-/*
- * NOTE: Do not include <asm-generic/dma-mapping.h>
- * Because it requires PCI stuffs, but current M32R don't provide these.
- */
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
-{
- return (void *)NULL;
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
-{
- return;
-}
-
-#endif /* _ASM_M32R_DMA_MAPPING_H */
+#include <asm-generic/dma-mapping-broken.h>diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h
index 4328863..391abbd 100644
--- a/include/asm-mips/dma-mapping.h
+++ b/include/asm-mips/dma-mapping.h
@@ -16,6 +16,12 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+int dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction);
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
index 74d4ac6..c5cb337 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/include/asm-parisc/dma-mapping.h
@@ -20,6 +20,10 @@ struct hppa_dma_ops {
void (*dma_sync_single_for_device)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
void (*dma_sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
void (*dma_sync_sg_for_device)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
+ int (*mmap_coherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+ int (*mmap_noncoherent)(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
};
/*@@ -75,6 +79,20 @@ dma_free_noncoherent(struct device *dev,
hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_coherent(dev, vma, cpu_addr, handle, size);
+}
+
+static inline int
+dma_mmap_noncoherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ hppa_dma_ops->mmap_noncoherent(dev, vma, cpu_addr, handle, size);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ac63f5..7e74385 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -167,6 +167,17 @@ #define dma_unmap_sg(dev, sg, nents, dir
#endif /* CONFIG_PPC64 */
+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 = page_to_pfn(virt_to_page(cpu_addr));
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline void dma_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)@@ -218,6 +229,7 @@ #endif
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_mmap_noncoherent(d, v, a, h, s) dma_mmap_coherent(d, v, a, h, s)
#ifdef CONFIG_NOT_COHERENT_CACHE
#define dma_is_consistent(d) (0)
#else
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 48f1f42..7c84cbf 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -12,6 +12,7 @@ extern struct bus_type pci_bus_type;
/* arch/sh/mm/consistent.c */
extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr, size_t size);
extern void consistent_sync(void *vaddr, size_t size, int direction);
#define dma_supported(dev, mask) (1)
@@ -54,6 +55,16 @@ static inline void dma_free_coherent(str
consistent_free(vaddr, size);
}
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ if (sh_mv.mv_consistent_alloc)
+ return -ENXIO;
+ else
+ return consistent_mmap(vma, cpu_addr, size);
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index cc9a2e8..66cceaf 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -11,6 +11,8 @@ extern void *consistent_alloc(struct pci
dma_addr_t *dma_handle);
extern void consistent_free(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+extern int consistent_mmap(struct vm_area_struct *vma, void *vaddr,
+ dma_addr_t handle, size_t size);
#define dma_supported(dev, mask) (1)
@@ -36,6 +38,21 @@ static inline void dma_free_coherent(str
consistent_free(NULL, size, vaddr, dma_handle);
}
+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;
+
+ /* dma_handle is equivalent with phys addr */
+ pfn = (unsigned long)handle >> PAGE_SHIFT;
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+
+}
+
static inline void dma_cache_sync(void *vaddr, size_t size,
enum dma_data_direction dir)
{diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index d7c3b0f..22380c0 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -6,20 +6,7 @@ #include <linux/config.h>
#ifdef CONFIG_PCI
#include <asm-generic/dma-mapping.h>
#else
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC_DMA_MAPPING_H */diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index a8d39f2..8ea0082 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -145,22 +145,7 @@ dma_mapping_error(dma_addr_t dma_addr)
}
#else
-
-struct device;
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- BUG();
- return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
#endif /* PCI */
#endif /* _ASM_SPARC64_DMA_MAPPING_H */diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
index 49a81a6..c3a9b25 100644
--- a/include/asm-x86_64/dma-mapping.h
+++ b/include/asm-x86_64/dma-mapping.h
@@ -49,6 +49,10 @@ struct dma_mapping_ops {
struct scatterlist *sg, int nents,
int direction);
int (*dma_supported)(struct device *hwdev, u64 mask);
+ int (*mmap_coherent)(struct device *hwdev,
+ struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle,
+ size_t size);
int is_phys;
};
@@ -69,6 +73,9 @@ extern void *dma_alloc_coherent(struct d
extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle);
+extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size);
+
static inline dma_addr_t
dma_map_single(struct device *hwdev, void *ptr, size_t size,
int direction)
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
index c425f10..e0b1ca9 100644
--- a/include/asm-xtensa/dma-mapping.h
+++ b/include/asm-xtensa/dma-mapping.h
@@ -33,6 +33,17 @@ void *dma_alloc_coherent(struct device *
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle);
+static inline int
+dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ struct page *page = virt_to_page(bus_to_virt(handle));
+ return remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(page) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static inline dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)