static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) { struct exynos_video_entity *ve; struct fimc_pipeline *p; struct video_device *vdev; int ret; vdev = media_entity_to_video_device(entity); if (vdev->entity.use_count == 0) return 0; ve = vdev_to_exynos_video_entity(vdev); p = to_fimc_pipeline(ve->pipe); /* * Nothing to do if we are disabling the pipeline, some link * has been disconnected and p->subdevs array is cleared now. */ if (!enable && p->subdevs[IDX_SENSOR] == NULL) return 0; if (enable) ret = __fimc_pipeline_open(ve->pipe, entity, true); else ret = __fimc_pipeline_close(ve->pipe); if (ret == 0 && !enable) memset(p->subdevs, 0, sizeof(p->subdevs)); return ret; }
static int fimc_md_link_notify(struct media_pad *source, struct media_pad *sink, u32 flags) { struct fimc_lite *fimc_lite = NULL; struct fimc_dev *fimc = NULL; struct fimc_pipeline *pipeline; struct v4l2_subdev *sd; int ret = 0; if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV) return 0; sd = media_entity_to_v4l2_subdev(sink->entity); switch (sd->grp_id) { case FLITE_GROUP_ID: fimc_lite = v4l2_get_subdevdata(sd); pipeline = &fimc_lite->pipeline; break; case FIMC_GROUP_ID: fimc = v4l2_get_subdevdata(sd); pipeline = &fimc->pipeline; break; default: return 0; } if (!(flags & MEDIA_LNK_FL_ENABLED)) { ret = __fimc_pipeline_close(pipeline); pipeline->subdevs[IDX_SENSOR] = NULL; pipeline->subdevs[IDX_CSIS] = NULL; if (fimc) { mutex_lock(&fimc->lock); fimc_ctrls_delete(fimc->vid_cap.ctx); mutex_unlock(&fimc->lock); } return ret; } /* * Link activation. Enable power of pipeline elements only if the * pipeline is already in use, i.e. its video node is opened. * Recreate the controls destroyed during the link deactivation. */ if (fimc) { mutex_lock(&fimc->lock); if (fimc->vid_cap.refcnt > 0) { ret = __fimc_pipeline_open(pipeline, source->entity, true); if (!ret) ret = fimc_capture_ctrls_create(fimc); } mutex_unlock(&fimc->lock); } else { mutex_lock(&fimc_lite->lock); ret = __fimc_pipeline_open(pipeline, source->entity, true); mutex_unlock(&fimc_lite->lock); } return ret ? -EPIPE : ret; }
static int fimc_pipeline_close(struct fimc_pipeline *p) { struct media_entity *me; int ret; if (!p || !p->subdevs[IDX_SENSOR]) return -EINVAL; me = &p->subdevs[IDX_SENSOR]->entity; mutex_lock(&me->parent->graph_mutex); ret = __fimc_pipeline_close(p); mutex_unlock(&me->parent->graph_mutex); return ret; }