aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoungJun Cho <yj44.cho@samsung.com>2013-02-12 07:23:54 -0500
committerInki Dae <inki.dae@samsung.com>2013-02-21 01:00:26 -0500
commit979c0c7eb0fb969f0621c7017a6a87e6a0e36a4c (patch)
tree6a59898b626301eee3b25a608082163f6a998299
parent5af9f116e6a0e1de675da979a19f95a74ce2aa2e (diff)
drm/exynos: release resources properly when fb creation is failed.
This patch releases allocated resources properly when exynos_user_fb_create() is failed. Signed-off-by: YoungJun Cho <yj44.cho@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 31d4cb19736e..0e04f4ea441f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -221,23 +221,25 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
221 struct drm_mode_fb_cmd2 *mode_cmd) 221 struct drm_mode_fb_cmd2 *mode_cmd)
222{ 222{
223 struct drm_gem_object *obj; 223 struct drm_gem_object *obj;
224 struct exynos_drm_gem_obj *exynos_gem_obj;
224 struct exynos_drm_fb *exynos_fb; 225 struct exynos_drm_fb *exynos_fb;
225 int i, ret; 226 int i, ret;
226 227
227 DRM_DEBUG_KMS("%s\n", __FILE__); 228 DRM_DEBUG_KMS("%s\n", __FILE__);
228 229
229 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
230 if (!obj) {
231 DRM_ERROR("failed to lookup gem object\n");
232 return ERR_PTR(-ENOENT);
233 }
234
235 exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL); 230 exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
236 if (!exynos_fb) { 231 if (!exynos_fb) {
237 DRM_ERROR("failed to allocate exynos drm framebuffer\n"); 232 DRM_ERROR("failed to allocate exynos drm framebuffer\n");
238 return ERR_PTR(-ENOMEM); 233 return ERR_PTR(-ENOMEM);
239 } 234 }
240 235
236 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
237 if (!obj) {
238 DRM_ERROR("failed to lookup gem object\n");
239 ret = -ENOENT;
240 goto err_free;
241 }
242
241 drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); 243 drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd);
242 exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj); 244 exynos_fb->exynos_gem_obj[0] = to_exynos_gem_obj(obj);
243 exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd); 245 exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd);
@@ -245,43 +247,44 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
245 DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt); 247 DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
246 248
247 for (i = 1; i < exynos_fb->buf_cnt; i++) { 249 for (i = 1; i < exynos_fb->buf_cnt; i++) {
248 struct exynos_drm_gem_obj *exynos_gem_obj;
249 int ret;
250
251 obj = drm_gem_object_lookup(dev, file_priv, 250 obj = drm_gem_object_lookup(dev, file_priv,
252 mode_cmd->handles[i]); 251 mode_cmd->handles[i]);
253 if (!obj) { 252 if (!obj) {
254 DRM_ERROR("failed to lookup gem object\n"); 253 DRM_ERROR("failed to lookup gem object\n");
255 kfree(exynos_fb); 254 ret = -ENOENT;
256 return ERR_PTR(-ENOENT); 255 exynos_fb->buf_cnt = i;
256 goto err_unreference;
257 } 257 }
258 258
259 exynos_gem_obj = to_exynos_gem_obj(obj); 259 exynos_gem_obj = to_exynos_gem_obj(obj);
260 exynos_fb->exynos_gem_obj[i] = exynos_gem_obj;
260 261
261 ret = check_fb_gem_memory_type(dev, exynos_gem_obj); 262 ret = check_fb_gem_memory_type(dev, exynos_gem_obj);
262 if (ret < 0) { 263 if (ret < 0) {
263 DRM_ERROR("cannot use this gem memory type for fb.\n"); 264 DRM_ERROR("cannot use this gem memory type for fb.\n");
264 kfree(exynos_fb); 265 goto err_unreference;
265 return ERR_PTR(ret);
266 } 266 }
267
268 exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj);
269 } 267 }
270 268
271 ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs); 269 ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs);
272 if (ret) { 270 if (ret) {
273 for (i = 0; i < exynos_fb->buf_cnt; i++) { 271 DRM_ERROR("failed to init framebuffer.\n");
274 struct exynos_drm_gem_obj *gem_obj; 272 goto err_unreference;
275
276 gem_obj = exynos_fb->exynos_gem_obj[i];
277 drm_gem_object_unreference_unlocked(&gem_obj->base);
278 }
279
280 kfree(exynos_fb);
281 return ERR_PTR(ret);
282 } 273 }
283 274
284 return &exynos_fb->fb; 275 return &exynos_fb->fb;
276
277err_unreference:
278 for (i = 0; i < exynos_fb->buf_cnt; i++) {
279 struct drm_gem_object *obj;
280
281 obj = &exynos_fb->exynos_gem_obj[i]->base;
282 if (obj)
283 drm_gem_object_unreference_unlocked(obj);
284 }
285err_free:
286 kfree(exynos_fb);
287 return ERR_PTR(ret);
285} 288}
286 289
287struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, 290struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb,