mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
media: platform: rockchip: cif: fix pipeline power management
Fixes: 99b3695fef ("media: rockchip: cif: add pipeline power management")
Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
Change-Id: I30308d3ffd91992addbc8466a9d36bd0c7719cc8
This commit is contained in:
@@ -563,7 +563,7 @@ static void rkcif_assign_new_buffer_oneframe(struct rkcif_stream *stream,
|
||||
buffer = stream->curr_buf;
|
||||
}
|
||||
|
||||
if (stream->frame_phase == CIF_CSI_FRAME1_READY ) {
|
||||
if (stream->frame_phase == CIF_CSI_FRAME1_READY) {
|
||||
stream->next_buf = list_first_entry(&stream->buf_head,
|
||||
struct rkcif_buffer, queue);
|
||||
list_del(&stream->next_buf->queue);
|
||||
@@ -1094,7 +1094,7 @@ static void rkcif_stop_streaming(struct vb2_queue *queue)
|
||||
if (ret < 0)
|
||||
v4l2_err(v4l2_dev, "pipeline close failed error:%d\n",
|
||||
ret);
|
||||
/* rkcif_soft_reset(dev, false); */
|
||||
/*rkcif_soft_reset(dev, false);*/
|
||||
pm_runtime_put(dev->dev);
|
||||
}
|
||||
|
||||
@@ -1376,6 +1376,7 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
struct rkcif_vdev_node *node = &stream->vnode;
|
||||
struct rkcif_device *dev = stream->cifdev;
|
||||
struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
|
||||
struct rkcif_sensor_info *sensor_info = dev->active_sensor;
|
||||
/* struct v4l2_subdev *sd; */
|
||||
int ret;
|
||||
|
||||
@@ -1420,6 +1421,18 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
goto destroy_buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* start sub-devices
|
||||
* When use bt601, the sampling edge of cif is random,
|
||||
* can be rising or fallling after powering on cif.
|
||||
* To keep the coherence of edge, open sensor in advance.
|
||||
*/
|
||||
if (sensor_info->mbus.type == V4L2_MBUS_PARALLEL) {
|
||||
ret = dev->pipe.set_stream(&dev->pipe, true);
|
||||
if (ret < 0)
|
||||
goto runtime_put;
|
||||
}
|
||||
|
||||
if (dev->chip_id == CHIP_RK1808_CIF) {
|
||||
if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2)
|
||||
ret = rkcif_csi_stream_start(stream);
|
||||
@@ -1431,10 +1444,12 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
|
||||
|
||||
if (ret < 0)
|
||||
goto runtime_put;
|
||||
/* start sub-devices */
|
||||
ret = dev->pipe.set_stream(&dev->pipe, true);
|
||||
if (ret < 0)
|
||||
goto stop_stream;
|
||||
|
||||
if (sensor_info->mbus.type != V4L2_MBUS_PARALLEL) {
|
||||
ret = dev->pipe.set_stream(&dev->pipe, true);
|
||||
if (ret < 0)
|
||||
goto stop_stream;
|
||||
}
|
||||
|
||||
ret = media_pipeline_start(&node->vdev.entity, &dev->pipe.pipe);
|
||||
if (ret < 0) {
|
||||
@@ -1645,7 +1660,14 @@ static int rkcif_fh_open(struct file *filp)
|
||||
rkcif_soft_reset(cifdev, true);
|
||||
}
|
||||
|
||||
return v4l2_fh_open(filp);
|
||||
ret = v4l2_fh_open(filp);
|
||||
if (!ret) {
|
||||
ret = v4l2_pipeline_pm_use(&vnode->vdev.entity, 1);
|
||||
if (ret < 0)
|
||||
vb2_fop_release(filp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rkcif_fh_release(struct file *filp)
|
||||
@@ -1657,6 +1679,12 @@ static int rkcif_fh_release(struct file *filp)
|
||||
int ret = 0;
|
||||
|
||||
ret = vb2_fop_release(filp);
|
||||
if (!ret) {
|
||||
ret = v4l2_pipeline_pm_use(&vnode->vdev.entity, 0);
|
||||
if (ret < 0)
|
||||
v4l2_err(&cifdev->v4l2_dev,
|
||||
"set pipeline power failed %d\n", ret);
|
||||
}
|
||||
|
||||
mutex_lock(&cifdev->stream_lock);
|
||||
if (!atomic_dec_return(&cifdev->fh_cnt))
|
||||
|
||||
@@ -86,41 +86,6 @@ static int __cif_pipeline_prepare(struct rkcif_pipeline *p,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __subdev_set_power(struct v4l2_subdev *sd, int on)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!sd)
|
||||
return -ENXIO;
|
||||
|
||||
ret = v4l2_subdev_call(sd, core, s_power, on);
|
||||
|
||||
return ret != -ENOIOCTLCMD ? ret : 0;
|
||||
}
|
||||
|
||||
static int __cif_pipeline_s_power(struct rkcif_pipeline *p, bool on)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (on) {
|
||||
for (i = p->num_subdevs - 1; i >= 0; --i) {
|
||||
ret = __subdev_set_power(p->subdevs[i], true);
|
||||
if (ret < 0 && ret != -ENXIO)
|
||||
goto err_power_off;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < p->num_subdevs; ++i)
|
||||
__subdev_set_power(p->subdevs[i], false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_power_off:
|
||||
for (++i; i < p->num_subdevs; ++i)
|
||||
__subdev_set_power(p->subdevs[i], false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __cif_pipeline_s_cif_clk(struct rkcif_pipeline *p)
|
||||
{
|
||||
return 0;
|
||||
@@ -148,22 +113,14 @@ static int rkcif_pipeline_open(struct rkcif_pipeline *p,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = __cif_pipeline_s_power(p, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkcif_pipeline_close(struct rkcif_pipeline *p)
|
||||
{
|
||||
int ret;
|
||||
atomic_dec_return(&p->power_cnt);
|
||||
|
||||
if (atomic_dec_return(&p->power_cnt) > 0)
|
||||
return 0;
|
||||
ret = __cif_pipeline_s_power(p, 0);
|
||||
|
||||
return ret == -ENXIO ? 0 : ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user