|
@@ -129,9 +129,6 @@ void exynos_platform_device_ipp_unregister(void)
|
|
|
|
|
|
int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
|
|
|
{
|
|
|
- if (!ippdrv)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
mutex_lock(&exynos_drm_ippdrv_lock);
|
|
|
list_add_tail(&ippdrv->drv_list, &exynos_drm_ippdrv_list);
|
|
|
mutex_unlock(&exynos_drm_ippdrv_lock);
|
|
@@ -141,9 +138,6 @@ int exynos_drm_ippdrv_register(struct exynos_drm_ippdrv *ippdrv)
|
|
|
|
|
|
int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
|
|
|
{
|
|
|
- if (!ippdrv)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
mutex_lock(&exynos_drm_ippdrv_lock);
|
|
|
list_del(&ippdrv->drv_list);
|
|
|
mutex_unlock(&exynos_drm_ippdrv_lock);
|
|
@@ -151,20 +145,15 @@ int exynos_drm_ippdrv_unregister(struct exynos_drm_ippdrv *ippdrv)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj,
|
|
|
- u32 *idp)
|
|
|
+static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj)
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
|
- /* do the allocation under our mutexlock */
|
|
|
mutex_lock(lock);
|
|
|
ret = idr_alloc(id_idr, obj, 1, 0, GFP_KERNEL);
|
|
|
mutex_unlock(lock);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
|
|
|
- *idp = ret;
|
|
|
- return 0;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static void ipp_remove_id(struct idr *id_idr, struct mutex *lock, u32 id)
|
|
@@ -178,35 +167,25 @@ static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id)
|
|
|
{
|
|
|
void *obj;
|
|
|
|
|
|
- DRM_DEBUG_KMS("id[%d]\n", id);
|
|
|
-
|
|
|
mutex_lock(lock);
|
|
|
-
|
|
|
- /* find object using handle */
|
|
|
obj = idr_find(id_idr, id);
|
|
|
- if (!obj) {
|
|
|
- DRM_ERROR("failed to find object.\n");
|
|
|
- mutex_unlock(lock);
|
|
|
- return ERR_PTR(-ENODEV);
|
|
|
- }
|
|
|
-
|
|
|
mutex_unlock(lock);
|
|
|
|
|
|
return obj;
|
|
|
}
|
|
|
|
|
|
-static inline bool ipp_check_dedicated(struct exynos_drm_ippdrv *ippdrv,
|
|
|
- enum drm_exynos_ipp_cmd cmd)
|
|
|
+static int ipp_check_driver(struct exynos_drm_ippdrv *ippdrv,
|
|
|
+ struct drm_exynos_ipp_property *property)
|
|
|
{
|
|
|
- /*
|
|
|
- * check dedicated flag and WB, OUTPUT operation with
|
|
|
- * power on state.
|
|
|
- */
|
|
|
- if (ippdrv->dedicated || (!ipp_is_m2m_cmd(cmd) &&
|
|
|
- !pm_runtime_suspended(ippdrv->dev)))
|
|
|
- return true;
|
|
|
+ if (ippdrv->dedicated || (!ipp_is_m2m_cmd(property->cmd) &&
|
|
|
+ !pm_runtime_suspended(ippdrv->dev)))
|
|
|
+ return -EBUSY;
|
|
|
|
|
|
- return false;
|
|
|
+ if (ippdrv->check_property &&
|
|
|
+ ippdrv->check_property(ippdrv->dev, property))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static struct exynos_drm_ippdrv *ipp_find_driver(struct ipp_context *ctx,
|
|
@@ -214,62 +193,30 @@ static struct exynos_drm_ippdrv *ipp_find_driver(struct ipp_context *ctx,
|
|
|
{
|
|
|
struct exynos_drm_ippdrv *ippdrv;
|
|
|
u32 ipp_id = property->ipp_id;
|
|
|
-
|
|
|
- DRM_DEBUG_KMS("ipp_id[%d]\n", ipp_id);
|
|
|
+ int ret;
|
|
|
|
|
|
if (ipp_id) {
|
|
|
- /* find ipp driver using idr */
|
|
|
- ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock,
|
|
|
- ipp_id);
|
|
|
- if (IS_ERR(ippdrv)) {
|
|
|
- DRM_ERROR("not found ipp%d driver.\n", ipp_id);
|
|
|
- return ippdrv;
|
|
|
+ ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock, ipp_id);
|
|
|
+ if (!ippdrv) {
|
|
|
+ DRM_DEBUG("ipp%d driver not found\n", ipp_id);
|
|
|
+ return ERR_PTR(-ENODEV);
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * WB, OUTPUT opertion not supported multi-operation.
|
|
|
- * so, make dedicated state at set property ioctl.
|
|
|
- * when ipp driver finished operations, clear dedicated flags.
|
|
|
- */
|
|
|
- if (ipp_check_dedicated(ippdrv, property->cmd)) {
|
|
|
- DRM_ERROR("already used choose device.\n");
|
|
|
- return ERR_PTR(-EBUSY);
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * This is necessary to find correct device in ipp drivers.
|
|
|
- * ipp drivers have different abilities,
|
|
|
- * so need to check property.
|
|
|
- */
|
|
|
- if (ippdrv->check_property &&
|
|
|
- ippdrv->check_property(ippdrv->dev, property)) {
|
|
|
- DRM_ERROR("not support property.\n");
|
|
|
- return ERR_PTR(-EINVAL);
|
|
|
+ ret = ipp_check_driver(ippdrv, property);
|
|
|
+ if (ret < 0) {
|
|
|
+ DRM_DEBUG("ipp%d driver check error %d\n", ipp_id, ret);
|
|
|
+ return ERR_PTR(ret);
|
|
|
}
|
|
|
|
|
|
return ippdrv;
|
|
|
} else {
|
|
|
- /*
|
|
|
- * This case is search all ipp driver for finding.
|
|
|
- * user application don't set ipp_id in this case,
|
|
|
- * so ipp subsystem search correct driver in driver list.
|
|
|
- */
|
|
|
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
|
|
|
- if (ipp_check_dedicated(ippdrv, property->cmd)) {
|
|
|
- DRM_DEBUG_KMS("used device.\n");
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (ippdrv->check_property &&
|
|
|
- ippdrv->check_property(ippdrv->dev, property)) {
|
|
|
- DRM_DEBUG_KMS("not support property.\n");
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- return ippdrv;
|
|
|
+ ret = ipp_check_driver(ippdrv, property);
|
|
|
+ if (ret == 0)
|
|
|
+ return ippdrv;
|
|
|
}
|
|
|
|
|
|
- DRM_ERROR("not support ipp driver operations.\n");
|
|
|
+ DRM_DEBUG("cannot find driver suitable for given property.\n");
|
|
|
}
|
|
|
|
|
|
return ERR_PTR(-ENODEV);
|
|
@@ -308,8 +255,7 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
|
|
|
struct drm_file *file)
|
|
|
{
|
|
|
struct drm_exynos_file_private *file_priv = file->driver_priv;
|
|
|
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
|
|
|
- struct device *dev = priv->dev;
|
|
|
+ struct device *dev = file_priv->ipp_dev;
|
|
|
struct ipp_context *ctx = get_ipp_context(dev);
|
|
|
struct drm_exynos_ipp_prop_list *prop_list = data;
|
|
|
struct exynos_drm_ippdrv *ippdrv;
|
|
@@ -346,10 +292,10 @@ int exynos_drm_ipp_get_property(struct drm_device *drm_dev, void *data,
|
|
|
*/
|
|
|
ippdrv = ipp_find_obj(&ctx->ipp_idr, &ctx->ipp_lock,
|
|
|
prop_list->ipp_id);
|
|
|
- if (IS_ERR(ippdrv)) {
|
|
|
+ if (!ippdrv) {
|
|
|
DRM_ERROR("not found ipp%d driver.\n",
|
|
|
prop_list->ipp_id);
|
|
|
- return PTR_ERR(ippdrv);
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
|
|
|
*prop_list = ippdrv->prop_list;
|
|
@@ -432,7 +378,7 @@ static struct drm_exynos_ipp_event_work *ipp_create_event_work(void)
|
|
|
if (!event_work)
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
- INIT_WORK((struct work_struct *)event_work, ipp_sched_event);
|
|
|
+ INIT_WORK(&event_work->work, ipp_sched_event);
|
|
|
|
|
|
return event_work;
|
|
|
}
|
|
@@ -441,8 +387,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
|
|
|
struct drm_file *file)
|
|
|
{
|
|
|
struct drm_exynos_file_private *file_priv = file->driver_priv;
|
|
|
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
|
|
|
- struct device *dev = priv->dev;
|
|
|
+ struct device *dev = file_priv->ipp_dev;
|
|
|
struct ipp_context *ctx = get_ipp_context(dev);
|
|
|
struct drm_exynos_ipp_property *property = data;
|
|
|
struct exynos_drm_ippdrv *ippdrv;
|
|
@@ -489,19 +434,18 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
|
|
|
if (!c_node)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
- /* create property id */
|
|
|
- ret = ipp_create_id(&ctx->prop_idr, &ctx->prop_lock, c_node,
|
|
|
- &property->prop_id);
|
|
|
- if (ret) {
|
|
|
+ ret = ipp_create_id(&ctx->prop_idr, &ctx->prop_lock, c_node);
|
|
|
+ if (ret < 0) {
|
|
|
DRM_ERROR("failed to create id.\n");
|
|
|
goto err_clear;
|
|
|
}
|
|
|
+ property->prop_id = ret;
|
|
|
|
|
|
DRM_DEBUG_KMS("created prop_id[%d]cmd[%d]ippdrv[0x%x]\n",
|
|
|
property->prop_id, property->cmd, (int)ippdrv);
|
|
|
|
|
|
/* stored property information and ippdrv in private data */
|
|
|
- c_node->priv = priv;
|
|
|
+ c_node->dev = dev;
|
|
|
c_node->property = *property;
|
|
|
c_node->state = IPP_STATE_IDLE;
|
|
|
|
|
@@ -534,7 +478,6 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
|
|
|
INIT_LIST_HEAD(&c_node->mem_list[i]);
|
|
|
|
|
|
INIT_LIST_HEAD(&c_node->event_list);
|
|
|
- list_splice_init(&priv->event_list, &c_node->event_list);
|
|
|
mutex_lock(&ippdrv->cmd_lock);
|
|
|
list_add_tail(&c_node->list, &ippdrv->cmd_list);
|
|
|
mutex_unlock(&ippdrv->cmd_lock);
|
|
@@ -577,42 +520,18 @@ static void ipp_clean_cmd_node(struct ipp_context *ctx,
|
|
|
kfree(c_node);
|
|
|
}
|
|
|
|
|
|
-static int ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
|
|
|
+static bool ipp_check_mem_list(struct drm_exynos_ipp_cmd_node *c_node)
|
|
|
{
|
|
|
- struct drm_exynos_ipp_property *property = &c_node->property;
|
|
|
- struct drm_exynos_ipp_mem_node *m_node;
|
|
|
- struct list_head *head;
|
|
|
- int ret, i, count[EXYNOS_DRM_OPS_MAX] = { 0, };
|
|
|
-
|
|
|
- for_each_ipp_ops(i) {
|
|
|
- /* source/destination memory list */
|
|
|
- head = &c_node->mem_list[i];
|
|
|
-
|
|
|
- /* find memory node entry */
|
|
|
- list_for_each_entry(m_node, head, list) {
|
|
|
- DRM_DEBUG_KMS("%s,count[%d]m_node[0x%x]\n",
|
|
|
- i ? "dst" : "src", count[i], (int)m_node);
|
|
|
- count[i]++;
|
|
|
- }
|
|
|
+ switch (c_node->property.cmd) {
|
|
|
+ case IPP_CMD_WB:
|
|
|
+ return !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_DST]);
|
|
|
+ case IPP_CMD_OUTPUT:
|
|
|
+ return !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_SRC]);
|
|
|
+ case IPP_CMD_M2M:
|
|
|
+ default:
|
|
|
+ return !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_SRC]) &&
|
|
|
+ !list_empty(&c_node->mem_list[EXYNOS_DRM_OPS_DST]);
|
|
|
}
|
|
|
-
|
|
|
- DRM_DEBUG_KMS("min[%d]max[%d]\n",
|
|
|
- min(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]),
|
|
|
- max(count[EXYNOS_DRM_OPS_SRC], count[EXYNOS_DRM_OPS_DST]));
|
|
|
-
|
|
|
- /*
|
|
|
- * M2M operations should be need paired memory address.
|
|
|
- * so, need to check minimum count about src, dst.
|
|
|
- * other case not use paired memory, so use maximum count
|
|
|
- */
|
|
|
- if (ipp_is_m2m_cmd(property->cmd))
|
|
|
- ret = min(count[EXYNOS_DRM_OPS_SRC],
|
|
|
- count[EXYNOS_DRM_OPS_DST]);
|
|
|
- else
|
|
|
- ret = max(count[EXYNOS_DRM_OPS_SRC],
|
|
|
- count[EXYNOS_DRM_OPS_DST]);
|
|
|
-
|
|
|
- return ret;
|
|
|
}
|
|
|
|
|
|
static struct drm_exynos_ipp_mem_node
|
|
@@ -683,16 +602,14 @@ static struct drm_exynos_ipp_mem_node
|
|
|
struct drm_exynos_ipp_queue_buf *qbuf)
|
|
|
{
|
|
|
struct drm_exynos_ipp_mem_node *m_node;
|
|
|
- struct drm_exynos_ipp_buf_info buf_info;
|
|
|
- void *addr;
|
|
|
+ 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);
|
|
|
|
|
|
- /* clear base address for error handling */
|
|
|
- memset(&buf_info, 0x0, sizeof(buf_info));
|
|
|
+ buf_info = &m_node->buf_info;
|
|
|
|
|
|
/* operations, buffer id */
|
|
|
m_node->ops_id = qbuf->ops_id;
|
|
@@ -707,6 +624,8 @@ static struct drm_exynos_ipp_mem_node
|
|
|
|
|
|
/* 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)) {
|
|
@@ -714,15 +633,14 @@ static struct drm_exynos_ipp_mem_node
|
|
|
goto err_clear;
|
|
|
}
|
|
|
|
|
|
- buf_info.handles[i] = qbuf->handle[i];
|
|
|
- buf_info.base[i] = *(dma_addr_t *) addr;
|
|
|
- DRM_DEBUG_KMS("i[%d]base[0x%x]hd[0x%x]\n",
|
|
|
- i, buf_info.base[i], (int)buf_info.handles[i]);
|
|
|
+ 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]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
m_node->filp = file;
|
|
|
- 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]);
|
|
|
mutex_unlock(&c_node->mem_lock);
|
|
@@ -930,8 +848,7 @@ int exynos_drm_ipp_queue_buf(struct drm_device *drm_dev, void *data,
|
|
|
struct drm_file *file)
|
|
|
{
|
|
|
struct drm_exynos_file_private *file_priv = file->driver_priv;
|
|
|
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
|
|
|
- struct device *dev = priv->dev;
|
|
|
+ struct device *dev = file_priv->ipp_dev;
|
|
|
struct ipp_context *ctx = get_ipp_context(dev);
|
|
|
struct drm_exynos_ipp_queue_buf *qbuf = data;
|
|
|
struct drm_exynos_ipp_cmd_node *c_node;
|
|
@@ -955,9 +872,9 @@ 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 (IS_ERR(c_node)) {
|
|
|
+ if (!c_node) {
|
|
|
DRM_ERROR("failed to get command node.\n");
|
|
|
- return PTR_ERR(c_node);
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
|
|
|
/* buffer control */
|
|
@@ -1062,9 +979,8 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
|
|
|
struct drm_file *file)
|
|
|
{
|
|
|
struct drm_exynos_file_private *file_priv = file->driver_priv;
|
|
|
- struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
|
|
|
struct exynos_drm_ippdrv *ippdrv = NULL;
|
|
|
- struct device *dev = priv->dev;
|
|
|
+ struct device *dev = file_priv->ipp_dev;
|
|
|
struct ipp_context *ctx = get_ipp_context(dev);
|
|
|
struct drm_exynos_ipp_cmd_ctrl *cmd_ctrl = data;
|
|
|
struct drm_exynos_ipp_cmd_work *cmd_work;
|
|
@@ -1091,9 +1007,9 @@ 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 (IS_ERR(c_node)) {
|
|
|
+ if (!c_node) {
|
|
|
DRM_ERROR("invalid command node list.\n");
|
|
|
- return PTR_ERR(c_node);
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
|
|
|
if (!exynos_drm_ipp_check_valid(ippdrv->dev, cmd_ctrl->ctrl,
|
|
@@ -1198,7 +1114,6 @@ static int ipp_set_property(struct exynos_drm_ippdrv *ippdrv,
|
|
|
/* reset h/w block */
|
|
|
if (ippdrv->reset &&
|
|
|
ippdrv->reset(ippdrv->dev)) {
|
|
|
- DRM_ERROR("failed to reset.\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
@@ -1216,30 +1131,24 @@ static int ipp_set_property(struct exynos_drm_ippdrv *ippdrv,
|
|
|
/* set format */
|
|
|
if (ops->set_fmt) {
|
|
|
ret = ops->set_fmt(ippdrv->dev, config->fmt);
|
|
|
- if (ret) {
|
|
|
- DRM_ERROR("not support format.\n");
|
|
|
+ if (ret)
|
|
|
return ret;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/* set transform for rotation, flip */
|
|
|
if (ops->set_transf) {
|
|
|
ret = ops->set_transf(ippdrv->dev, config->degree,
|
|
|
config->flip, &swap);
|
|
|
- if (ret) {
|
|
|
- DRM_ERROR("not support tranf.\n");
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/* set size */
|
|
|
if (ops->set_size) {
|
|
|
ret = ops->set_size(ippdrv->dev, swap, &config->pos,
|
|
|
&config->sz);
|
|
|
- if (ret) {
|
|
|
- DRM_ERROR("not support size.\n");
|
|
|
+ if (ret)
|
|
|
return ret;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1283,11 +1192,6 @@ static int ipp_start_property(struct exynos_drm_ippdrv *ippdrv,
|
|
|
|
|
|
m_node = list_first_entry(head,
|
|
|
struct drm_exynos_ipp_mem_node, list);
|
|
|
- if (!m_node) {
|
|
|
- DRM_ERROR("failed to get node.\n");
|
|
|
- ret = -EFAULT;
|
|
|
- goto err_unlock;
|
|
|
- }
|
|
|
|
|
|
DRM_DEBUG_KMS("m_node[0x%x]\n", (int)m_node);
|
|
|
|
|
@@ -1545,11 +1449,6 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
|
|
|
|
|
|
m_node = list_first_entry(head,
|
|
|
struct drm_exynos_ipp_mem_node, list);
|
|
|
- if (!m_node) {
|
|
|
- DRM_ERROR("empty memory node.\n");
|
|
|
- ret = -ENOMEM;
|
|
|
- goto err_mem_unlock;
|
|
|
- }
|
|
|
|
|
|
tbuf_id[i] = m_node->buf_id;
|
|
|
DRM_DEBUG_KMS("%s buf_id[%d]\n",
|
|
@@ -1586,11 +1485,6 @@ static int ipp_send_event(struct exynos_drm_ippdrv *ippdrv,
|
|
|
|
|
|
m_node = list_first_entry(head,
|
|
|
struct drm_exynos_ipp_mem_node, list);
|
|
|
- if (!m_node) {
|
|
|
- DRM_ERROR("empty memory node.\n");
|
|
|
- ret = -ENOMEM;
|
|
|
- goto err_mem_unlock;
|
|
|
- }
|
|
|
|
|
|
tbuf_id[EXYNOS_DRM_OPS_SRC] = m_node->buf_id;
|
|
|
|
|
@@ -1704,21 +1598,17 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
|
|
|
|
|
|
/* get ipp driver entry */
|
|
|
list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
|
|
|
- u32 ipp_id;
|
|
|
-
|
|
|
ippdrv->drm_dev = drm_dev;
|
|
|
|
|
|
- ret = ipp_create_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv,
|
|
|
- &ipp_id);
|
|
|
- if (ret || ipp_id == 0) {
|
|
|
+ ret = ipp_create_id(&ctx->ipp_idr, &ctx->ipp_lock, ippdrv);
|
|
|
+ if (ret < 0) {
|
|
|
DRM_ERROR("failed to create id.\n");
|
|
|
goto err;
|
|
|
}
|
|
|
+ ippdrv->prop_list.ipp_id = ret;
|
|
|
|
|
|
DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n",
|
|
|
- count++, (int)ippdrv, ipp_id);
|
|
|
-
|
|
|
- ippdrv->prop_list.ipp_id = ipp_id;
|
|
|
+ count++, (int)ippdrv, ret);
|
|
|
|
|
|
/* store parent device for node */
|
|
|
ippdrv->parent_dev = dev;
|
|
@@ -1776,17 +1666,10 @@ static int ipp_subdrv_open(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_ipp_private *priv;
|
|
|
-
|
|
|
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
|
|
- if (!priv)
|
|
|
- return -ENOMEM;
|
|
|
- priv->dev = dev;
|
|
|
- file_priv->ipp_priv = priv;
|
|
|
|
|
|
- INIT_LIST_HEAD(&priv->event_list);
|
|
|
+ file_priv->ipp_dev = dev;
|
|
|
|
|
|
- DRM_DEBUG_KMS("done priv[0x%x]\n", (int)priv);
|
|
|
+ DRM_DEBUG_KMS("done priv[0x%x]\n", (int)dev);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1795,13 +1678,12 @@ 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_ipp_private *priv = file_priv->ipp_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)priv);
|
|
|
+ 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);
|
|
@@ -1810,7 +1692,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->priv == priv) {
|
|
|
+ if (c_node->dev == file_priv->ipp_dev) {
|
|
|
/*
|
|
|
* userland goto unnormal state. process killed.
|
|
|
* and close the file.
|
|
@@ -1832,7 +1714,6 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
|
|
|
mutex_unlock(&ippdrv->cmd_lock);
|
|
|
}
|
|
|
|
|
|
- kfree(priv);
|
|
|
return;
|
|
|
}
|
|
|
|