@@ -118,6 +118,66 @@ void v4l2_subdev_close(struct media_entity *entity)
entity->sd->fd = -1;
}
+int v4l2_subdev_open_pipeline(struct media_device *media)
+{
+ struct media_entity *entity = media->pipeline;
+ int ret;
+
+ if (entity == NULL)
+ return 0;
+
+ /*
+ * Stop walking the pipeline on the last last but one entity, because
+ * the sink entity sub-device was opened by libv4l2 core and its
+ * file descriptor needs to be preserved.
+ */
+ while (entity->next) {
+ media_dbg(media, "Opening sub-device: %s\n", entity->devname);
+ ret = v4l2_subdev_open(entity);
+ if (ret < 0)
+ return ret;
+
+ if (entity->sd->fd < 0)
+ goto err_open_subdev;
+
+ entity = entity->next;
+ }
+
+ return 0;
+
+err_open_subdev:
+ v4l2_subdev_release_pipeline(media);
+
+ return -EINVAL;
+}
+
+void v4l2_subdev_release_pipeline(struct media_device *media)
+{
+ struct media_entity *entity = media->pipeline;
+
+ if (entity == NULL)
+ return;
+ /*
+ * Stop walking the pipeline on the last last but one entity, because
+ * the sink entity sub-device should be released by the client that
+ * instantiated it.
+ */
+ while (entity->next) {
+ if (!entity->sd) {
+ entity = entity->next;
+ continue;
+ }
+
+ if (entity->sd->fd >= 0) {
+ media_dbg(media, "Releasing sub-device: %s\n", entity->devname);
+ v4l2_subdev_release(entity, true);
+ }
+
+ entity = entity->next;
+ }
+}
+
+
int v4l2_subdev_get_format(struct media_entity *entity,
struct v4l2_mbus_framefmt *format, unsigned int pad,
enum v4l2_subdev_format_whence which)
@@ -100,6 +100,24 @@ int v4l2_subdev_open(struct media_entity *entity);
void v4l2_subdev_close(struct media_entity *entity);
/**
+ * @brief Open media device pipeline
+ * @param media - media device.
+ *
+ * Open all sub-devices in the media device pipeline.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_open_pipeline(struct media_device *media);
+
+/**
+ * @brief Release media device pipeline sub-devices
+ * @param media - media device.
+ *
+ * Release all sub-devices in the media device pipeline.
+ */
+void v4l2_subdev_release_pipeline(struct media_device *media);
+
+/**
* @brief Retrieve the format on a pad.
* @param entity - subdev-device media entity.
* @param format - format to be filled.