drm/exynos/ipp: move nodes cleaning to separate function

The patch introduces ipp_clean_mem_nodes function which replaces
redundant code. Additionally memory node function definitions
are moved up to increase its visibility.

Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
Andrzej Hajda 2014-08-28 11:07:31 +02:00 committed by Inki Dae
parent 6602ffb849
commit c4a856a733
1 changed files with 106 additions and 123 deletions

View File

@ -498,6 +498,108 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
return ret; return ret;
} }
static int ipp_put_mem_node(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node,
struct drm_exynos_ipp_mem_node *m_node)
{
int i;
DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
if (!m_node) {
DRM_ERROR("invalid dequeue node.\n");
return -EFAULT;
}
DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
/* put gem buffer */
for_each_ipp_planar(i) {
unsigned long handle = m_node->buf_info.handles[i];
if (handle)
exynos_drm_gem_put_dma_addr(drm_dev, handle,
c_node->filp);
}
list_del(&m_node->list);
kfree(m_node);
return 0;
}
static struct drm_exynos_ipp_mem_node
*ipp_get_mem_node(struct drm_device *drm_dev,
struct drm_file *file,
struct drm_exynos_ipp_cmd_node *c_node,
struct drm_exynos_ipp_queue_buf *qbuf)
{
struct drm_exynos_ipp_mem_node *m_node;
struct drm_exynos_ipp_buf_info *buf_info;
int i;
m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
if (!m_node)
return ERR_PTR(-ENOMEM);
buf_info = &m_node->buf_info;
/* operations, buffer id */
m_node->ops_id = qbuf->ops_id;
m_node->prop_id = qbuf->prop_id;
m_node->buf_id = qbuf->buf_id;
INIT_LIST_HEAD(&m_node->list);
DRM_DEBUG_KMS("m_node[0x%x]ops_id[%d]\n", (int)m_node, qbuf->ops_id);
DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]\n", qbuf->prop_id, m_node->buf_id);
for_each_ipp_planar(i) {
DRM_DEBUG_KMS("i[%d]handle[0x%x]\n", i, qbuf->handle[i]);
/* get dma address by handle */
if (qbuf->handle[i]) {
dma_addr_t *addr;
addr = exynos_drm_gem_get_dma_addr(drm_dev,
qbuf->handle[i], file);
if (IS_ERR(addr)) {
DRM_ERROR("failed to get addr.\n");
ipp_put_mem_node(drm_dev, c_node, m_node);
return ERR_PTR(-EFAULT);
}
buf_info->handles[i] = qbuf->handle[i];
buf_info->base[i] = *addr;
DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%lx]\n", i,
buf_info->base[i], buf_info->handles[i]);
}
}
mutex_lock(&c_node->mem_lock);
list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]);
mutex_unlock(&c_node->mem_lock);
return m_node;
}
static void ipp_clean_mem_nodes(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node, int ops)
{
struct drm_exynos_ipp_mem_node *m_node, *tm_node;
struct list_head *head = &c_node->mem_list[ops];
mutex_lock(&c_node->mem_lock);
list_for_each_entry_safe(m_node, tm_node, head, list) {
int ret;
ret = ipp_put_mem_node(drm_dev, c_node, m_node);
if (ret)
DRM_ERROR("failed to put m_node.\n");
}
mutex_unlock(&c_node->mem_lock);
}
static void ipp_clean_cmd_node(struct ipp_context *ctx, static void ipp_clean_cmd_node(struct ipp_context *ctx,
struct drm_exynos_ipp_cmd_node *c_node) struct drm_exynos_ipp_cmd_node *c_node)
{ {
@ -599,89 +701,6 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv,
return ret; return ret;
} }
static int ipp_put_mem_node(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node,
struct drm_exynos_ipp_mem_node *m_node)
{
int i;
DRM_DEBUG_KMS("node[0x%x]\n", (int)m_node);
if (!m_node) {
DRM_ERROR("invalid dequeue node.\n");
return -EFAULT;
}
DRM_DEBUG_KMS("ops_id[%d]\n", m_node->ops_id);
/* put gem buffer */
for_each_ipp_planar(i) {
unsigned long handle = m_node->buf_info.handles[i];
if (handle)
exynos_drm_gem_put_dma_addr(drm_dev, handle,
c_node->filp);
}
list_del(&m_node->list);
kfree(m_node);
return 0;
}
static struct drm_exynos_ipp_mem_node
*ipp_get_mem_node(struct drm_device *drm_dev,
struct drm_file *file,
struct drm_exynos_ipp_cmd_node *c_node,
struct drm_exynos_ipp_queue_buf *qbuf)
{
struct drm_exynos_ipp_mem_node *m_node;
struct drm_exynos_ipp_buf_info *buf_info;
int i;
m_node = kzalloc(sizeof(*m_node), GFP_KERNEL);
if (!m_node)
return ERR_PTR(-ENOMEM);
buf_info = &m_node->buf_info;
/* operations, buffer id */
m_node->ops_id = qbuf->ops_id;
m_node->prop_id = qbuf->prop_id;
m_node->buf_id = qbuf->buf_id;
INIT_LIST_HEAD(&m_node->list);
DRM_DEBUG_KMS("m_node[0x%x]ops_id[%d]\n", (int)m_node, qbuf->ops_id);
DRM_DEBUG_KMS("prop_id[%d]buf_id[%d]\n", qbuf->prop_id, m_node->buf_id);
for_each_ipp_planar(i) {
DRM_DEBUG_KMS("i[%d]handle[0x%x]\n", i, qbuf->handle[i]);
/* get dma address by handle */
if (qbuf->handle[i]) {
dma_addr_t *addr;
addr = exynos_drm_gem_get_dma_addr(drm_dev,
qbuf->handle[i], file);
if (IS_ERR(addr)) {
DRM_ERROR("failed to get addr.\n");
ipp_put_mem_node(drm_dev, c_node, m_node);
return ERR_PTR(-EFAULT);
}
buf_info->handles[i] = qbuf->handle[i];
buf_info->base[i] = *addr;
DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%lx]\n", i,
buf_info->base[i], buf_info->handles[i]);
}
}
mutex_lock(&c_node->mem_lock);
list_add_tail(&m_node->list, &c_node->mem_list[qbuf->ops_id]);
mutex_unlock(&c_node->mem_lock);
return m_node;
}
static void ipp_free_event(struct drm_pending_event *event) static void ipp_free_event(struct drm_pending_event *event)
{ {
kfree(event); kfree(event);
@ -1257,9 +1276,7 @@ static int ipp_stop_property(struct drm_device *drm_dev,
struct exynos_drm_ippdrv *ippdrv, struct exynos_drm_ippdrv *ippdrv,
struct drm_exynos_ipp_cmd_node *c_node) struct drm_exynos_ipp_cmd_node *c_node)
{ {
struct drm_exynos_ipp_mem_node *m_node, *tm_node;
struct drm_exynos_ipp_property *property = &c_node->property; struct drm_exynos_ipp_property *property = &c_node->property;
struct list_head *head;
int ret = 0, i; int ret = 0, i;
DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id); DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
@ -1267,49 +1284,17 @@ 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:
for_each_ipp_ops(i) { for_each_ipp_ops(i)
/* source/destination memory list */ ipp_clean_mem_nodes(drm_dev, c_node, i);
head = &c_node->mem_list[i];
list_for_each_entry_safe(m_node, tm_node,
head, list) {
ret = ipp_put_mem_node(drm_dev, c_node,
m_node);
if (ret) {
DRM_ERROR("failed to put m_node.\n");
goto err_clear;
}
}
}
break; break;
case IPP_CMD_WB: case IPP_CMD_WB:
/* destination memory list */ ipp_clean_mem_nodes(drm_dev, c_node, EXYNOS_DRM_OPS_DST);
head = &c_node->mem_list[EXYNOS_DRM_OPS_DST];
list_for_each_entry_safe(m_node, tm_node, head, list) {
ret = ipp_put_mem_node(drm_dev, c_node, m_node);
if (ret) {
DRM_ERROR("failed to put m_node.\n");
goto err_clear;
}
}
break; break;
case IPP_CMD_OUTPUT: case IPP_CMD_OUTPUT:
/* source memory list */ ipp_clean_mem_nodes(drm_dev, c_node, EXYNOS_DRM_OPS_SRC);
head = &c_node->mem_list[EXYNOS_DRM_OPS_SRC];
list_for_each_entry_safe(m_node, tm_node, head, list) {
ret = ipp_put_mem_node(drm_dev, c_node, m_node);
if (ret) {
DRM_ERROR("failed to put m_node.\n");
goto err_clear;
}
}
break; break;
default: default:
DRM_ERROR("invalid operations.\n"); DRM_ERROR("invalid operations.\n");
@ -1318,8 +1303,6 @@ 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);