diff options
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_ipp.c | 69 |
1 files changed, 22 insertions, 47 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 9e9714afca1d..4f36a9d91926 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c | |||
@@ -318,44 +318,6 @@ static void ipp_print_property(struct drm_exynos_ipp_property *property, | |||
318 | sz->hsize, sz->vsize, config->flip, config->degree); | 318 | sz->hsize, sz->vsize, config->flip, config->degree); |
319 | } | 319 | } |
320 | 320 | ||
321 | static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) | ||
322 | { | ||
323 | struct exynos_drm_ippdrv *ippdrv; | ||
324 | struct drm_exynos_ipp_cmd_node *c_node; | ||
325 | u32 prop_id = property->prop_id; | ||
326 | |||
327 | DRM_DEBUG_KMS("prop_id[%d]\n", prop_id); | ||
328 | |||
329 | ippdrv = ipp_find_drv_by_handle(prop_id); | ||
330 | if (IS_ERR(ippdrv)) { | ||
331 | DRM_ERROR("failed to get ipp driver.\n"); | ||
332 | return -EINVAL; | ||
333 | } | ||
334 | |||
335 | /* | ||
336 | * Find command node using command list in ippdrv. | ||
337 | * when we find this command no using prop_id. | ||
338 | * return property information set in this command node. | ||
339 | */ | ||
340 | mutex_lock(&ippdrv->cmd_lock); | ||
341 | list_for_each_entry(c_node, &ippdrv->cmd_list, list) { | ||
342 | if ((c_node->property.prop_id == prop_id) && | ||
343 | (c_node->state == IPP_STATE_STOP)) { | ||
344 | mutex_unlock(&ippdrv->cmd_lock); | ||
345 | DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n", | ||
346 | property->cmd, (int)ippdrv); | ||
347 | |||
348 | c_node->property = *property; | ||
349 | return 0; | ||
350 | } | ||
351 | } | ||
352 | mutex_unlock(&ippdrv->cmd_lock); | ||
353 | |||
354 | DRM_ERROR("failed to search property.\n"); | ||
355 | |||
356 | return -EINVAL; | ||
357 | } | ||
358 | |||
359 | static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void) | 321 | static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void) |
360 | { | 322 | { |
361 | struct drm_exynos_ipp_cmd_work *cmd_work; | 323 | struct drm_exynos_ipp_cmd_work *cmd_work; |
@@ -391,6 +353,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, | |||
391 | struct drm_exynos_ipp_property *property = data; | 353 | struct drm_exynos_ipp_property *property = data; |
392 | struct exynos_drm_ippdrv *ippdrv; | 354 | struct exynos_drm_ippdrv *ippdrv; |
393 | struct drm_exynos_ipp_cmd_node *c_node; | 355 | struct drm_exynos_ipp_cmd_node *c_node; |
356 | u32 prop_id; | ||
394 | int ret, i; | 357 | int ret, i; |
395 | 358 | ||
396 | if (!ctx) { | 359 | if (!ctx) { |
@@ -403,6 +366,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, | |||
403 | return -EINVAL; | 366 | return -EINVAL; |
404 | } | 367 | } |
405 | 368 | ||
369 | prop_id = property->prop_id; | ||
370 | |||
406 | /* | 371 | /* |
407 | * This is log print for user application property. | 372 | * This is log print for user application property. |
408 | * user application set various property. | 373 | * user application set various property. |
@@ -411,14 +376,24 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, | |||
411 | ipp_print_property(property, i); | 376 | ipp_print_property(property, i); |
412 | 377 | ||
413 | /* | 378 | /* |
414 | * set property ioctl generated new prop_id. | 379 | * In case prop_id is not zero try to set existing property. |
415 | * but in this case already asigned prop_id using old set property. | ||
416 | * e.g PAUSE state. this case supports find current prop_id and use it | ||
417 | * instead of allocation. | ||
418 | */ | 380 | */ |
419 | if (property->prop_id) { | 381 | if (prop_id) { |
420 | DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id); | 382 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, prop_id); |
421 | return ipp_find_and_set_property(property); | 383 | |
384 | if (!c_node || c_node->filp != file) { | ||
385 | DRM_DEBUG_KMS("prop_id[%d] not found\n", prop_id); | ||
386 | return -EINVAL; | ||
387 | } | ||
388 | |||
389 | if (c_node->state != IPP_STATE_STOP) { | ||
390 | DRM_DEBUG_KMS("prop_id[%d] not stopped\n", prop_id); | ||
391 | return -EINVAL; | ||
392 | } | ||
393 | |||
394 | c_node->property = *property; | ||
395 | |||
396 | return 0; | ||
422 | } | 397 | } |
423 | 398 | ||
424 | /* find ipp driver using ipp id */ | 399 | /* find ipp driver using ipp id */ |
@@ -897,7 +872,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, | |||
897 | /* find command node */ | 872 | /* find command node */ |
898 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, | 873 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, |
899 | qbuf->prop_id); | 874 | qbuf->prop_id); |
900 | if (!c_node) { | 875 | if (!c_node || c_node->filp != file) { |
901 | DRM_ERROR("failed to get command node.\n"); | 876 | DRM_ERROR("failed to get command node.\n"); |
902 | return -ENODEV; | 877 | return -ENODEV; |
903 | } | 878 | } |
@@ -1032,7 +1007,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data, | |||
1032 | 1007 | ||
1033 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, | 1008 | c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, |
1034 | cmd_ctrl->prop_id); | 1009 | cmd_ctrl->prop_id); |
1035 | if (!c_node) { | 1010 | if (!c_node || c_node->filp != file) { |
1036 | DRM_ERROR("invalid command node list.\n"); | 1011 | DRM_ERROR("invalid command node list.\n"); |
1037 | return -ENODEV; | 1012 | return -ENODEV; |
1038 | } | 1013 | } |