From: Inki Dae Date: Tue, 3 Apr 2012 12:27:58 +0000 (+0900) Subject: drm/exynos: fixed page align and code clean. X-Git-Tag: v3.4-rc3~33^2^2~9 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=dcf9af822803bcc2cd9e8009648547e6060b59a0;p=~emulex%2Finfiniband.git drm/exynos: fixed page align and code clean. 1M section, 64k page count also should be rounded up so this patch rounds up them and caculates page count of them properly and also checks memory flags from user. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 4a3a5f72ed4..52d42cdeeb9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c @@ -41,7 +41,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (flags & EXYNOS_BO_NONCONTIG) { + if (IS_NONCONTIG_BUFFER(flags)) { DRM_DEBUG_KMS("not support allocation type.\n"); return -EINVAL; } @@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, } if (buf->size >= SZ_1M) { - npages = (buf->size >> SECTION_SHIFT) + 1; + npages = buf->size >> SECTION_SHIFT; page_size = SECTION_SIZE; } else if (buf->size >= SZ_64K) { - npages = (buf->size >> 16) + 1; + npages = buf->size >> 16; page_size = SZ_64K; } else { - npages = (buf->size >> PAGE_SHIFT) + 1; + npages = buf->size >> PAGE_SHIFT; page_size = PAGE_SIZE; } @@ -119,9 +119,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, buf->pages[i] = phys_to_page(start_addr); - sgl = sg_next(sgl); - sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0); - DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)buf->kvaddr, (unsigned long)buf->dma_addr, @@ -150,7 +147,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, * non-continuous memory would be released by exynos * gem framework. */ - if (flags & EXYNOS_BO_NONCONTIG) { + if (IS_NONCONTIG_BUFFER(flags)) { DRM_DEBUG_KMS("not support allocation type.\n"); return; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index fa1aa94a3d8..26d51979116 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg) return out_msg; } -static unsigned int mask_gem_flags(unsigned int flags) +static int check_gem_flags(unsigned int flags) { - return flags &= EXYNOS_BO_NONCONTIG; + if (flags & ~(EXYNOS_BO_MASK)) { + DRM_ERROR("invalid flags.\n"); + return -EINVAL; + } + + return 0; +} + +static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) +{ + if (!IS_NONCONTIG_BUFFER(flags)) { + if (size >= SZ_1M) + return roundup(size, SECTION_SIZE); + else if (size >= SZ_64K) + return roundup(size, SZ_64K); + else + goto out; + } +out: + return roundup(size, PAGE_SIZE); } static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, @@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, struct exynos_drm_gem_buf *buf; int ret; - size = roundup(size, PAGE_SIZE); - DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); + if (!size) { + DRM_ERROR("invalid size.\n"); + return ERR_PTR(-EINVAL); + } - flags = mask_gem_flags(flags); + size = roundup_gem_size(size, flags); + DRM_DEBUG_KMS("%s\n", __FILE__); + + ret = check_gem_flags(flags); + if (ret) + return ERR_PTR(ret); buf = exynos_drm_init_buf(dev, size); if (!buf) @@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, exynos_gem_obj = exynos_drm_gem_init(dev, size); if (!exynos_gem_obj) { ret = -ENOMEM; - goto err; + goto err_fini_buf; } exynos_gem_obj->buffer = buf; @@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); if (ret < 0) { drm_gem_object_release(&exynos_gem_obj->base); - goto err; + goto err_fini_buf; } } else { ret = exynos_drm_alloc_buf(dev, buf, flags); if (ret < 0) { drm_gem_object_release(&exynos_gem_obj->base); - goto err; + goto err_fini_buf; } } return exynos_gem_obj; -err: + +err_fini_buf: exynos_drm_fini_buf(dev, buf); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index e40fbad8b70..4ed84203950 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -29,6 +29,8 @@ #define to_exynos_gem_obj(x) container_of(x,\ struct exynos_drm_gem_obj, base) +#define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG) + /* * exynos drm gem buffer structure. * diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h index 3963116083a..1bb2d471920 100644 --- a/include/drm/exynos_drm.h +++ b/include/drm/exynos_drm.h @@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos { /* memory type definitions. */ enum e_drm_exynos_gem_mem_type { /* Physically Non-Continuous memory. */ - EXYNOS_BO_NONCONTIG = 1 << 0 + EXYNOS_BO_NONCONTIG = 1 << 0, + EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG }; #define DRM_EXYNOS_GEM_CREATE 0x00