media: rockchip: isp1: fix kernel reboot in monkey test

1. use the same mutex to serialize the calls from user application.
2. keep iommu attached state when last video is closed,
because the user application may still access the buffer allocated
 by v4l2 driver.

Change-Id: I667a42a07672e5d30cc4383e9f54388fe1b91f1c
Signed-off-by: Hu Kejun <william.hu@rock-chips.com>
This commit is contained in:
Hu Kejun
2019-05-27 10:07:16 +08:00
committed by Tao Huang
parent f18816ac45
commit bd07e7ccbe
7 changed files with 35 additions and 22 deletions

View File

@@ -944,6 +944,7 @@ static int raw_config_mi(struct rkisp1_stream *stream)
in_size = raw->out_fmt.plane_fmt[0].sizeimage;
}
dmatx0_set_pic_size(base, in_frm->width, in_frm->height);
dmatx0_set_pic_off(base, 0);
dmatx0_ctrl(base,
@@ -1601,7 +1602,7 @@ static int rkisp_init_vb2_queue(struct vb2_queue *q,
q->buf_struct_size = sizeof(struct rkisp1_buffer);
q->min_buffers_needed = CIF_ISP_REQ_BUFS_MIN;
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &node->vlock;
q->lock = &stream->ispdev->apilock;
return vb2_queue_init(q);
}
@@ -1720,9 +1721,7 @@ int rkisp1_fh_open(struct file *filp)
ret = v4l2_fh_open(filp);
if (!ret) {
if (atomic_inc_return(&dev->open_cnt) == 1)
rkisp1_dma_attach_device(dev);
atomic_inc(&dev->open_cnt);
ret = dev->pipe.pm_use(&vdev->entity, 1);
if (ret < 0)
v4l2_err(&dev->v4l2_dev,
@@ -1746,8 +1745,7 @@ int rkisp1_fop_release(struct file *file)
v4l2_err(&dev->v4l2_dev,
"set pipeline power failed %d\n", ret);
if (atomic_dec_return(&dev->open_cnt) == 0)
rkisp1_dma_detach_device(dev);
atomic_dec(&dev->open_cnt);
}
return ret;
@@ -2058,14 +2056,13 @@ static int rkisp1_register_stream_vdev(struct rkisp1_stream *stream)
}
strlcpy(vdev->name, vdev_name, sizeof(vdev->name));
node = vdev_to_node(vdev);
mutex_init(&node->vlock);
vdev->ioctl_ops = &rkisp1_v4l2_ioctl_ops;
vdev->release = video_device_release_empty;
vdev->fops = &rkisp1_fops;
vdev->minor = -1;
vdev->v4l2_dev = v4l2_dev;
vdev->lock = &node->vlock;
vdev->lock = &dev->apilock;
vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
V4L2_CAP_STREAMING;
video_set_drvdata(vdev, stream);

View File

@@ -69,8 +69,6 @@ enum rkisp1_sd_type {
/* One structure per video node */
struct rkisp1_vdev_node {
struct vb2_queue buf_queue;
/* vfd lock */
struct mutex vlock;
struct video_device vdev;
struct media_pad pad;
};

View File

@@ -991,8 +991,10 @@ err:
static int rkisp1_iommu_init(struct rkisp1_device *rkisp1_dev)
{
struct device *dev = rkisp1_dev->dev;
struct iommu_domain *domain;
struct iommu_group *group;
int ret;
int ret = 0;
rkisp1_dev->domain = iommu_domain_alloc(&platform_bus_type);
if (!rkisp1_dev->domain) {
@@ -1000,6 +1002,7 @@ static int rkisp1_iommu_init(struct rkisp1_device *rkisp1_dev)
goto err;
}
domain = rkisp1_dev->domain;
ret = iommu_get_dma_cookie(rkisp1_dev->domain);
if (ret)
goto err;
@@ -1015,7 +1018,19 @@ static int rkisp1_iommu_init(struct rkisp1_device *rkisp1_dev)
goto err;
}
return 0;
ret = iommu_attach_device(domain, dev);
if (ret) {
dev_err(dev, "Failed to attach iommu device\n");
goto err;
}
if (!common_iommu_setup_dma_ops(dev, 0x10000000, SZ_2G, domain->ops)) {
dev_err(dev, "Failed to set dma_ops\n");
iommu_detach_device(domain, dev);
ret = -ENODEV;
}
return ret;
err:
dev_err(rkisp1_dev->dev, "Failed to setup IOMMU\n");
@@ -1025,7 +1040,11 @@ err:
static void rkisp1_iommu_cleanup(struct rkisp1_device *rkisp1_dev)
{
iommu_domain_free(rkisp1_dev->domain);
struct iommu_domain *domain = rkisp1_dev->domain;
struct device *dev = rkisp1_dev->dev;
iommu_detach_device(domain, dev);
iommu_domain_free(domain);
}
static int rkisp1_vs_irq_parse(struct platform_device *pdev)
@@ -1164,6 +1183,7 @@ static int rkisp1_plat_probe(struct platform_device *pdev)
isp_dev->clk_rate_tbl = match_data->clk_rate_tbl;
isp_dev->num_clk_rate_tbl = match_data->num_clk_rate_tbl;
mutex_init(&isp_dev->apilock);
atomic_set(&isp_dev->pipe.power_cnt, 0);
atomic_set(&isp_dev->pipe.stream_cnt, 0);
atomic_set(&isp_dev->open_cnt, 0);

View File

@@ -166,6 +166,7 @@ struct rkisp1_device {
enum rkisp1_isp_state isp_state;
unsigned int isp_err_cnt;
enum rkisp1_isp_inp isp_inp;
struct mutex apilock; /* mutex to serialize the calls from user */
};
#endif

View File

@@ -403,7 +403,7 @@ static int rkisp_init_vb2_queue(struct vb2_queue *q,
q->buf_struct_size = sizeof(struct rkisp1_buffer);
q->min_buffers_needed = CIF_ISP_REQ_BUFS_MIN;
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &node->vlock;
q->lock = &stream->ispdev->apilock;
return vb2_queue_init(q);
}
@@ -594,13 +594,12 @@ static int rkisp1_register_dmarx_video(struct rkisp1_stream *stream)
int ret = 0;
node = vdev_to_node(vdev);
mutex_init(&node->vlock);
vdev->release = video_device_release_empty;
vdev->fops = &rkisp1_fops;
vdev->minor = -1;
vdev->v4l2_dev = v4l2_dev;
vdev->lock = &node->vlock;
vdev->lock = &dev->apilock;
video_set_drvdata(vdev, stream);
vdev->ioctl_ops = &rkisp1_dmarx_ioctl;

View File

@@ -2557,7 +2557,7 @@ rkisp1_params_init_vb2_queue(struct vb2_queue *q,
q->mem_ops = &vb2_vmalloc_memops;
q->buf_struct_size = sizeof(struct rkisp1_buffer);
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &node->vlock;
q->lock = &params_vdev->dev->apilock;
return vb2_queue_init(q);
}
@@ -2588,7 +2588,6 @@ int rkisp1_register_params_vdev(struct rkisp1_isp_params_vdev *params_vdev,
struct video_device *vdev = &node->vdev;
params_vdev->dev = dev;
mutex_init(&node->vlock);
spin_lock_init(&params_vdev->config_lock);
strlcpy(vdev->name, "rkisp1-input-params", sizeof(vdev->name));
@@ -2601,7 +2600,7 @@ int rkisp1_register_params_vdev(struct rkisp1_isp_params_vdev *params_vdev,
* Provide a mutex to v4l2 core. It will be used
* to protect all fops and v4l2 ioctls.
*/
vdev->lock = &node->vlock;
vdev->lock = &dev->apilock;
vdev->v4l2_dev = v4l2_dev;
vdev->queue = &node->buf_queue;
vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT;

View File

@@ -215,7 +215,7 @@ static int rkisp1_stats_init_vb2_queue(struct vb2_queue *q,
q->mem_ops = &vb2_vmalloc_memops;
q->buf_struct_size = sizeof(struct rkisp1_buffer);
q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
q->lock = &node->vlock;
q->lock = &stats_vdev->dev->apilock;
return vb2_queue_init(q);
}
@@ -623,7 +623,6 @@ int rkisp1_register_stats_vdev(struct rkisp1_isp_stats_vdev *stats_vdev,
struct video_device *vdev = &node->vdev;
stats_vdev->dev = dev;
mutex_init(&node->vlock);
INIT_LIST_HEAD(&stats_vdev->stat);
spin_lock_init(&stats_vdev->irq_lock);
spin_lock_init(&stats_vdev->rd_lock);
@@ -634,7 +633,7 @@ int rkisp1_register_stats_vdev(struct rkisp1_isp_stats_vdev *stats_vdev,
vdev->ioctl_ops = &rkisp1_stats_ioctl;
vdev->fops = &rkisp1_stats_fops;
vdev->release = video_device_release_empty;
vdev->lock = &node->vlock;
vdev->lock = &dev->apilock;
vdev->v4l2_dev = v4l2_dev;
vdev->queue = &node->buf_queue;
vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;