aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_ipp.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index b60ae54ef82b..f1c51b4dd56c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -167,6 +167,13 @@ static int ipp_create_id(struct idr *id_idr, struct mutex *lock, void *obj,
167 return 0; 167 return 0;
168} 168}
169 169
170static void ipp_remove_id(struct idr *id_idr, struct mutex *lock, u32 id)
171{
172 mutex_lock(lock);
173 idr_remove(id_idr, id);
174 mutex_unlock(lock);
175}
176
170static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id) 177static void *ipp_find_obj(struct idr *id_idr, struct mutex *lock, u32 id)
171{ 178{
172 void *obj; 179 void *obj;
@@ -501,7 +508,7 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data,
501 c_node->start_work = ipp_create_cmd_work(); 508 c_node->start_work = ipp_create_cmd_work();
502 if (IS_ERR(c_node->start_work)) { 509 if (IS_ERR(c_node->start_work)) {
503 DRM_ERROR("failed to create start work.\n"); 510 DRM_ERROR("failed to create start work.\n");
504 goto err_clear; 511 goto err_remove_id;
505 } 512 }
506 513
507 c_node->stop_work = ipp_create_cmd_work(); 514 c_node->stop_work = ipp_create_cmd_work();
@@ -542,16 +549,22 @@ err_free_stop:
542 kfree(c_node->stop_work); 549 kfree(c_node->stop_work);
543err_free_start: 550err_free_start:
544 kfree(c_node->start_work); 551 kfree(c_node->start_work);
552err_remove_id:
553 ipp_remove_id(&ctx->prop_idr, &ctx->prop_lock, property->prop_id);
545err_clear: 554err_clear:
546 kfree(c_node); 555 kfree(c_node);
547 return ret; 556 return ret;
548} 557}
549 558
550static void ipp_clean_cmd_node(struct drm_exynos_ipp_cmd_node *c_node) 559static void ipp_clean_cmd_node(struct ipp_context *ctx,
560 struct drm_exynos_ipp_cmd_node *c_node)
551{ 561{
552 /* delete list */ 562 /* delete list */
553 list_del(&c_node->list); 563 list_del(&c_node->list);
554 564
565 ipp_remove_id(&ctx->prop_idr, &ctx->prop_lock,
566 c_node->property.prop_id);
567
555 /* destroy mutex */ 568 /* destroy mutex */
556 mutex_destroy(&c_node->lock); 569 mutex_destroy(&c_node->lock);
557 mutex_destroy(&c_node->mem_lock); 570 mutex_destroy(&c_node->mem_lock);
@@ -1122,7 +1135,7 @@ int exynos_drm_ipp_cmd_ctrl(struct drm_device *drm_dev, void *data,
1122 c_node->state = IPP_STATE_STOP; 1135 c_node->state = IPP_STATE_STOP;
1123 ippdrv->dedicated = false; 1136 ippdrv->dedicated = false;
1124 mutex_lock(&ippdrv->cmd_lock); 1137 mutex_lock(&ippdrv->cmd_lock);
1125 ipp_clean_cmd_node(c_node); 1138 ipp_clean_cmd_node(ctx, c_node);
1126 1139
1127 if (list_empty(&ippdrv->cmd_list)) 1140 if (list_empty(&ippdrv->cmd_list))
1128 pm_runtime_put_sync(ippdrv->dev); 1141 pm_runtime_put_sync(ippdrv->dev);
@@ -1686,7 +1699,7 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
1686 &ipp_id); 1699 &ipp_id);
1687 if (ret || ipp_id == 0) { 1700 if (ret || ipp_id == 0) {
1688 DRM_ERROR("failed to create id.\n"); 1701 DRM_ERROR("failed to create id.\n");
1689 goto err_idr; 1702 goto err;
1690 } 1703 }
1691 1704
1692 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n", 1705 DRM_DEBUG_KMS("count[%d]ippdrv[0x%x]ipp_id[%d]\n",
@@ -1707,34 +1720,40 @@ static int ipp_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
1707 ret = drm_iommu_attach_device(drm_dev, ippdrv->dev); 1720 ret = drm_iommu_attach_device(drm_dev, ippdrv->dev);
1708 if (ret) { 1721 if (ret) {
1709 DRM_ERROR("failed to activate iommu\n"); 1722 DRM_ERROR("failed to activate iommu\n");
1710 goto err_iommu; 1723 goto err;
1711 } 1724 }
1712 } 1725 }
1713 } 1726 }
1714 1727
1715 return 0; 1728 return 0;
1716 1729
1717err_iommu: 1730err:
1718 /* get ipp driver entry */ 1731 /* get ipp driver entry */
1719 list_for_each_entry_reverse(ippdrv, &exynos_drm_ippdrv_list, drv_list) 1732 list_for_each_entry_continue_reverse(ippdrv, &exynos_drm_ippdrv_list,
1733 drv_list) {
1720 if (is_drm_iommu_supported(drm_dev)) 1734 if (is_drm_iommu_supported(drm_dev))
1721 drm_iommu_detach_device(drm_dev, ippdrv->dev); 1735 drm_iommu_detach_device(drm_dev, ippdrv->dev);
1722 1736
1723err_idr: 1737 ipp_remove_id(&ctx->ipp_idr, &ctx->ipp_lock,
1724 idr_destroy(&ctx->ipp_idr); 1738 ippdrv->prop_list.ipp_id);
1725 idr_destroy(&ctx->prop_idr); 1739 }
1740
1726 return ret; 1741 return ret;
1727} 1742}
1728 1743
1729static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev) 1744static void ipp_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
1730{ 1745{
1731 struct exynos_drm_ippdrv *ippdrv; 1746 struct exynos_drm_ippdrv *ippdrv;
1747 struct ipp_context *ctx = get_ipp_context(dev);
1732 1748
1733 /* get ipp driver entry */ 1749 /* get ipp driver entry */
1734 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) { 1750 list_for_each_entry(ippdrv, &exynos_drm_ippdrv_list, drv_list) {
1735 if (is_drm_iommu_supported(drm_dev)) 1751 if (is_drm_iommu_supported(drm_dev))
1736 drm_iommu_detach_device(drm_dev, ippdrv->dev); 1752 drm_iommu_detach_device(drm_dev, ippdrv->dev);
1737 1753
1754 ipp_remove_id(&ctx->ipp_idr, &ctx->ipp_lock,
1755 ippdrv->prop_list.ipp_id);
1756
1738 ippdrv->drm_dev = NULL; 1757 ippdrv->drm_dev = NULL;
1739 exynos_drm_ippdrv_unregister(ippdrv); 1758 exynos_drm_ippdrv_unregister(ippdrv);
1740 } 1759 }
@@ -1765,6 +1784,7 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
1765 struct drm_exynos_file_private *file_priv = file->driver_priv; 1784 struct drm_exynos_file_private *file_priv = file->driver_priv;
1766 struct exynos_drm_ipp_private *priv = file_priv->ipp_priv; 1785 struct exynos_drm_ipp_private *priv = file_priv->ipp_priv;
1767 struct exynos_drm_ippdrv *ippdrv = NULL; 1786 struct exynos_drm_ippdrv *ippdrv = NULL;
1787 struct ipp_context *ctx = get_ipp_context(dev);
1768 struct drm_exynos_ipp_cmd_node *c_node, *tc_node; 1788 struct drm_exynos_ipp_cmd_node *c_node, *tc_node;
1769 int count = 0; 1789 int count = 0;
1770 1790
@@ -1791,7 +1811,7 @@ static void ipp_subdrv_close(struct drm_device *drm_dev, struct device *dev,
1791 } 1811 }
1792 1812
1793 ippdrv->dedicated = false; 1813 ippdrv->dedicated = false;
1794 ipp_clean_cmd_node(c_node); 1814 ipp_clean_cmd_node(ctx, c_node);
1795 if (list_empty(&ippdrv->cmd_list)) 1815 if (list_empty(&ippdrv->cmd_list))
1796 pm_runtime_put_sync(ippdrv->dev); 1816 pm_runtime_put_sync(ippdrv->dev);
1797 } 1817 }