diff options
author | Joonyoung Shim <jy0922.shim@samsung.com> | 2011-12-13 00:39:13 -0500 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2011-12-28 21:21:41 -0500 |
commit | 2364839a1aca677842b0dfd7ed0449acda3c3175 (patch) | |
tree | ee5dba46a9859409ea5c939d362883f7873b4255 /drivers/gpu/drm/exynos | |
parent | 2d91cf17b58b4d8228190103bef507bc73094bef (diff) |
drm/exynos: Split creation of gem object and gem handle
exynos_drm_gem_create function created gem object with gem handle but it
can be called externally without gem handle creation through this patch.
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.c | 130 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.h | 7 |
3 files changed, 81 insertions, 60 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 39f268b49aea..5231759dfd47 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -162,9 +162,7 @@ exynos_drm_fb_init(struct drm_file *file_priv, struct drm_device *dev, | |||
162 | 162 | ||
163 | goto out; | 163 | goto out; |
164 | } else { | 164 | } else { |
165 | exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, | 165 | exynos_gem_obj = exynos_drm_gem_create(dev, size); |
166 | &mode_cmd->handles[0], | ||
167 | size); | ||
168 | if (IS_ERR(exynos_gem_obj)) { | 166 | if (IS_ERR(exynos_gem_obj)) { |
169 | ret = PTR_ERR(exynos_gem_obj); | 167 | ret = PTR_ERR(exynos_gem_obj); |
170 | goto err_buffer; | 168 | goto err_buffer; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 90aa6302eaf9..025abb3e3b67 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -55,62 +55,84 @@ static unsigned int convert_to_vm_err_msg(int msg) | |||
55 | return out_msg; | 55 | return out_msg; |
56 | } | 56 | } |
57 | 57 | ||
58 | static struct exynos_drm_gem_obj * | 58 | static int exynos_drm_gem_handle_create(struct drm_gem_object *obj, |
59 | exynos_drm_gem_init(struct drm_device *drm_dev, struct drm_file *file_priv, | 59 | struct drm_file *file_priv, |
60 | unsigned int *handle, unsigned int size) | 60 | unsigned int *handle) |
61 | { | 61 | { |
62 | struct exynos_drm_gem_obj *exynos_gem_obj; | ||
63 | struct drm_gem_object *obj; | ||
64 | int ret; | 62 | int ret; |
65 | 63 | ||
66 | exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL); | ||
67 | if (!exynos_gem_obj) { | ||
68 | DRM_ERROR("failed to allocate exynos gem object.\n"); | ||
69 | return ERR_PTR(-ENOMEM); | ||
70 | } | ||
71 | |||
72 | obj = &exynos_gem_obj->base; | ||
73 | |||
74 | ret = drm_gem_object_init(drm_dev, obj, size); | ||
75 | if (ret < 0) { | ||
76 | DRM_ERROR("failed to initialize gem object.\n"); | ||
77 | ret = -EINVAL; | ||
78 | goto err; | ||
79 | } | ||
80 | |||
81 | DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp); | ||
82 | |||
83 | /* | 64 | /* |
84 | * allocate a id of idr table where the obj is registered | 65 | * allocate a id of idr table where the obj is registered |
85 | * and handle has the id what user can see. | 66 | * and handle has the id what user can see. |
86 | */ | 67 | */ |
87 | ret = drm_gem_handle_create(file_priv, obj, handle); | 68 | ret = drm_gem_handle_create(file_priv, obj, handle); |
88 | if (ret) | 69 | if (ret) |
89 | goto err_release; | 70 | return ret; |
90 | 71 | ||
91 | DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle); | 72 | DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle); |
92 | 73 | ||
93 | /* drop reference from allocate - handle holds it now. */ | 74 | /* drop reference from allocate - handle holds it now. */ |
94 | drm_gem_object_unreference_unlocked(obj); | 75 | drm_gem_object_unreference_unlocked(obj); |
95 | 76 | ||
96 | return exynos_gem_obj; | 77 | return 0; |
78 | } | ||
79 | |||
80 | void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj) | ||
81 | { | ||
82 | struct drm_gem_object *obj; | ||
83 | |||
84 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
85 | |||
86 | if (!exynos_gem_obj) | ||
87 | return; | ||
88 | |||
89 | obj = &exynos_gem_obj->base; | ||
90 | |||
91 | DRM_DEBUG_KMS("handle count = %d\n", atomic_read(&obj->handle_count)); | ||
92 | |||
93 | exynos_drm_buf_destroy(obj->dev, exynos_gem_obj->buffer); | ||
97 | 94 | ||
98 | err_release: | 95 | if (obj->map_list.map) |
96 | drm_gem_free_mmap_offset(obj); | ||
97 | |||
98 | /* release file pointer to gem object. */ | ||
99 | drm_gem_object_release(obj); | 99 | drm_gem_object_release(obj); |
100 | 100 | ||
101 | err: | ||
102 | kfree(exynos_gem_obj); | 101 | kfree(exynos_gem_obj); |
103 | return ERR_PTR(ret); | 102 | } |
103 | |||
104 | static struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, | ||
105 | unsigned long size) | ||
106 | { | ||
107 | struct exynos_drm_gem_obj *exynos_gem_obj; | ||
108 | struct drm_gem_object *obj; | ||
109 | int ret; | ||
110 | |||
111 | exynos_gem_obj = kzalloc(sizeof(*exynos_gem_obj), GFP_KERNEL); | ||
112 | if (!exynos_gem_obj) { | ||
113 | DRM_ERROR("failed to allocate exynos gem object\n"); | ||
114 | return NULL; | ||
115 | } | ||
116 | |||
117 | obj = &exynos_gem_obj->base; | ||
118 | |||
119 | ret = drm_gem_object_init(dev, obj, size); | ||
120 | if (ret < 0) { | ||
121 | DRM_ERROR("failed to initialize gem object\n"); | ||
122 | kfree(exynos_gem_obj); | ||
123 | return NULL; | ||
124 | } | ||
125 | |||
126 | DRM_DEBUG_KMS("created file object = 0x%x\n", (unsigned int)obj->filp); | ||
127 | |||
128 | return exynos_gem_obj; | ||
104 | } | 129 | } |
105 | 130 | ||
106 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | 131 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, |
107 | struct drm_file *file_priv, | ||
108 | unsigned int *handle, | ||
109 | unsigned long size) | 132 | unsigned long size) |
110 | { | 133 | { |
111 | |||
112 | struct exynos_drm_gem_obj *exynos_gem_obj; | ||
113 | struct exynos_drm_gem_buf *buffer; | 134 | struct exynos_drm_gem_buf *buffer; |
135 | struct exynos_drm_gem_obj *exynos_gem_obj; | ||
114 | 136 | ||
115 | size = roundup(size, PAGE_SIZE); | 137 | size = roundup(size, PAGE_SIZE); |
116 | DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); | 138 | DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); |
@@ -119,10 +141,10 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | |||
119 | if (!buffer) | 141 | if (!buffer) |
120 | return ERR_PTR(-ENOMEM); | 142 | return ERR_PTR(-ENOMEM); |
121 | 143 | ||
122 | exynos_gem_obj = exynos_drm_gem_init(dev, file_priv, handle, size); | 144 | exynos_gem_obj = exynos_drm_gem_init(dev, size); |
123 | if (IS_ERR(exynos_gem_obj)) { | 145 | if (!exynos_gem_obj) { |
124 | exynos_drm_buf_destroy(dev, buffer); | 146 | exynos_drm_buf_destroy(dev, buffer); |
125 | return exynos_gem_obj; | 147 | return ERR_PTR(-ENOMEM); |
126 | } | 148 | } |
127 | 149 | ||
128 | exynos_gem_obj->buffer = buffer; | 150 | exynos_gem_obj->buffer = buffer; |
@@ -135,14 +157,21 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, | |||
135 | { | 157 | { |
136 | struct drm_exynos_gem_create *args = data; | 158 | struct drm_exynos_gem_create *args = data; |
137 | struct exynos_drm_gem_obj *exynos_gem_obj; | 159 | struct exynos_drm_gem_obj *exynos_gem_obj; |
160 | int ret; | ||
138 | 161 | ||
139 | DRM_DEBUG_KMS("%s\n", __FILE__); | 162 | DRM_DEBUG_KMS("%s\n", __FILE__); |
140 | 163 | ||
141 | exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, &args->handle, | 164 | exynos_gem_obj = exynos_drm_gem_create(dev, args->size); |
142 | args->size); | ||
143 | if (IS_ERR(exynos_gem_obj)) | 165 | if (IS_ERR(exynos_gem_obj)) |
144 | return PTR_ERR(exynos_gem_obj); | 166 | return PTR_ERR(exynos_gem_obj); |
145 | 167 | ||
168 | ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, | ||
169 | &args->handle); | ||
170 | if (ret) { | ||
171 | exynos_drm_gem_destroy(exynos_gem_obj); | ||
172 | return ret; | ||
173 | } | ||
174 | |||
146 | return 0; | 175 | return 0; |
147 | } | 176 | } |
148 | 177 | ||
@@ -177,6 +206,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, | |||
177 | 206 | ||
178 | vma->vm_flags |= (VM_IO | VM_RESERVED); | 207 | vma->vm_flags |= (VM_IO | VM_RESERVED); |
179 | 208 | ||
209 | /* in case of direct mapping, always having non-cachable attribute */ | ||
180 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 210 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
181 | vma->vm_file = filp; | 211 | vma->vm_file = filp; |
182 | 212 | ||
@@ -261,24 +291,9 @@ int exynos_drm_gem_init_object(struct drm_gem_object *obj) | |||
261 | 291 | ||
262 | void exynos_drm_gem_free_object(struct drm_gem_object *obj) | 292 | void exynos_drm_gem_free_object(struct drm_gem_object *obj) |
263 | { | 293 | { |
264 | struct exynos_drm_gem_obj *exynos_gem_obj; | ||
265 | |||
266 | DRM_DEBUG_KMS("%s\n", __FILE__); | 294 | DRM_DEBUG_KMS("%s\n", __FILE__); |
267 | 295 | ||
268 | DRM_DEBUG_KMS("handle count = %d\n", | 296 | exynos_drm_gem_destroy(to_exynos_gem_obj(obj)); |
269 | atomic_read(&obj->handle_count)); | ||
270 | |||
271 | if (obj->map_list.map) | ||
272 | drm_gem_free_mmap_offset(obj); | ||
273 | |||
274 | /* release file pointer to gem object. */ | ||
275 | drm_gem_object_release(obj); | ||
276 | |||
277 | exynos_gem_obj = to_exynos_gem_obj(obj); | ||
278 | |||
279 | exynos_drm_buf_destroy(obj->dev, exynos_gem_obj->buffer); | ||
280 | |||
281 | kfree(exynos_gem_obj); | ||
282 | } | 297 | } |
283 | 298 | ||
284 | int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | 299 | int exynos_drm_gem_dumb_create(struct drm_file *file_priv, |
@@ -286,6 +301,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | |||
286 | struct drm_mode_create_dumb *args) | 301 | struct drm_mode_create_dumb *args) |
287 | { | 302 | { |
288 | struct exynos_drm_gem_obj *exynos_gem_obj; | 303 | struct exynos_drm_gem_obj *exynos_gem_obj; |
304 | int ret; | ||
289 | 305 | ||
290 | DRM_DEBUG_KMS("%s\n", __FILE__); | 306 | DRM_DEBUG_KMS("%s\n", __FILE__); |
291 | 307 | ||
@@ -298,11 +314,17 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | |||
298 | args->pitch = args->width * args->bpp >> 3; | 314 | args->pitch = args->width * args->bpp >> 3; |
299 | args->size = args->pitch * args->height; | 315 | args->size = args->pitch * args->height; |
300 | 316 | ||
301 | exynos_gem_obj = exynos_drm_gem_create(dev, file_priv, &args->handle, | 317 | exynos_gem_obj = exynos_drm_gem_create(dev, args->size); |
302 | args->size); | ||
303 | if (IS_ERR(exynos_gem_obj)) | 318 | if (IS_ERR(exynos_gem_obj)) |
304 | return PTR_ERR(exynos_gem_obj); | 319 | return PTR_ERR(exynos_gem_obj); |
305 | 320 | ||
321 | ret = exynos_drm_gem_handle_create(&exynos_gem_obj->base, file_priv, | ||
322 | &args->handle); | ||
323 | if (ret) { | ||
324 | exynos_drm_gem_destroy(exynos_gem_obj); | ||
325 | return ret; | ||
326 | } | ||
327 | |||
306 | return 0; | 328 | return 0; |
307 | } | 329 | } |
308 | 330 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 4fe4a8b14818..67cdc9168708 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
@@ -64,10 +64,11 @@ struct exynos_drm_gem_obj { | |||
64 | struct exynos_drm_gem_buf *buffer; | 64 | struct exynos_drm_gem_buf *buffer; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | /* create a new buffer and get a new gem handle. */ | 67 | /* destroy a buffer with gem object */ |
68 | void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj); | ||
69 | |||
70 | /* create a new buffer with gem object */ | ||
68 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, | 71 | struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, |
69 | struct drm_file *file_priv, | ||
70 | unsigned int *handle, | ||
71 | unsigned long size); | 72 | unsigned long size); |
72 | 73 | ||
73 | /* | 74 | /* |