diff options
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_ipp.c | 20 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_ipp.h | 2 |
2 files changed, 20 insertions, 2 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 0d85433dab8b..b60ae54ef82b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c | |||
| @@ -284,9 +284,14 @@ static struct exynos_drm_ippdrv *ipp_find_drv_by_handle(u32 prop_id) | |||
| 284 | list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { | 284 | list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { |
| 285 | DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv); | 285 | DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv); |
| 286 | 286 | ||
| 287 | list_for_each_entry(c_node, &ippdrv->cmd_list, list) | 287 | mutex_lock(&ippdrv->cmd_lock); |
| 288 | if (c_node->property.prop_id == prop_id) | 288 | list_for_each_entry(c_node, &ippdrv->cmd_list, list) { |
| 289 | if (c_node->property.prop_id == prop_id) { | ||
| 290 | mutex_unlock(&ippdrv->cmd_lock); | ||
| 289 | return ippdrv; | 291 | return ippdrv; |
| 292 | } | ||
| 293 | } | ||
| 294 | mutex_unlock(&ippdrv->cmd_lock); | ||
| 290 | } | 295 | } |
| 291 | 296 | ||
| 292 | return ERR_PTR(-ENODEV); | 297 | return ERR_PTR(-ENODEV); |
| @@ -318,6 +323,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data, | |||
| 318 | if (!prop_list->ipp_id) { | 323 | if (!prop_list->ipp_id) { |
| 319 | list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) | 324 | list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) |
| 320 | count++; | 325 | count++; |
| 326 | |||
| 321 | /* | 327 | /* |
| 322 | * Supports ippdrv list count for user application. | 328 | * Supports ippdrv list count for user application. |
| 323 | * First step user application getting ippdrv count. | 329 | * First step user application getting ippdrv count. |
| @@ -379,9 +385,11 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) | |||
| 379 | * when we find this command no using prop_id. | 385 | * when we find this command no using prop_id. |
| 380 | * return property information set in this command node. | 386 | * return property information set in this command node. |
| 381 | */ | 387 | */ |
| 388 | mutex_lock(&ippdrv->cmd_lock); | ||
| 382 | list_for_each_entry(c_node, &ippdrv->cmd_list, list) { | 389 | list_for_each_entry(c_node, &ippdrv->cmd_list, list) { |
| 383 | if ((c_node->property.prop_id == prop_id) && | 390 | if ((c_node->property.prop_id == prop_id) && |
| 384 | (c_node->state == IPP_STATE_STOP)) { | 391 | (c_node->state == IPP_STATE_STOP)) { |
| 392 | mutex_unlock(&ippdrv->cmd_lock); | ||
| 385 | DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n", | 393 | DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n", |
| 386 | property->cmd, (int)ippdrv); | 394 | property->cmd, (int)ippdrv); |
| 387 | 395 | ||
| @@ -389,6 +397,7 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) | |||
| 389 | return 0; | 397 | return 0; |
| 390 | } | 398 | } |
| 391 | } | 399 | } |
| 400 | mutex_unlock(&ippdrv->cmd_lock); | ||
| 392 | 401 | ||
| 393 | DRM_ERROR("failed to search property.\n"); | 402 | DRM_ERROR("failed to search property.\n"); |
| 394 | 403 | ||
| @@ -519,7 +528,9 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, | |||
| 519 | 528 | ||
| 520 | INIT_LIST_HEAD(&c_node->event_list); | 529 | INIT_LIST_HEAD(&c_node->event_list); |
| 521 | list_splice_init(&priv->event_list, &c_node->event_list); | 530 | list_splice_init(&priv->event_list, &c_node->event_list); |
| 531 | mutex_lock(&ippdrv->cmd_lock); | ||
| 522 | list_add_tail(&c_node->list, &ippdrv->cmd_list); | 532 | list_add_tail(&c_node->list, &ippdrv->cmd_list); |
| 533 | mutex_unlock(&ippdrv->cmd_lock); | ||
| 523 | 534 | ||
| 524 | /* make dedicated state without m2m */ | 535 | /* make dedicated state without m2m */ |
| 525 | if (!ipp_is_m2m_cmd(property->cmd)) | 536 | if (!ipp_is_m2m_cmd(property->cmd)) |
| @@ -1110,10 +1121,12 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data, | |||
| 1110 | 1121 | ||
| 1111 | c_node->state = IPP_STATE_STOP; | 1122 | c_node->state = IPP_STATE_STOP; |
| 1112 | ippdrv->dedicated = false; | 1123 | ippdrv->dedicated = false; |
| 1124 | mutex_lock(&ippdrv->cmd_lock); | ||
| 1113 | ipp_clean_cmd_node(c_node); | 1125 | ipp_clean_cmd_node(c_node); |
| 1114 | 1126 | ||
| 1115 | if (list_empty(&ippdrv->cmd_list)) | 1127 | if (list_empty(&ippdrv->cmd_list)) |
| 1116 | pm_runtime_put_sync(ippdrv->dev); | 1128 | pm_runtime_put_sync(ippdrv->dev); |
| 1129 | mutex_unlock(&ippdrv->cmd_lock); | ||
| 1117 | break; | 1130 | break; |
| 1118 | case IPP_CTRL_PAUSE: | 1131 | case IPP_CTRL_PAUSE: |
| 1119 | cmd_work = c_node->stop_work; | 1132 | cmd_work = c_node->stop_work; |
| @@ -1688,6 +1701,7 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev) | |||
| 1688 | ippdrv->event_workq = ctx->event_workq; | 1701 | ippdrv->event_workq = ctx->event_workq; |
| 1689 | ippdrv->sched_event = ipp_sched_event; | 1702 | ippdrv->sched_event = ipp_sched_event; |
| 1690 | INIT_LIST_HEAD(&ippdrv->cmd_list); | 1703 | INIT_LIST_HEAD(&ippdrv->cmd_list); |
| 1704 | mutex_init(&ippdrv->cmd_lock); | ||
| 1691 | 1705 | ||
| 1692 | if (is_drm_iommu_supported(drm_dev)) { | 1706 | if (is_drm_iommu_supported(drm_dev)) { |
| 1693 | ret = drm_iommu_attach_device(drm_dev, ippdrv->dev); | 1707 | ret = drm_iommu_attach_device(drm_dev, ippdrv->dev); |
| @@ -1757,6 +1771,7 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev, | |||
| 1757 | DRM_DEBUG_KMS("for priv[0x%x]\n", (int)priv); | 1771 | DRM_DEBUG_KMS("for priv[0x%x]\n", (int)priv); |
| 1758 | 1772 | ||
| 1759 | list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { | 1773 | list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { |
| 1774 | mutex_lock(&ippdrv->cmd_lock); | ||
| 1760 | list_for_each_entry_safe(c_node, tc_node, | 1775 | list_for_each_entry_safe(c_node, tc_node, |
| 1761 | &ippdrv->cmd_list, list) { | 1776 | &ippdrv->cmd_list, list) { |
| 1762 | DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", | 1777 | DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", |
| @@ -1781,6 +1796,7 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev, | |||
| 1781 | pm_runtime_put_sync(ippdrv->dev); | 1796 | pm_runtime_put_sync(ippdrv->dev); |
| 1782 | } | 1797 | } |
| 1783 | } | 1798 | } |
| 1799 | mutex_unlock(&ippdrv->cmd_lock); | ||
| 1784 | } | 1800 | } |
| 1785 | 1801 | ||
| 1786 | kfree(priv); | 1802 | kfree(priv); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h index fbb80ac5311d..09cb5a20540c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h | |||
| @@ -148,6 +148,7 @@ struct exynos_drm_ipp_ops { | |||
| 148 | * @event_workq: event work queue. | 148 | * @event_workq: event work queue. |
| 149 | * @c_node: current command information. | 149 | * @c_node: current command information. |
| 150 | * @cmd_list: list head for command information. | 150 | * @cmd_list: list head for command information. |
| 151 | * @cmd_lock: lock for synchronization of access to cmd_list. | ||
| 151 | * @prop_list: property informations of current ipp driver. | 152 | * @prop_list: property informations of current ipp driver. |
| 152 | * @check_property: check property about format, size, buffer. | 153 | * @check_property: check property about format, size, buffer. |
| 153 | * @reset: reset ipp block. | 154 | * @reset: reset ipp block. |
| @@ -165,6 +166,7 @@ struct exynos_drm_ippdrv { | |||
| 165 | struct workqueue_struct *event_workq; | 166 | struct workqueue_struct *event_workq; |
| 166 | struct drm_exynos_ipp_cmd_node *c_node; | 167 | struct drm_exynos_ipp_cmd_node *c_node; |
| 167 | struct list_head cmd_list; | 168 | struct list_head cmd_list; |
| 169 | struct mutex cmd_lock; | ||
| 168 | struct drm_exynos_ipp_prop_list prop_list; | 170 | struct drm_exynos_ipp_prop_list prop_list; |
| 169 | 171 | ||
| 170 | int (*check_property)(struct device *dev, | 172 | int (*check_property)(struct device *dev, |
