|
@@ -7,7 +7,7 @@
|
|
|
*/
|
|
|
|
|
|
#include <linux/acpi.h>
|
|
|
-#include <linux/dma-mapping.h>
|
|
|
+#include <linux/dma-noncoherent.h>
|
|
|
#include <linux/export.h>
|
|
|
#include <linux/gfp.h>
|
|
|
#include <linux/of_device.h>
|
|
@@ -220,27 +220,37 @@ EXPORT_SYMBOL(dma_common_get_sgtable);
|
|
|
* Create userspace mapping for the DMA-coherent memory.
|
|
|
*/
|
|
|
int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
|
|
|
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
|
|
|
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
|
|
|
+ unsigned long attrs)
|
|
|
{
|
|
|
- int ret = -ENXIO;
|
|
|
#ifndef CONFIG_ARCH_NO_COHERENT_DMA_MMAP
|
|
|
unsigned long user_count = vma_pages(vma);
|
|
|
unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
|
|
|
unsigned long off = vma->vm_pgoff;
|
|
|
+ unsigned long pfn;
|
|
|
+ int ret = -ENXIO;
|
|
|
|
|
|
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
|
|
+ vma->vm_page_prot = arch_dma_mmap_pgprot(dev, vma->vm_page_prot, attrs);
|
|
|
|
|
|
if (dma_mmap_from_dev_coherent(dev, vma, cpu_addr, size, &ret))
|
|
|
return ret;
|
|
|
|
|
|
- if (off < count && user_count <= (count - off))
|
|
|
- ret = remap_pfn_range(vma, vma->vm_start,
|
|
|
- page_to_pfn(virt_to_page(cpu_addr)) + off,
|
|
|
- user_count << PAGE_SHIFT,
|
|
|
- vma->vm_page_prot);
|
|
|
-#endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
|
|
|
+ if (off >= count || user_count > count - off)
|
|
|
+ return -ENXIO;
|
|
|
+
|
|
|
+ if (!dev_is_dma_coherent(dev)) {
|
|
|
+ if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN))
|
|
|
+ return -ENXIO;
|
|
|
+ pfn = arch_dma_coherent_to_pfn(dev, cpu_addr, dma_addr);
|
|
|
+ } else {
|
|
|
+ pfn = page_to_pfn(virt_to_page(cpu_addr));
|
|
|
+ }
|
|
|
|
|
|
- return ret;
|
|
|
+ return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff,
|
|
|
+ user_count << PAGE_SHIFT, vma->vm_page_prot);
|
|
|
+#else
|
|
|
+ return -ENXIO;
|
|
|
+#endif /* !CONFIG_ARCH_NO_COHERENT_DMA_MMAP */
|
|
|
}
|
|
|
EXPORT_SYMBOL(dma_common_mmap);
|
|
|
|