diff options
Diffstat (limited to 'drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c')
-rw-r--r-- | drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c index 7df806b1b7a3..2ea7738cbdef 100644 --- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c +++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_subdev.c @@ -35,6 +35,7 @@ #include "cam_hw_mgr_intf.h" #include "cam_icp_hw_mgr_intf.h" #include "cam_debug_util.h" +#include "cam_smmu_api.h" #define CAM_ICP_DEV_NAME "cam-icp" @@ -55,6 +56,25 @@ static const struct of_device_id cam_icp_dt_match[] = { {} }; +static void cam_icp_dev_iommu_fault_handler( + struct iommu_domain *domain, struct device *dev, unsigned long iova, + int flags, void *token, uint32_t buf_info) +{ + int i = 0; + struct cam_node *node = NULL; + + if (!token) { + CAM_ERR(CAM_ICP, "invalid token in page handler cb"); + return; + } + + node = (struct cam_node *)token; + + for (i = 0; i < node->ctx_size; i++) + cam_context_dump_pf_info(&(node->ctx_list[i]), iova, + buf_info); +} + static int cam_icp_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { @@ -96,7 +116,7 @@ static int cam_icp_subdev_close(struct v4l2_subdev *sd, mutex_lock(&g_icp_dev.icp_lock); if (g_icp_dev.open_cnt <= 0) { - CAM_ERR(CAM_ICP, "ICP subdev is already closed"); + CAM_DBG(CAM_ICP, "ICP subdev is already closed"); rc = -EINVAL; goto end; } @@ -135,6 +155,7 @@ static int cam_icp_probe(struct platform_device *pdev) int rc = 0, i = 0; struct cam_node *node; struct cam_hw_mgr_intf *hw_mgr_intf; + int iommu_hdl = -1; if (!pdev) { CAM_ERR(CAM_ICP, "pdev is NULL"); @@ -158,7 +179,8 @@ static int cam_icp_probe(struct platform_device *pdev) goto hw_alloc_fail; } - rc = cam_icp_hw_mgr_init(pdev->dev.of_node, (uint64_t *)hw_mgr_intf); + rc = cam_icp_hw_mgr_init(pdev->dev.of_node, (uint64_t *)hw_mgr_intf, + &iommu_hdl); if (rc) { CAM_ERR(CAM_ICP, "ICP HW manager init failed: %d", rc); goto hw_init_fail; @@ -181,6 +203,9 @@ static int cam_icp_probe(struct platform_device *pdev) goto ctx_fail; } + cam_smmu_set_client_page_fault_handler(iommu_hdl, + cam_icp_dev_iommu_fault_handler, node); + g_icp_dev.open_cnt = 0; mutex_init(&g_icp_dev.icp_lock); |