diff options
Diffstat (limited to 'arch/arm/mm/dma-mapping.c')
-rw-r--r-- | arch/arm/mm/dma-mapping.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f906d5f4cbd8..a2881c98fb03 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -611,16 +611,22 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma, | |||
611 | { | 611 | { |
612 | int ret = -ENXIO; | 612 | int ret = -ENXIO; |
613 | #ifdef CONFIG_MMU | 613 | #ifdef CONFIG_MMU |
614 | unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | ||
615 | unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; | ||
614 | unsigned long pfn = dma_to_pfn(dev, dma_addr); | 616 | unsigned long pfn = dma_to_pfn(dev, dma_addr); |
617 | unsigned long off = vma->vm_pgoff; | ||
618 | |||
615 | vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); | 619 | vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot); |
616 | 620 | ||
617 | if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) | 621 | if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret)) |
618 | return ret; | 622 | return ret; |
619 | 623 | ||
620 | ret = remap_pfn_range(vma, vma->vm_start, | 624 | if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) { |
621 | pfn + vma->vm_pgoff, | 625 | ret = remap_pfn_range(vma, vma->vm_start, |
622 | vma->vm_end - vma->vm_start, | 626 | pfn + off, |
623 | vma->vm_page_prot); | 627 | vma->vm_end - vma->vm_start, |
628 | vma->vm_page_prot); | ||
629 | } | ||
624 | #endif /* CONFIG_MMU */ | 630 | #endif /* CONFIG_MMU */ |
625 | 631 | ||
626 | return ret; | 632 | return ret; |