summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2014-08-28 11:07:30 +0200
committerChanho Park <chanho61.park@samsung.com>2014-11-18 12:00:45 +0900
commit25d5f5d38eea0b04ee2ae1e217d36026d6fbbbff (patch)
tree7af23bcfc49d8368ea7dd43545557b715743b31d /drivers/gpu/drm
parentc4e369289da7071e8bcd04835ab40fb1a0d0434e (diff)
downloadlinux-3.10-25d5f5d38eea0b04ee2ae1e217d36026d6fbbbff.tar.gz
linux-3.10-25d5f5d38eea0b04ee2ae1e217d36026d6fbbbff.tar.bz2
linux-3.10-25d5f5d38eea0b04ee2ae1e217d36026d6fbbbff.zip
drm/exynos/ipp: free partially allocated resources on error
In case of allocation errors some already allocated buffers were not freed. The patch fixes it. Change-Id: I23447928fb497ad33324fc2affa430bd2de98122 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>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.c70
1 files changed, 31 insertions, 39 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index e2e5dc52e98..8b311ef83cd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -682,6 +682,35 @@ err_unlock:
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,
@@ -707,6 +736,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("%s:m_node[0x%x]ops_id[%d]\n", __func__,
(int)m_node, qbuf->ops_id);
@@ -750,50 +780,12 @@ static struct drm_exynos_ipp_mem_node
return m_node;
err_clear:
- kfree(m_node);
+ ipp_put_mem_node(drm_dev, c_node, m_node);
err_unlock:
mutex_unlock(&c_node->mem_lock);
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("%s:node[0x%x]\n", __func__, (int)m_node);
-
- if (!m_node) {
- DRM_ERROR("invalid dequeue node.\n");
- 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("%s:ops_id[%d]\n", __func__, 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);
-
- mutex_unlock(&c_node->mem_lock);
-
- return 0;
-}
static void ipp_free_event(struct drm_pending_event *event)
{