aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-04-27 03:20:27 -0400
committerDave Airlie <airlied@redhat.com>2012-04-27 03:20:35 -0400
commitb9556e0fa22ae8217289d6be445a2120f7865043 (patch)
treeb024b1eb408fd75a70c19b0ab5c0fad5bc4d0aef /drivers
parentaf3a3ab2966112c0d0a44df7eeb1e95fe32d4495 (diff)
parent818c4ea7c589c521912430ea54e0c0a0671b2c6d (diff)
Merge branch 'exynos-drm-fixes' of git://git.infradead.org/users/kmpark/linux-2.6-samsung into drm-fixes
From Inki Dae: this patch set fixes gem allocation and mapping issue between user space and physical memory region. * 'exynos-drm-fixes' of git://git.infradead.org/users/kmpark/linux-2.6-samsung: drm/exynos: added missed vm area region mapping type. drm/exynos: fixed exynos_drm_gem_map_pages bug. drm/exynos: fixed duplicatd memory allocation bug.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c30
1 files changed, 5 insertions, 25 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 392ce71ed6a1..1dffa8359f88 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -149,22 +149,12 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj,
149 unsigned long pfn; 149 unsigned long pfn;
150 150
151 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { 151 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
152 unsigned long usize = buf->size;
153
154 if (!buf->pages) 152 if (!buf->pages)
155 return -EINTR; 153 return -EINTR;
156 154
157 while (usize > 0) { 155 pfn = page_to_pfn(buf->pages[page_offset++]);
158 pfn = page_to_pfn(buf->pages[page_offset++]); 156 } else
159 vm_insert_mixed(vma, f_vaddr, pfn); 157 pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;
160 f_vaddr += PAGE_SIZE;
161 usize -= PAGE_SIZE;
162 }
163
164 return 0;
165 }
166
167 pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;
168 158
169 return vm_insert_mixed(vma, f_vaddr, pfn); 159 return vm_insert_mixed(vma, f_vaddr, pfn);
170} 160}
@@ -524,6 +514,8 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
524 if (!buffer->pages) 514 if (!buffer->pages)
525 return -EINVAL; 515 return -EINVAL;
526 516
517 vma->vm_flags |= VM_MIXEDMAP;
518
527 do { 519 do {
528 ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); 520 ret = vm_insert_page(vma, uaddr, buffer->pages[i++]);
529 if (ret) { 521 if (ret) {
@@ -710,7 +702,6 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv,
710int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 702int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
711{ 703{
712 struct drm_gem_object *obj = vma->vm_private_data; 704 struct drm_gem_object *obj = vma->vm_private_data;
713 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
714 struct drm_device *dev = obj->dev; 705 struct drm_device *dev = obj->dev;
715 unsigned long f_vaddr; 706 unsigned long f_vaddr;
716 pgoff_t page_offset; 707 pgoff_t page_offset;
@@ -722,21 +713,10 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
722 713
723 mutex_lock(&dev->struct_mutex); 714 mutex_lock(&dev->struct_mutex);
724 715
725 /*
726 * allocate all pages as desired size if user wants to allocate
727 * physically non-continuous memory.
728 */
729 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
730 ret = exynos_drm_gem_get_pages(obj);
731 if (ret < 0)
732 goto err;
733 }
734
735 ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); 716 ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset);
736 if (ret < 0) 717 if (ret < 0)
737 DRM_ERROR("failed to map pages.\n"); 718 DRM_ERROR("failed to map pages.\n");
738 719
739err:
740 mutex_unlock(&dev->struct_mutex); 720 mutex_unlock(&dev->struct_mutex);
741 721
742 return convert_to_vm_err_msg(ret); 722 return convert_to_vm_err_msg(ret);