This set of patches contains various improvement and fixes for exynos_drm ipp framework. The patchset is based on exynos-drm-next branch.
IPP framework was tested for regressions on exynos4210-trats target.
In the 2nd version of the series I have included changes proposed by Joonyoung Shim. I have decided to resend whole series because the changes caused merge conflicts and two separate patches have been added to the series. Changes are described in comit messages.
Regards Andrzej
Andrzej Hajda (17): drm/exynos/ipp: remove fake pm callbacks drm/exynos/ipp: cancel works before command node clean drm/exynos/ipp: move file reference from memory to command node drm/exynos/ipp: remove only related commands on file close drm/exynos/ipp: remove unused field in command node drm/exynos/ipp: free partially allocated resources on error drm/exynos/ipp: move nodes cleaning to separate function drm/exynos/ipp: clean memory nodes on command node cleaning drm/exynos/ipp: replace work_struct casting with better constructs drm/exynos/ipp: stop hardware before freeing memory drm/exynos/ipp: remove events during command cleaning drm/exynos/fimc: avoid clearing overflow bits drm/exynos/fimc: do not enable fimc twice drm/exynos/fimc: simplify buffer queuing drm/exynos/fimc: fix source buffer registers drm/exynos/ipp: remove file argument from node related functions drm/exynos/ipp: add file checks for ioctls
drivers/gpu/drm/exynos/exynos_drm_fimc.c | 90 ++----- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 3 +- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 397 ++++++++++++---------------- drivers/gpu/drm/exynos/exynos_drm_ipp.h | 4 +- drivers/gpu/drm/exynos/exynos_drm_rotator.c | 3 +- 5 files changed, 195 insertions(+), 302 deletions(-)
PM callbacks in ipp core do nothing, so the patch removes it.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 51 --------------------------------- 1 file changed, 51 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index c411399..da917ca 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -1808,63 +1808,12 @@ static int ipp_remove(struct platform_device *pdev) return 0; }
-static int ipp_power_ctrl(struct ipp_context *ctx, bool enable) -{ - DRM_DEBUG_KMS("enable[%d]\n", enable); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int ipp_suspend(struct device *dev) -{ - struct ipp_context *ctx = get_ipp_context(dev); - - if (pm_runtime_suspended(dev)) - return 0; - - return ipp_power_ctrl(ctx, false); -} - -static int ipp_resume(struct device *dev) -{ - struct ipp_context *ctx = get_ipp_context(dev); - - if (!pm_runtime_suspended(dev)) - return ipp_power_ctrl(ctx, true); - - return 0; -} -#endif - -#ifdef CONFIG_PM_RUNTIME -static int ipp_runtime_suspend(struct device *dev) -{ - struct ipp_context *ctx = get_ipp_context(dev); - - return ipp_power_ctrl(ctx, false); -} - -static int ipp_runtime_resume(struct device *dev) -{ - struct ipp_context *ctx = get_ipp_context(dev); - - return ipp_power_ctrl(ctx, true); -} -#endif - -static const struct dev_pm_ops ipp_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ipp_suspend, ipp_resume) - SET_RUNTIME_PM_OPS(ipp_runtime_suspend, ipp_runtime_resume, NULL) -}; - struct platform_driver ipp_driver = { .probe = ipp_probe, .remove = ipp_remove, .driver = { .name = "exynos-drm-ipp", .owner = THIS_MODULE, - .pm = &ipp_pm_ops, }, };
All pending works should be canceled prior to its removal.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index da917ca..9770966 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -502,6 +502,11 @@ err_clear: static void ipp_clean_cmd_node(struct ipp_context *ctx, struct drm_exynos_ipp_cmd_node *c_node) { + /* cancel works */ + cancel_work_sync(&c_node->start_work->work); + cancel_work_sync(&c_node->stop_work->work); + cancel_work_sync(&c_node->event_work->work); + /* delete list */ list_del(&c_node->list);
Command node should contain file reference to distinguish commands created by different processes.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 5 ++--- drivers/gpu/drm/exynos/exynos_drm_ipp.h | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 9770966..bbe9968 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -75,7 +75,6 @@ struct drm_exynos_ipp_mem_node { u32 prop_id; u32 buf_id; struct drm_exynos_ipp_buf_info buf_info; - struct drm_file *filp; };
/* @@ -448,6 +447,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, c_node->dev = dev; c_node->property = *property; c_node->state = IPP_STATE_IDLE; + c_node->filp = file;
c_node->start_work = ipp_create_cmd_work(); if (IS_ERR(c_node->start_work)) { @@ -645,7 +645,6 @@ static struct drm_exynos_ipp_mem_node } }
- m_node->filp = file; 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); @@ -677,7 +676,7 @@ static int ipp_put_mem_node(struct drm_device *drm_dev, unsigned long handle = m_node->buf_info.handles[i]; if (handle) exynos_drm_gem_put_dma_addr(drm_dev, handle, - m_node->filp); + c_node->filp); }
/* delete list in queue */ diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h index 6f48d62..0311035 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h @@ -62,6 +62,7 @@ struct drm_exynos_ipp_cmd_work { * @stop_work: stop command work structure. * @event_work: event work structure. * @state: state of command node. + * @filp: associated file pointer. */ struct drm_exynos_ipp_cmd_node { struct device *dev; @@ -78,6 +79,7 @@ struct drm_exynos_ipp_cmd_node { struct drm_exynos_ipp_cmd_work *stop_work; struct drm_exynos_ipp_event_work *event_work; enum drm_exynos_ipp_state state; + struct drm_file *filp; };
/*
On file close driver should remove only command nodes created via this file.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index bbe9968..81f780e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -1681,14 +1681,11 @@ static int ipp_subdrv_open(struct drm_device *drm_dev, struct device *dev, static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev, struct drm_file *file) { - struct drm_exynos_file_private *file_priv = file->driver_priv; struct exynos_drm_ippdrv *ippdrv = NULL; struct ipp_context *ctx = get_ipp_context(dev); struct drm_exynos_ipp_cmd_node *c_node, *tc_node; int count = 0;
- DRM_DEBUG_KMS("for priv[0x%x]\n", (int)file_priv->ipp_dev); - list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { mutex_lock(&ippdrv->cmd_lock); list_for_each_entry_safe(c_node, tc_node, @@ -1696,7 +1693,7 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev, DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]\n", count++, (int)ippdrv);
- if (c_node->dev == file_priv->ipp_dev) { + if (c_node->filp == file) { /* * userland goto unnormal state. process killed. * and close the file.
Since command node have file pointer dev field became useless.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 1 - drivers/gpu/drm/exynos/exynos_drm_ipp.h | 2 -- 2 files changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 81f780e..060a198 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -444,7 +444,6 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, property->prop_id, property->cmd, (int)ippdrv);
/* stored property information and ippdrv in private data */ - c_node->dev = dev; c_node->property = *property; c_node->state = IPP_STATE_IDLE; c_node->filp = file; diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h index 0311035..2a61547 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h @@ -48,7 +48,6 @@ struct drm_exynos_ipp_cmd_work { /* * A structure of command node. * - * @dev: IPP device. * @list: list head to command queue information. * @event_list: list head of event. * @mem_list: list head to source,destination memory queue information. @@ -65,7 +64,6 @@ struct drm_exynos_ipp_cmd_work { * @filp: associated file pointer. */ struct drm_exynos_ipp_cmd_node { - struct device *dev; struct list_head list; struct list_head event_list; struct list_head mem_list[EXYNOS_DRM_OPS_MAX];
In case of allocation errors some already allocated buffers were not freed. The patch fixes it.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 67 ++++++++++++++++----------------- 1 file changed, 32 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 060a198..ab7b74c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -599,6 +599,35 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv, 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, @@ -619,6 +648,7 @@ static struct drm_exynos_ipp_mem_node 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); @@ -634,7 +664,8 @@ static struct drm_exynos_ipp_mem_node qbuf->handle[i], file); if (IS_ERR(addr)) { DRM_ERROR("failed to get addr.\n"); - goto err_clear; + ipp_put_mem_node(drm_dev, c_node, m_node); + return ERR_PTR(-EFAULT); }
buf_info->handles[i] = qbuf->handle[i]; @@ -649,40 +680,6 @@ static struct drm_exynos_ipp_mem_node mutex_unlock(&c_node->mem_lock);
return m_node; - -err_clear: - kfree(m_node); - return ERR_PTR(-EFAULT); -} - -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); - } - - /* delete list in queue */ - list_del(&m_node->list); - kfree(m_node); - - return 0; }
static void ipp_free_event(struct drm_pending_event *event)
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 --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 229 +++++++++++++++----------------- 1 file changed, 106 insertions(+), 123 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index ab7b74c..05f103e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -498,6 +498,108 @@ err_clear: 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, 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; }
-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) { kfree(event); @@ -1257,9 +1276,7 @@ static int ipp_stop_property(struct drm_device *drm_dev, struct exynos_drm_ippdrv *ippdrv, 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 list_head *head; int ret = 0, i;
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 */ ipp_put_event(c_node, NULL);
- mutex_lock(&c_node->mem_lock); - /* check command */ switch (property->cmd) { case IPP_CMD_M2M: - for_each_ipp_ops(i) { - /* source/destination memory list */ - 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; - } - } - } + for_each_ipp_ops(i) + ipp_clean_mem_nodes(drm_dev, c_node, i); break; case IPP_CMD_WB: - /* destination memory list */ - 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; - } - } + ipp_clean_mem_nodes(drm_dev, c_node, EXYNOS_DRM_OPS_DST); break; case IPP_CMD_OUTPUT: - /* source memory list */ - 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; - } - } + ipp_clean_mem_nodes(drm_dev, c_node, EXYNOS_DRM_OPS_SRC); break; default: DRM_ERROR("invalid operations.\n"); @@ -1318,8 +1303,6 @@ static int ipp_stop_property(struct drm_device *drm_dev, }
err_clear: - mutex_unlock(&c_node->mem_lock); - /* stop operations */ if (ippdrv->stop) ippdrv->stop(ippdrv->dev, property->cmd);
The nodes should be removed before removing command node.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 05f103e..857817c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -603,11 +603,16 @@ static void ipp_clean_mem_nodes(struct drm_device *drm_dev, static void ipp_clean_cmd_node(struct ipp_context *ctx, struct drm_exynos_ipp_cmd_node *c_node) { + int i; + /* cancel works */ cancel_work_sync(&c_node->start_work->work); cancel_work_sync(&c_node->stop_work->work); cancel_work_sync(&c_node->event_work->work);
+ for_each_ipp_ops(i) + ipp_clean_mem_nodes(ctx->subdrv.drm_dev, c_node, i); + /* delete list */ list_del(&c_node->list);
Type casting should be avoided if possible. In case of work_struct it can be simply replaced by reference to member field.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 3 +-- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 6 +++--- drivers/gpu/drm/exynos/exynos_drm_rotator.c | 3 +-- 4 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 177e7bc..34367ff 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -1309,7 +1309,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
event_work->ippdrv = ippdrv; event_work->buf_id[EXYNOS_DRM_OPS_DST] = buf_id; - queue_work(ippdrv->event_workq, (struct work_struct *)event_work); + queue_work(ippdrv->event_workq, &event_work->work);
return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 9e3ff16..c6a013f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -1326,8 +1326,7 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id) buf_id[EXYNOS_DRM_OPS_SRC]; event_work->buf_id[EXYNOS_DRM_OPS_DST] = buf_id[EXYNOS_DRM_OPS_DST]; - queue_work(ippdrv->event_workq, - (struct work_struct *)event_work); + queue_work(ippdrv->event_workq, &event_work->work); }
return IRQ_HANDLED; diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 857817c..fff3509 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -790,7 +790,7 @@ static void ipp_handle_cmd_work(struct device *dev,
cmd_work->ippdrv = ippdrv; cmd_work->c_node = c_node; - queue_work(ctx->cmd_workq, (struct work_struct *)cmd_work); + queue_work(ctx->cmd_workq, &cmd_work->work); }
static int ipp_queue_buf_with_run(struct device *dev, @@ -1318,7 +1318,7 @@ err_clear: void ipp_sched_cmd(struct work_struct *work) { struct drm_exynos_ipp_cmd_work *cmd_work = - (struct drm_exynos_ipp_cmd_work *)work; + container_of(work, struct drm_exynos_ipp_cmd_work, work); struct exynos_drm_ippdrv *ippdrv; struct drm_exynos_ipp_cmd_node *c_node; struct drm_exynos_ipp_property *property; @@ -1531,7 +1531,7 @@ err_event_unlock: void ipp_sched_event(struct work_struct *work) { struct drm_exynos_ipp_event_work *event_work = - (struct drm_exynos_ipp_event_work *)work; + container_of(work, struct drm_exynos_ipp_event_work, work); struct exynos_drm_ippdrv *ippdrv; struct drm_exynos_ipp_cmd_node *c_node; int ret; diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index 55af6b4..b6a37d4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -156,8 +156,7 @@ static irqreturn_t rotator_irq_handler(int irq, void *arg) event_work->ippdrv = ippdrv; event_work->buf_id[EXYNOS_DRM_OPS_DST] = rot->cur_buf_id[EXYNOS_DRM_OPS_DST]; - queue_work(ippdrv->event_workq, - (struct work_struct *)event_work); + queue_work(ippdrv->event_workq, &event_work->work); } else { DRM_ERROR("the SFR is set illegally\n"); }
Memory shouldn't be freed when hardware is still running.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index fff3509..341db52 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -1282,12 +1282,15 @@ static int ipp_stop_property(struct drm_device *drm_dev, struct drm_exynos_ipp_cmd_node *c_node) { struct drm_exynos_ipp_property *property = &c_node->property; - int ret = 0, i; + int i;
DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
/* put event */ ipp_put_event(c_node, NULL); + /* stop operations */ + if (ippdrv->stop) + ippdrv->stop(ippdrv->dev, property->cmd);
/* check command */ switch (property->cmd) { @@ -1303,16 +1306,10 @@ static int ipp_stop_property(struct drm_device *drm_dev, break; default: DRM_ERROR("invalid operations.\n"); - ret = -EINVAL; - goto err_clear; + return -EINVAL; }
-err_clear: - /* stop operations */ - if (ippdrv->stop) - ippdrv->stop(ippdrv->dev, property->cmd); - - return ret; + return 0; }
void ipp_sched_cmd(struct work_struct *work)
Events were removed only during stop command, as a result there were memory leaks if program prematurely exited. This patch fixes it.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 155 ++++++++++++++++---------------- 1 file changed, 78 insertions(+), 77 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 341db52..05f0f4e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -600,6 +600,81 @@ static void ipp_clean_mem_nodes(struct drm_device *drm_dev, mutex_unlock(&c_node->mem_lock); }
+static void ipp_free_event(struct drm_pending_event *event) +{ + kfree(event); +} + +static int ipp_get_event(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_send_event *e; + unsigned long flags; + + DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id); + + e = kzalloc(sizeof(*e), GFP_KERNEL); + if (!e) { + spin_lock_irqsave(&drm_dev->event_lock, flags); + file->event_space += sizeof(e->event); + spin_unlock_irqrestore(&drm_dev->event_lock, flags); + return -ENOMEM; + } + + /* make event */ + e->event.base.type = DRM_EXYNOS_IPP_EVENT; + e->event.base.length = sizeof(e->event); + e->event.user_data = qbuf->user_data; + e->event.prop_id = qbuf->prop_id; + e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; + e->base.event = &e->event.base; + e->base.file_priv = file; + e->base.destroy = ipp_free_event; + mutex_lock(&c_node->event_lock); + list_add_tail(&e->base.link, &c_node->event_list); + mutex_unlock(&c_node->event_lock); + + return 0; +} + +static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node, + struct drm_exynos_ipp_queue_buf *qbuf) +{ + struct drm_exynos_ipp_send_event *e, *te; + int count = 0; + + mutex_lock(&c_node->event_lock); + list_for_each_entry_safe(e, te, &c_node->event_list, base.link) { + DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); + + /* + * qbuf == NULL condition means all event deletion. + * stop operations want to delete all event list. + * another case delete only same buf id. + */ + if (!qbuf) { + /* delete list */ + list_del(&e->base.link); + kfree(e); + } + + /* compare buffer id */ + if (qbuf && (qbuf->buf_id == + e->event.buf_id[EXYNOS_DRM_OPS_DST])) { + /* delete list */ + list_del(&e->base.link); + kfree(e); + goto out_unlock; + } + } + +out_unlock: + mutex_unlock(&c_node->event_lock); + return; +} + static void ipp_clean_cmd_node(struct ipp_context *ctx, struct drm_exynos_ipp_cmd_node *c_node) { @@ -610,6 +685,9 @@ static void ipp_clean_cmd_node(struct ipp_context *ctx, cancel_work_sync(&c_node->stop_work->work); cancel_work_sync(&c_node->event_work->work);
+ /* put event */ + ipp_put_event(c_node, NULL); + for_each_ipp_ops(i) ipp_clean_mem_nodes(ctx->subdrv.drm_dev, c_node, i);
@@ -706,81 +784,6 @@ static int ipp_set_mem_node(struct exynos_drm_ippdrv *ippdrv, return ret; }
-static void ipp_free_event(struct drm_pending_event *event) -{ - kfree(event); -} - -static int ipp_get_event(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_send_event *e; - unsigned long flags; - - DRM_DEBUG_KMS("ops_id[%d]buf_id[%d]\n", qbuf->ops_id, qbuf->buf_id); - - e = kzalloc(sizeof(*e), GFP_KERNEL); - if (!e) { - spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); - spin_unlock_irqrestore(&drm_dev->event_lock, flags); - return -ENOMEM; - } - - /* make event */ - e->event.base.type = DRM_EXYNOS_IPP_EVENT; - e->event.base.length = sizeof(e->event); - e->event.user_data = qbuf->user_data; - e->event.prop_id = qbuf->prop_id; - e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; - e->base.event = &e->event.base; - e->base.file_priv = file; - e->base.destroy = ipp_free_event; - mutex_lock(&c_node->event_lock); - list_add_tail(&e->base.link, &c_node->event_list); - mutex_unlock(&c_node->event_lock); - - return 0; -} - -static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node, - struct drm_exynos_ipp_queue_buf *qbuf) -{ - struct drm_exynos_ipp_send_event *e, *te; - int count = 0; - - mutex_lock(&c_node->event_lock); - list_for_each_entry_safe(e, te, &c_node->event_list, base.link) { - DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); - - /* - * qbuf == NULL condition means all event deletion. - * stop operations want to delete all event list. - * another case delete only same buf id. - */ - if (!qbuf) { - /* delete list */ - list_del(&e->base.link); - kfree(e); - } - - /* compare buffer id */ - if (qbuf && (qbuf->buf_id == - e->event.buf_id[EXYNOS_DRM_OPS_DST])) { - /* delete list */ - list_del(&e->base.link); - kfree(e); - goto out_unlock; - } - } - -out_unlock: - mutex_unlock(&c_node->event_lock); - return; -} - static void ipp_handle_cmd_work(struct device *dev, struct exynos_drm_ippdrv *ippdrv, struct drm_exynos_ipp_cmd_work *cmd_work, @@ -1286,8 +1289,6 @@ static int ipp_stop_property(struct drm_device *drm_dev,
DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
- /* put event */ - ipp_put_event(c_node, NULL); /* stop operations */ if (ippdrv->stop) ippdrv->stop(ippdrv->dev, property->cmd);
Overflow bits shall be cleared by H/W.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 34367ff..6dc9c41 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -341,9 +341,6 @@ static bool fimc_check_ovf(struct fimc_context *ctx) fimc_set_bits(ctx, EXYNOS_CIWDOFST, EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB | EXYNOS_CIWDOFST_CLROVFICR); - fimc_clear_bits(ctx, EXYNOS_CIWDOFST, - EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB | - EXYNOS_CIWDOFST_CLROVFICR);
dev_err(ippdrv->dev, "occurred overflow at %d, status 0x%x.\n", ctx->id, status);
The patch removes redundant H/W activation.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 6dc9c41..62ba033 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -1598,12 +1598,9 @@ static int fimc_ippdrv_start(struct device *dev, enum drm_exynos_ipp_cmd cmd)
fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK);
- if (cmd == IPP_CMD_M2M) { + if (cmd == IPP_CMD_M2M) fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
- fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID); - } - return 0; }
The patch removes redundant checks, redundant HW reads and simplifies code.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- v2: - fixed bit cleaning operation --- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 64 ++++++++------------------------ 1 file changed, 15 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 62ba033..59ba8bb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -1126,67 +1126,34 @@ static int fimc_dst_set_size(struct device *dev, int swap, return 0; }
-static int fimc_dst_get_buf_count(struct fimc_context *ctx) -{ - u32 cfg, buf_num; - - cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ); - - buf_num = hweight32(cfg); - - DRM_DEBUG_KMS("buf_num[%d]\n", buf_num); - - return buf_num; -} - -static int fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, +static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, enum drm_exynos_ipp_buf_type buf_type) { - struct exynos_drm_ippdrv *ippdrv = &ctx->ippdrv; - bool enable; - u32 cfg; - u32 mask = 0x00000001 << buf_id; - int ret = 0; unsigned long flags; + u32 buf_num; + u32 cfg;
DRM_DEBUG_KMS("buf_id[%d]buf_type[%d]\n", buf_id, buf_type);
spin_lock_irqsave(&ctx->lock, flags);
- /* mask register set */ cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
- switch (buf_type) { - case IPP_BUF_ENQUEUE: - enable = true; - break; - case IPP_BUF_DEQUEUE: - enable = false; - break; - default: - dev_err(ippdrv->dev, "invalid buf ctrl parameter.\n"); - ret = -EINVAL; - goto err_unlock; - } + if (buf_type == IPP_BUF_ENQUEUE) + cfg |= (1 << buf_id); + else + cfg &= ~(1 << buf_id);
- /* sequence id */ - cfg &= ~mask; - cfg |= (enable << buf_id); fimc_write(ctx, cfg, EXYNOS_CIFCNTSEQ);
- /* interrupt enable */ - if (buf_type == IPP_BUF_ENQUEUE && - fimc_dst_get_buf_count(ctx) >= FIMC_BUF_START) - fimc_mask_irq(ctx, true); + buf_num = hweight32(cfg);
- /* interrupt disable */ - if (buf_type == IPP_BUF_DEQUEUE && - fimc_dst_get_buf_count(ctx) <= FIMC_BUF_STOP) + if (buf_type == IPP_BUF_ENQUEUE && buf_num >= FIMC_BUF_START) + fimc_mask_irq(ctx, true); + else if (buf_type == IPP_BUF_DEQUEUE && buf_num <= FIMC_BUF_STOP) fimc_mask_irq(ctx, false);
-err_unlock: spin_unlock_irqrestore(&ctx->lock, flags); - return ret; }
static int fimc_dst_set_addr(struct device *dev, @@ -1244,7 +1211,9 @@ static int fimc_dst_set_addr(struct device *dev, break; }
- return fimc_dst_set_buf_seq(ctx, buf_id, buf_type); + fimc_dst_set_buf_seq(ctx, buf_id, buf_type); + + return 0; }
static struct exynos_drm_ipp_ops fimc_dst_ops = { @@ -1299,10 +1268,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
DRM_DEBUG_KMS("buf_id[%d]\n", buf_id);
- if (fimc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE) < 0) { - DRM_ERROR("failed to dequeue.\n"); - return IRQ_HANDLED; - } + fimc_dst_set_buf_seq(ctx, buf_id, IPP_BUF_DEQUEUE);
event_work->ippdrv = ippdrv; event_work->buf_id[EXYNOS_DRM_OPS_DST] = buf_id;
FIMC in default mode of operation uses only one input buffer, but the driver used also second buffer, as a result only the first frame was processed correctly. The patch fixes it.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 59ba8bb..e2c43b4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -722,24 +722,24 @@ static int fimc_src_set_addr(struct device *dev, case IPP_BUF_ENQUEUE: config = &property->config[EXYNOS_DRM_OPS_SRC]; fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_Y], - EXYNOS_CIIYSA(buf_id)); + EXYNOS_CIIYSA0);
if (config->fmt == DRM_FORMAT_YVU420) { fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR], - EXYNOS_CIICBSA(buf_id)); + EXYNOS_CIICBSA0); fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB], - EXYNOS_CIICRSA(buf_id)); + EXYNOS_CIICRSA0); } else { fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CB], - EXYNOS_CIICBSA(buf_id)); + EXYNOS_CIICBSA0); fimc_write(ctx, buf_info->base[EXYNOS_DRM_PLANAR_CR], - EXYNOS_CIICRSA(buf_id)); + EXYNOS_CIICRSA0); } break; case IPP_BUF_DEQUEUE: - fimc_write(ctx, 0x0, EXYNOS_CIIYSA(buf_id)); - fimc_write(ctx, 0x0, EXYNOS_CIICBSA(buf_id)); - fimc_write(ctx, 0x0, EXYNOS_CIICRSA(buf_id)); + fimc_write(ctx, 0x0, EXYNOS_CIIYSA0); + fimc_write(ctx, 0x0, EXYNOS_CIICBSA0); + fimc_write(ctx, 0x0, EXYNOS_CIICRSA0); break; default: /* bypass */
Since file pointer is preserved in c_node passing it as argument in node functions is redundant.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 05f0f4e..fc8bb67 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -529,7 +529,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
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) { @@ -560,7 +559,7 @@ static struct drm_exynos_ipp_mem_node dma_addr_t *addr;
addr = exynos_drm_gem_get_dma_addr(drm_dev, - qbuf->handle[i], file); + qbuf->handle[i], c_node->filp); if (IS_ERR(addr)) { DRM_ERROR("failed to get addr.\n"); ipp_put_mem_node(drm_dev, c_node, m_node); @@ -606,7 +605,6 @@ static void ipp_free_event(struct drm_pending_event *event) }
static int ipp_get_event(struct drm_device *drm_dev, - struct drm_file *file, struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf) { @@ -618,7 +616,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) { spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); + c_node->filp->event_space += sizeof(e->event); spin_unlock_irqrestore(&drm_dev->event_lock, flags); return -ENOMEM; } @@ -630,7 +628,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e->event.prop_id = qbuf->prop_id; e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; e->base.event = &e->event.base; - e->base.file_priv = file; + e->base.file_priv = c_node->filp; e->base.destroy = ipp_free_event; mutex_lock(&c_node->event_lock); list_add_tail(&e->base.link, &c_node->event_list); @@ -899,7 +897,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, /* find command node */ c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, qbuf->prop_id); - if (!c_node) { + if (!c_node || c_node->filp != file) { DRM_ERROR("failed to get command node.\n"); return -ENODEV; } @@ -908,7 +906,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, switch (qbuf->buf_type) { case IPP_BUF_ENQUEUE: /* get memory node */ - m_node = ipp_get_mem_node(drm_dev, file, c_node, qbuf); + m_node = ipp_get_mem_node(drm_dev, c_node, qbuf); if (IS_ERR(m_node)) { DRM_ERROR("failed to get m_node.\n"); return PTR_ERR(m_node); @@ -921,7 +919,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, */ if (qbuf->ops_id == EXYNOS_DRM_OPS_DST) { /* get event for destination buffer */ - ret = ipp_get_event(drm_dev, file, c_node, qbuf); + ret = ipp_get_event(drm_dev, c_node, qbuf); if (ret) { DRM_ERROR("failed to get event.\n"); goto err_clean_node;
Hi Andrzej,
On 08/28/2014 06:07 PM, Andrzej Hajda wrote:
Since file pointer is preserved in c_node passing it as argument in node functions is redundant.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com
drivers/gpu/drm/exynos/exynos_drm_ipp.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 05f0f4e..fc8bb67 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -529,7 +529,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
static struct drm_exynos_ipp_mem_node *ipp_get_mem_node(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf)struct drm_file *file,
{ @@ -560,7 +559,7 @@ static struct drm_exynos_ipp_mem_node dma_addr_t *addr;
addr = exynos_drm_gem_get_dma_addr(drm_dev,
qbuf->handle[i], file);
qbuf->handle[i], c_node->filp); if (IS_ERR(addr)) { DRM_ERROR("failed to get addr.\n"); ipp_put_mem_node(drm_dev, c_node, m_node);
@@ -606,7 +605,6 @@ static void ipp_free_event(struct drm_pending_event *event) }
static int ipp_get_event(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf)struct drm_file *file,
{ @@ -618,7 +616,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) { spin_lock_irqsave(&drm_dev->event_lock, flags);
file->event_space += sizeof(e->event);
spin_unlock_irqrestore(&drm_dev->event_lock, flags); return -ENOMEM; }c_node->filp->event_space += sizeof(e->event);
@@ -630,7 +628,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e->event.prop_id = qbuf->prop_id; e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; e->base.event = &e->event.base;
- e->base.file_priv = file;
- e->base.file_priv = c_node->filp; e->base.destroy = ipp_free_event; mutex_lock(&c_node->event_lock); list_add_tail(&e->base.link, &c_node->event_list);
@@ -899,7 +897,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, /* find command node */ c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, qbuf->prop_id);
- if (!c_node) {
- if (!c_node || c_node->filp != file) {
I think this should go to patch 17.
Thanks.
DRM_ERROR("failed to get command node.\n"); return -ENODEV;
} @@ -908,7 +906,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, switch (qbuf->buf_type) { case IPP_BUF_ENQUEUE: /* get memory node */
m_node = ipp_get_mem_node(drm_dev, file, c_node, qbuf);
if (IS_ERR(m_node)) { DRM_ERROR("failed to get m_node.\n"); return PTR_ERR(m_node);m_node = ipp_get_mem_node(drm_dev, c_node, qbuf);
@@ -921,7 +919,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, */ if (qbuf->ops_id == EXYNOS_DRM_OPS_DST) { /* get event for destination buffer */
ret = ipp_get_event(drm_dev, file, c_node, qbuf);
ret = ipp_get_event(drm_dev, c_node, qbuf); if (ret) { DRM_ERROR("failed to get event.\n"); goto err_clean_node;
Since file pointer is preserved in c_node passing it as argument in node functions is redundant.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- v3: - file check moved to next patch --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 05f0f4e..9e9714a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -529,7 +529,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
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) { @@ -560,7 +559,7 @@ static struct drm_exynos_ipp_mem_node dma_addr_t *addr;
addr = exynos_drm_gem_get_dma_addr(drm_dev, - qbuf->handle[i], file); + qbuf->handle[i], c_node->filp); if (IS_ERR(addr)) { DRM_ERROR("failed to get addr.\n"); ipp_put_mem_node(drm_dev, c_node, m_node); @@ -606,7 +605,6 @@ static void ipp_free_event(struct drm_pending_event *event) }
static int ipp_get_event(struct drm_device *drm_dev, - struct drm_file *file, struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf) { @@ -618,7 +616,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) { spin_lock_irqsave(&drm_dev->event_lock, flags); - file->event_space += sizeof(e->event); + c_node->filp->event_space += sizeof(e->event); spin_unlock_irqrestore(&drm_dev->event_lock, flags); return -ENOMEM; } @@ -630,7 +628,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e->event.prop_id = qbuf->prop_id; e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; e->base.event = &e->event.base; - e->base.file_priv = file; + e->base.file_priv = c_node->filp; e->base.destroy = ipp_free_event; mutex_lock(&c_node->event_lock); list_add_tail(&e->base.link, &c_node->event_list); @@ -908,7 +906,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, switch (qbuf->buf_type) { case IPP_BUF_ENQUEUE: /* get memory node */ - m_node = ipp_get_mem_node(drm_dev, file, c_node, qbuf); + m_node = ipp_get_mem_node(drm_dev, c_node, qbuf); if (IS_ERR(m_node)) { DRM_ERROR("failed to get m_node.\n"); return PTR_ERR(m_node); @@ -921,7 +919,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, */ if (qbuf->ops_id == EXYNOS_DRM_OPS_DST) { /* get event for destination buffer */ - ret = ipp_get_event(drm_dev, file, c_node, qbuf); + ret = ipp_get_event(drm_dev, c_node, qbuf); if (ret) { DRM_ERROR("failed to get event.\n"); goto err_clean_node;
On 09/02/2014 09:55 PM, Andrzej Hajda wrote:
Since file pointer is preserved in c_node passing it as argument in node functions is redundant.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com
v3:
- file check moved to next patch
drivers/gpu/drm/exynos/exynos_drm_ipp.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
About both patch 16 and 17
Reviewed-by: Joonyoung Shim jy0922.shim@samsung.com
Thanks.
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 05f0f4e..9e9714a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -529,7 +529,6 @@ static int ipp_put_mem_node(struct drm_device *drm_dev,
static struct drm_exynos_ipp_mem_node *ipp_get_mem_node(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf)struct drm_file *file,
{ @@ -560,7 +559,7 @@ static struct drm_exynos_ipp_mem_node dma_addr_t *addr;
addr = exynos_drm_gem_get_dma_addr(drm_dev,
qbuf->handle[i], file);
qbuf->handle[i], c_node->filp); if (IS_ERR(addr)) { DRM_ERROR("failed to get addr.\n"); ipp_put_mem_node(drm_dev, c_node, m_node);
@@ -606,7 +605,6 @@ static void ipp_free_event(struct drm_pending_event *event) }
static int ipp_get_event(struct drm_device *drm_dev,
struct drm_exynos_ipp_cmd_node *c_node, struct drm_exynos_ipp_queue_buf *qbuf)struct drm_file *file,
{ @@ -618,7 +616,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) { spin_lock_irqsave(&drm_dev->event_lock, flags);
file->event_space += sizeof(e->event);
spin_unlock_irqrestore(&drm_dev->event_lock, flags); return -ENOMEM; }c_node->filp->event_space += sizeof(e->event);
@@ -630,7 +628,7 @@ static int ipp_get_event(struct drm_device *drm_dev, e->event.prop_id = qbuf->prop_id; e->event.buf_id[EXYNOS_DRM_OPS_DST] = qbuf->buf_id; e->base.event = &e->event.base;
- e->base.file_priv = file;
- e->base.file_priv = c_node->filp; e->base.destroy = ipp_free_event; mutex_lock(&c_node->event_lock); list_add_tail(&e->base.link, &c_node->event_list);
@@ -908,7 +906,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, switch (qbuf->buf_type) { case IPP_BUF_ENQUEUE: /* get memory node */
m_node = ipp_get_mem_node(drm_dev, file, c_node, qbuf);
if (IS_ERR(m_node)) { DRM_ERROR("failed to get m_node.\n"); return PTR_ERR(m_node);m_node = ipp_get_mem_node(drm_dev, c_node, qbuf);
@@ -921,7 +919,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, */ if (qbuf->ops_id == EXYNOS_DRM_OPS_DST) { /* get event for destination buffer */
ret = ipp_get_event(drm_dev, file, c_node, qbuf);
ret = ipp_get_event(drm_dev, c_node, qbuf); if (ret) { DRM_ERROR("failed to get event.\n"); goto err_clean_node;
Process should not have access to ipp nodes created by another process. The patch adds necessary checks.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index fc8bb67..d233cfc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -318,7 +318,8 @@ static void ipp_print_property(struct drm_exynos_ipp_property *property, sz->hsize, sz->vsize, config->flip, config->degree); }
-static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) +static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property, + struct drm_file *file) { struct exynos_drm_ippdrv *ippdrv; struct drm_exynos_ipp_cmd_node *c_node; @@ -339,8 +340,12 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) */ mutex_lock(&ippdrv->cmd_lock); list_for_each_entry(c_node, &ippdrv->cmd_list, list) { - if ((c_node->property.prop_id == prop_id) && - (c_node->state == IPP_STATE_STOP)) { + if (c_node->property.prop_id == prop_id) { + if (c_node->filp != file) + break; + if (c_node->state != IPP_STATE_STOP) + break; + mutex_unlock(&ippdrv->cmd_lock); DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n", property->cmd, (int)ippdrv); @@ -418,7 +423,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, */ if (property->prop_id) { DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id); - return ipp_find_and_set_property(property); + return ipp_find_and_set_property(property, file); }
/* find ipp driver using ipp id */ @@ -1032,7 +1037,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, cmd_ctrl->prop_id); - if (!c_node) { + if (!c_node || c_node->filp != file) { DRM_ERROR("invalid command node list.\n"); return -ENODEV; }
Hi Andrzej,
On 08/28/2014 06:07 PM, Andrzej Hajda wrote:
Process should not have access to ipp nodes created by another process. The patch adds necessary checks.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com
drivers/gpu/drm/exynos/exynos_drm_ipp.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index fc8bb67..d233cfc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -318,7 +318,8 @@ static void ipp_print_property(struct drm_exynos_ipp_property *property, sz->hsize, sz->vsize, config->flip, config->degree); }
-static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) +static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property,
struct drm_file *file)
This is ok, but i think ipp_find_and_set_property function is some duplicated. If we add function to get c_node from struct exynos_drm_ippdrv, it's easy to remove ipp_find_and_set_property.
Thanks.
{ struct exynos_drm_ippdrv *ippdrv; struct drm_exynos_ipp_cmd_node *c_node; @@ -339,8 +340,12 @@ static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) */ mutex_lock(&ippdrv->cmd_lock); list_for_each_entry(c_node, &ippdrv->cmd_list, list) {
if ((c_node->property.prop_id == prop_id) &&
(c_node->state == IPP_STATE_STOP)) {
if (c_node->property.prop_id == prop_id) {
if (c_node->filp != file)
break;
if (c_node->state != IPP_STATE_STOP)
break;
mutex_unlock(&ippdrv->cmd_lock); DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n", property->cmd, (int)ippdrv);
@@ -418,7 +423,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, */ if (property->prop_id) { DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id);
return ipp_find_and_set_property(property);
return ipp_find_and_set_property(property, file);
}
/* find ipp driver using ipp id */
@@ -1032,7 +1037,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, cmd_ctrl->prop_id);
- if (!c_node) {
- if (!c_node || c_node->filp != file) { DRM_ERROR("invalid command node list.\n"); return -ENODEV; }
Process should not have access to ipp nodes created by another process. The patch adds necessary checks. It also simplifies lookup for command node.
Signed-off-by: Andrzej Hajda a.hajda@samsung.com --- v3: - added file check from previous commit - simplified c_node lookup --- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 69 +++++++++++---------------------- 1 file 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 9e9714a..4f36a9d 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, sz->hsize, sz->vsize, config->flip, config->degree); }
-static int ipp_find_and_set_property(struct drm_exynos_ipp_property *property) -{ - struct exynos_drm_ippdrv *ippdrv; - struct drm_exynos_ipp_cmd_node *c_node; - u32 prop_id = property->prop_id; - - DRM_DEBUG_KMS("prop_id[%d]\n", prop_id); - - ippdrv = ipp_find_drv_by_handle(prop_id); - if (IS_ERR(ippdrv)) { - DRM_ERROR("failed to get ipp driver.\n"); - return -EINVAL; - } - - /* - * Find command node using command list in ippdrv. - * when we find this command no using prop_id. - * return property information set in this command node. - */ - mutex_lock(&ippdrv->cmd_lock); - list_for_each_entry(c_node, &ippdrv->cmd_list, list) { - if ((c_node->property.prop_id == prop_id) && - (c_node->state == IPP_STATE_STOP)) { - mutex_unlock(&ippdrv->cmd_lock); - DRM_DEBUG_KMS("found cmd[%d]ippdrv[0x%x]\n", - property->cmd, (int)ippdrv); - - c_node->property = *property; - return 0; - } - } - mutex_unlock(&ippdrv->cmd_lock); - - DRM_ERROR("failed to search property.\n"); - - return -EINVAL; -} - static struct drm_exynos_ipp_cmd_work *ipp_create_cmd_work(void) { 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, struct drm_exynos_ipp_property *property = data; struct exynos_drm_ippdrv *ippdrv; struct drm_exynos_ipp_cmd_node *c_node; + u32 prop_id; int ret, i;
if (!ctx) { @@ -403,6 +366,8 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, return -EINVAL; }
+ prop_id = property->prop_id; + /* * This is log print for user application property. * user application set various property. @@ -411,14 +376,24 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, ipp_print_property(property, i);
/* - * set property ioctl generated new prop_id. - * but in this case already asigned prop_id using old set property. - * e.g PAUSE state. this case supports find current prop_id and use it - * instead of allocation. + * In case prop_id is not zero try to set existing property. */ - if (property->prop_id) { - DRM_DEBUG_KMS("prop_id[%d]\n", property->prop_id); - return ipp_find_and_set_property(property); + if (prop_id) { + c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, prop_id); + + if (!c_node || c_node->filp != file) { + DRM_DEBUG_KMS("prop_id[%d] not found\n", prop_id); + return -EINVAL; + } + + if (c_node->state != IPP_STATE_STOP) { + DRM_DEBUG_KMS("prop_id[%d] not stopped\n", prop_id); + return -EINVAL; + } + + c_node->property = *property; + + return 0; }
/* find ipp driver using ipp id */ @@ -897,7 +872,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data, /* find command node */ c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, qbuf->prop_id); - if (!c_node) { + if (!c_node || c_node->filp != file) { DRM_ERROR("failed to get command node.\n"); return -ENODEV; } @@ -1032,7 +1007,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
c_node = ipp_find_obj(&ctx->prop_idr, &ctx->prop_lock, cmd_ctrl->prop_id); - if (!c_node) { + if (!c_node || c_node->filp != file) { DRM_ERROR("invalid command node list.\n"); return -ENODEV; }
On 2014년 08월 28일 18:07, Andrzej Hajda wrote:
This set of patches contains various improvement and fixes for exynos_drm ipp framework. The patchset is based on exynos-drm-next branch.
IPP framework was tested for regressions on exynos4210-trats target.
In the 2nd version of the series I have included changes proposed by Joonyoung Shim. I have decided to resend whole series because the changes caused merge conflicts and two separate patches have been added to the series. Changes are described in comit messages.
Applied.
Thanks, Inki Dae
Regards Andrzej
Andrzej Hajda (17): drm/exynos/ipp: remove fake pm callbacks drm/exynos/ipp: cancel works before command node clean drm/exynos/ipp: move file reference from memory to command node drm/exynos/ipp: remove only related commands on file close drm/exynos/ipp: remove unused field in command node drm/exynos/ipp: free partially allocated resources on error drm/exynos/ipp: move nodes cleaning to separate function drm/exynos/ipp: clean memory nodes on command node cleaning drm/exynos/ipp: replace work_struct casting with better constructs drm/exynos/ipp: stop hardware before freeing memory drm/exynos/ipp: remove events during command cleaning drm/exynos/fimc: avoid clearing overflow bits drm/exynos/fimc: do not enable fimc twice drm/exynos/fimc: simplify buffer queuing drm/exynos/fimc: fix source buffer registers drm/exynos/ipp: remove file argument from node related functions drm/exynos/ipp: add file checks for ioctls
drivers/gpu/drm/exynos/exynos_drm_fimc.c | 90 ++----- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 3 +- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 397 ++++++++++++---------------- drivers/gpu/drm/exynos/exynos_drm_ipp.h | 4 +- drivers/gpu/drm/exynos/exynos_drm_rotator.c | 3 +- 5 files changed, 195 insertions(+), 302 deletions(-)
dri-devel@lists.freedesktop.org