diff options
author | YoungJun Cho <yj44.cho@samsung.com> | 2014-05-26 04:17:18 -0400 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2014-06-01 13:07:13 -0400 |
commit | 7f5af0597be7cb2eae42fa2ce614d5805b72a74e (patch) | |
tree | 8519df077152d81d13dbde33895b356c66ded9e4 | |
parent | 4e4fe5546de3cfd97921f24d9df4c4f323941729 (diff) |
drm/exynos: ipp: add cmd_lock for cmd_list
This patch adds cmd_lock for cmd_list synchronization.
Signed-off-by: YoungJun Cho <yj44.cho@samsung.com>
Acked-by: Seong-Woo Kim <sw0312.kim@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Tested-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
-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, |