Commit 220db6fe authored by YoungJun Cho's avatar YoungJun Cho Committed by Inki Dae

drm/exynos: ipp: rearrange c_node->mem_lock using routines

The c_node->mem_list[] should be protected with
c_node->mem_lock.
Signed-off-by: default avatarYoungJun Cho <yj44.cho@samsung.com>
Acked-by: default avatarSeong-Woo Kim <sw0312.kim@samsung.com>
Acked-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Tested-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 075436b0
...@@ -584,8 +584,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node) ...@@ -584,8 +584,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
struct list_head *head; struct list_head *head;
int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, }; int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, };
mutex_lock(&c_node->mem_lock);
for_each_ipp_ops(i) { for_each_ipp_ops(i) {
/* source/destination memory list */ /* source/destination memory list */
head = &c_node->mem_list[i]; head = &c_node->mem_list[i];
...@@ -614,8 +612,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node) ...@@ -614,8 +612,6 @@ static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
ret = max(count[EXYNOS_DRM_OPS_SRC], ret = max(count[EXYNOS_DRM_OPS_SRC],
count[EXYNOS_DRM_OPS_DST]); count[EXYNOS_DRM_OPS_DST]);
mutex_unlock(&c_node->mem_lock);
return ret; return ret;
} }
...@@ -658,16 +654,13 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv, ...@@ -658,16 +654,13 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
return -EFAULT; return -EFAULT;
} }
mutex_lock(&c_node->mem_lock);
DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
/* get operations callback */ /* get operations callback */
ops = ippdrv->ops[m_node->ops_id]; ops = ippdrv->ops[m_node->ops_id];
if (!ops) { if (!ops) {
DRM_ERROR("not support ops.\n"); DRM_ERROR("not support ops.\n");
ret = -EFAULT; return -EFAULT;
goto err_unlock;
} }
/* set address and enable irq */ /* set address and enable irq */
...@@ -676,12 +669,10 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv, ...@@ -676,12 +669,10 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
m_node->buf_id, IPP_BUF_ENQUEUE); m_node->buf_id, IPP_BUF_ENQUEUE);
if (ret) { if (ret) {
DRM_ERROR("failed to set addr.\n"); DRM_ERROR("failed to set addr.\n");
goto err_unlock; return ret;
} }
} }
err_unlock:
mutex_unlock(&c_node->mem_lock);
return ret; return ret;
} }
...@@ -696,11 +687,9 @@ static struct drm_exynos_ipp_mem_node ...@@ -696,11 +687,9 @@ static struct drm_exynos_ipp_mem_node
void *addr; void *addr;
int i; int i;
mutex_lock(&c_node->mem_lock);
m_node = kzalloc(sizeof(*m_node), GFP_KERNEL); m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
if (!m_node) if (!m_node)
goto err_unlock; return ERR_PTR(-ENOMEM);
/* clear base address for error handling */ /* clear base address for error handling */
memset(&buf_info, 0x0, sizeof(buf_info)); memset(&buf_info, 0x0, sizeof(buf_info));
...@@ -734,15 +723,14 @@ static struct drm_exynos_ipp_mem_node ...@@ -734,15 +723,14 @@ static struct drm_exynos_ipp_mem_node
m_node->filp = file; m_node->filp = file;
m_node->buf_info = buf_info; m_node->buf_info = buf_info;
mutex_lock(&c_node->mem_lock);
list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]); list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]);
mutex_unlock(&c_node->mem_lock); mutex_unlock(&c_node->mem_lock);
return m_node; return m_node;
err_clear: err_clear:
kfree(m_node); kfree(m_node);
err_unlock:
mutex_unlock(&c_node->mem_lock);
return ERR_PTR(-EFAULT); return ERR_PTR(-EFAULT);
} }
...@@ -759,13 +747,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev, ...@@ -759,13 +747,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
return -EFAULT; return -EFAULT;
} }
if (list_empty(&m_node->list)) {
DRM_ERROR("empty memory node.\n");
return -ENOMEM;
}
mutex_lock(&c_node->mem_lock);
DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id); DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
/* put gem buffer */ /* put gem buffer */
...@@ -780,8 +761,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev, ...@@ -780,8 +761,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
list_del(&m_node->list); list_del(&m_node->list);
kfree(m_node); kfree(m_node);
mutex_unlock(&c_node->mem_lock);
return 0; return 0;
} }
...@@ -894,7 +873,9 @@ static int ipp_queue_buf_with_run(struct device *dev, ...@@ -894,7 +873,9 @@ static int ipp_queue_buf_with_run(struct device *dev,
return 0; return 0;
} }
mutex_lock(&c_node->mem_lock);
if (!ipp_check_mem_list(c_node)) { if (!ipp_check_mem_list(c_node)) {
mutex_unlock(&c_node->mem_lock);
DRM_DEBUG_KMS("empty memory.\n"); DRM_DEBUG_KMS("empty memory.\n");
return 0; return 0;
} }
...@@ -911,10 +892,12 @@ static int ipp_queue_buf_with_run(struct device *dev, ...@@ -911,10 +892,12 @@ static int ipp_queue_buf_with_run(struct device *dev,
} else { } else {
ret = ipp_set_mem_node(ippdrv, c_node, m_node); ret = ipp_set_mem_node(ippdrv, c_node, m_node);
if (ret) { if (ret) {
mutex_unlock(&c_node->mem_lock);
DRM_ERROR("failed to set m node.\n"); DRM_ERROR("failed to set m node.\n");
return ret; return ret;
} }
} }
mutex_unlock(&c_node->mem_lock);
return 0; return 0;
} }
...@@ -926,12 +909,14 @@ static void ipp_clean_queue_buf(struct drm_device *drm_dev, ...@@ -926,12 +909,14 @@ static void ipp_clean_queue_buf(struct drm_device *drm_dev,
struct drm_exynos_ipp_mem_node *m_node, *tm_node; struct drm_exynos_ipp_mem_node *m_node, *tm_node;
/* delete list */ /* delete list */
mutex_lock(&c_node->mem_lock);
list_for_each_entry_safe(m_node, tm_node, list_for_each_entry_safe(m_node, tm_node,
&c_node->mem_list[qbuf->ops_id], list) { &c_node->mem_list[qbuf->ops_id], list) {
if (m_node->buf_id == qbuf->buf_id && if (m_node->buf_id == qbuf->buf_id &&
m_node->ops_id == qbuf->ops_id) m_node->ops_id == qbuf->ops_id)
ipp_put_mem_node(drm_dev, c_node, m_node); ipp_put_mem_node(drm_dev, c_node, m_node);
} }
mutex_unlock(&c_node->mem_lock);
} }
int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
...@@ -1267,9 +1252,11 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ...@@ -1267,9 +1252,11 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
/* store command info in ippdrv */ /* store command info in ippdrv */
ippdrv->c_node = c_node; ippdrv->c_node = c_node;
mutex_lock(&c_node->mem_lock);
if (!ipp_check_mem_list(c_node)) { if (!ipp_check_mem_list(c_node)) {
DRM_DEBUG_KMS("empty memory.\n"); DRM_DEBUG_KMS("empty memory.\n");
return -ENOMEM; ret = -ENOMEM;
goto err_unlock;
} }
/* set current property in ippdrv */ /* set current property in ippdrv */
...@@ -1277,7 +1264,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ...@@ -1277,7 +1264,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
if (ret) { if (ret) {
DRM_ERROR("failed to set property.\n"); DRM_ERROR("failed to set property.\n");
ippdrv->c_node = NULL; ippdrv->c_node = NULL;
return ret; goto err_unlock;
} }
/* check command */ /* check command */
...@@ -1292,7 +1279,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ...@@ -1292,7 +1279,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
if (!m_node) { if (!m_node) {
DRM_ERROR("failed to get node.\n"); DRM_ERROR("failed to get node.\n");
ret = -EFAULT; ret = -EFAULT;
return ret; goto err_unlock;
} }
DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node); DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node);
...@@ -1300,7 +1287,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ...@@ -1300,7 +1287,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
ret = ipp_set_mem_node(ippdrv, c_node, m_node); ret = ipp_set_mem_node(ippdrv, c_node, m_node);
if (ret) { if (ret) {
DRM_ERROR("failed to set m node.\n"); DRM_ERROR("failed to set m node.\n");
return ret; goto err_unlock;
} }
} }
break; break;
...@@ -1312,7 +1299,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ...@@ -1312,7 +1299,7 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
ret = ipp_set_mem_node(ippdrv, c_node, m_node); ret = ipp_set_mem_node(ippdrv, c_node, m_node);
if (ret) { if (ret) {
DRM_ERROR("failed to set m node.\n"); DRM_ERROR("failed to set m node.\n");
return ret; goto err_unlock;
} }
} }
break; break;
...@@ -1324,14 +1311,16 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ...@@ -1324,14 +1311,16 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
ret = ipp_set_mem_node(ippdrv, c_node, m_node); ret = ipp_set_mem_node(ippdrv, c_node, m_node);
if (ret) { if (ret) {
DRM_ERROR("failed to set m node.\n"); DRM_ERROR("failed to set m node.\n");
return ret; goto err_unlock;
} }
} }
break; break;
default: default:
DRM_ERROR("invalid operations.\n"); DRM_ERROR("invalid operations.\n");
return -EINVAL; ret = -EINVAL;
goto err_unlock;
} }
mutex_unlock(&c_node->mem_lock);
DRM_DEBUG_KMS("cmd[%d]\n", property->cmd); DRM_DEBUG_KMS("cmd[%d]\n", property->cmd);
...@@ -1340,11 +1329,17 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv, ...@@ -1340,11 +1329,17 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
ret = ippdrv->start(ippdrv->dev, property->cmd); ret = ippdrv->start(ippdrv->dev, property->cmd);
if (ret) { if (ret) {
DRM_ERROR("failed to start ops.\n"); DRM_ERROR("failed to start ops.\n");
ippdrv->c_node = NULL;
return ret; return ret;
} }
} }
return 0; return 0;
err_unlock:
mutex_unlock(&c_node->mem_lock);
ippdrv->c_node = NULL;
return ret;
} }
static int ipp_stop_property(struct drm_device *drm_dev, static int ipp_stop_property(struct drm_device *drm_dev,
...@@ -1361,6 +1356,8 @@ static int ipp_stop_property(struct drm_device *drm_dev, ...@@ -1361,6 +1356,8 @@ static int ipp_stop_property(struct drm_device *drm_dev,
/* put event */ /* put event */
ipp_put_event(c_node, NULL); ipp_put_event(c_node, NULL);
mutex_lock(&c_node->mem_lock);
/* check command */ /* check command */
switch (property->cmd) { switch (property->cmd) {
case IPP_CMD_M2M: case IPP_CMD_M2M:
...@@ -1410,6 +1407,8 @@ static int ipp_stop_property(struct drm_device *drm_dev, ...@@ -1410,6 +1407,8 @@ static int ipp_stop_property(struct drm_device *drm_dev,
} }
err_clear: err_clear:
mutex_unlock(&c_node->mem_lock);
/* stop operations */ /* stop operations */
if (ippdrv->stop) if (ippdrv->stop)
ippdrv->stop(ippdrv->dev, property->cmd); ippdrv->stop(ippdrv->dev, property->cmd);
...@@ -1521,9 +1520,11 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, ...@@ -1521,9 +1520,11 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
return 0; return 0;
} }
mutex_lock(&c_node->mem_lock);
if (!ipp_check_mem_list(c_node)) { if (!ipp_check_mem_list(c_node)) {
DRM_DEBUG_KMS("empty memory.\n"); DRM_DEBUG_KMS("empty memory.\n");
return 0; ret = 0;
goto err_mem_unlock;
} }
/* check command */ /* check command */
...@@ -1537,7 +1538,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, ...@@ -1537,7 +1538,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
struct drm_exynos_ipp_mem_node, list); struct drm_exynos_ipp_mem_node, list);
if (!m_node) { if (!m_node) {
DRM_ERROR("empty memory node.\n"); DRM_ERROR("empty memory node.\n");
return -ENOMEM; ret = -ENOMEM;
goto err_mem_unlock;
} }
tbuf_id[i] = m_node->buf_id; tbuf_id[i] = m_node->buf_id;
...@@ -1559,7 +1561,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, ...@@ -1559,7 +1561,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
m_node = ipp_find_mem_node(c_node, &qbuf); m_node = ipp_find_mem_node(c_node, &qbuf);
if (!m_node) { if (!m_node) {
DRM_ERROR("empty memory node.\n"); DRM_ERROR("empty memory node.\n");
return -ENOMEM; ret = -ENOMEM;
goto err_mem_unlock;
} }
tbuf_id[EXYNOS_DRM_OPS_DST] = m_node->buf_id; tbuf_id[EXYNOS_DRM_OPS_DST] = m_node->buf_id;
...@@ -1576,7 +1579,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, ...@@ -1576,7 +1579,8 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
struct drm_exynos_ipp_mem_node, list); struct drm_exynos_ipp_mem_node, list);
if (!m_node) { if (!m_node) {
DRM_ERROR("empty memory node.\n"); DRM_ERROR("empty memory node.\n");
return -ENOMEM; ret = -ENOMEM;
goto err_mem_unlock;
} }
tbuf_id[EXYNOS_DRM_OPS_SRC] = m_node->buf_id; tbuf_id[EXYNOS_DRM_OPS_SRC] = m_node->buf_id;
...@@ -1587,8 +1591,10 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, ...@@ -1587,8 +1591,10 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
break; break;
default: default:
DRM_ERROR("invalid operations.\n"); DRM_ERROR("invalid operations.\n");
return -EINVAL; ret = -EINVAL;
goto err_mem_unlock;
} }
mutex_unlock(&c_node->mem_lock);
if (tbuf_id[EXYNOS_DRM_OPS_DST] != buf_id[EXYNOS_DRM_OPS_DST]) if (tbuf_id[EXYNOS_DRM_OPS_DST] != buf_id[EXYNOS_DRM_OPS_DST])
DRM_ERROR("failed to match buf_id[%d %d]prop_id[%d]\n", DRM_ERROR("failed to match buf_id[%d %d]prop_id[%d]\n",
...@@ -1627,6 +1633,10 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv, ...@@ -1627,6 +1633,10 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
property->cmd, property->prop_id, tbuf_id[EXYNOS_DRM_OPS_DST]); property->cmd, property->prop_id, tbuf_id[EXYNOS_DRM_OPS_DST]);
return 0; return 0;
err_mem_unlock:
mutex_unlock(&c_node->mem_lock);
return ret;
} }
void ipp_sched_event(struct work_struct *work) void ipp_sched_event(struct work_struct *work)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment