Hi Niklas, Thanks for the patch (and sorry for my late reply). On 5/17/19 10:07 PM, Niklas Söderlund wrote: > A sensor which is running is already part of a pipeline and trying to > start a new pipeline is not possible. This prevents two capture devices > connected to the same sensor from running at the same time. > > Instead of failing to start the second capture device allow it to join > the already running pipeline by looking it up at the sensor. This allows > two (or more) capture devices to independently be started and stopped > while still being connected to the same sensor. > > Signed-off-by: Niklas Söderlund <niklas.soderlund@xxxxxxxxxxxx> > --- > drivers/media/platform/vimc/vimc-capture.c | 35 +++++++++++++++++++++- > 1 file changed, 34 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c > index e7d0fc2228a6f0c1..f9eb1e327e311b4a 100644 > --- a/drivers/media/platform/vimc/vimc-capture.c > +++ b/drivers/media/platform/vimc/vimc-capture.c > @@ -264,16 +264,49 @@ static void vimc_cap_return_all_buffers(struct vimc_cap_device *vcap, > spin_unlock(&vcap->qlock); > } > > +static struct media_entity *vimc_cap_get_sensor(struct vimc_cap_device *vcap) > +{ > + struct media_entity *entity = &vcap->vdev.entity; > + struct media_device *mdev = entity->graph_obj.mdev; > + struct media_graph graph; > + > + mutex_lock(&mdev->graph_mutex); > + if (media_graph_walk_init(&graph, mdev)) { > + mutex_unlock(&mdev->graph_mutex); > + return NULL; > + } > + > + media_graph_walk_start(&graph, entity); > + > + while ((entity = media_graph_walk_next(&graph))) > + if (entity->function == MEDIA_ENT_F_CAM_SENSOR) > + break; I was wondering if it should search up to the sensor, or if it could just search the first entity with a pipe object, what do you think? Like this it should work with an output device instead of a sensor. Regards, Helen > + > + mutex_unlock(&mdev->graph_mutex); > + > + media_graph_walk_cleanup(&graph); > + > + return entity; > +} > + > static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count) > { > struct vimc_cap_device *vcap = vb2_get_drv_priv(vq); > struct media_entity *entity = &vcap->vdev.entity; > + struct media_pipeline *pipe = NULL; > + struct media_entity *sensorent; > int ret; > > vcap->sequence = 0; > > /* Start the media pipeline */ > - ret = media_pipeline_start(entity, &vcap->stream.pipe); > + sensorent = vimc_cap_get_sensor(vcap); > + if (sensorent && sensorent->pipe) > + pipe = sensorent->pipe; > + else > + pipe = &vcap->stream.pipe; > + > + ret = media_pipeline_start(entity, pipe); > if (ret) { > vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED); > return ret; >