Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17d3d405 authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab
Browse files

[media] v4l: omap3isp: Use media entity enumeration interface



Instead of using a bitmap directly in a driver, use the new media entity
enumeration interface to perform the same.

Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 74a41330
Loading
Loading
Loading
Loading
+13 −8
Original line number Diff line number Diff line
@@ -896,7 +896,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
	 * starting entities if the pipeline won't start anyway (those entities
	 * would then likely fail to stop, making the problem worse).
	 */
	if (pipe->entities & isp->crashed)
	if (media_entity_enum_intersects(&pipe->ent_enum, &isp->crashed))
		return -EIO;

	spin_lock_irqsave(&pipe->lock, flags);
@@ -989,7 +989,6 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
	struct v4l2_subdev *subdev;
	int failure = 0;
	int ret;
	u32 id;

	/*
	 * We need to stop all the modules after CCDC first or they'll
@@ -1041,10 +1040,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
		if (ret) {
			dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
			isp->stop_failure = true;
			if (subdev == &isp->isp_prev.subdev) {
				id = media_entity_id(&subdev->entity);
				isp->crashed |= 1U << id;
			}
			if (subdev == &isp->isp_prev.subdev)
				media_entity_enum_set(&isp->crashed,
						      &subdev->entity);
			failure = -ETIMEDOUT;
		}
	}
@@ -1250,7 +1248,7 @@ static int isp_reset(struct isp_device *isp)
	}

	isp->stop_failure = false;
	isp->crashed = 0;
	media_entity_enum_zero(&isp->crashed);
	return 0;
}

@@ -1661,7 +1659,8 @@ static void __omap3isp_put(struct isp_device *isp, bool save_ctx)
		/* Reset the ISP if an entity has failed to stop. This is the
		 * only way to recover from such conditions.
		 */
		if (isp->crashed || isp->stop_failure)
		if (!media_entity_enum_empty(&isp->crashed) ||
		    isp->stop_failure)
			isp_reset(isp);
		isp_disable_clocks(isp);
	}
@@ -2219,6 +2218,8 @@ static int isp_remove(struct platform_device *pdev)
	isp_detach_iommu(isp);
	__omap3isp_put(isp, false);

	media_entity_enum_cleanup(&isp->crashed);

	return 0;
}

@@ -2366,6 +2367,10 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
	struct isp_bus_cfg *bus;
	int ret;

	ret = media_entity_enum_init(&isp->crashed, &isp->media_dev);
	if (ret)
		return ret;

	list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
		/* Only try to link entities whose interface was set on bound */
		if (sd->host_priv) {
+3 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef OMAP3_ISP_CORE_H
#define OMAP3_ISP_CORE_H

#include <media/media-entity.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <linux/clk-provider.h>
@@ -152,7 +153,7 @@ struct isp_xclk {
 * @stat_lock: Spinlock for handling statistics
 * @isp_mutex: Mutex for serializing requests to ISP.
 * @stop_failure: Indicates that an entity failed to stop.
 * @crashed: Bitmask of crashed entities (indexed by entity ID)
 * @crashed: Crashed ent_enum
 * @has_context: Context has been saved at least once and can be restored.
 * @ref_count: Reference count for handling multiple ISP requests.
 * @cam_ick: Pointer to camera interface clock structure.
@@ -195,7 +196,7 @@ struct isp_device {
	spinlock_t stat_lock;	/* common lock for statistic drivers */
	struct mutex isp_mutex;	/* For handling ref_count field */
	bool stop_failure;
	u32 crashed;
	struct media_entity_enum crashed;
	int has_context;
	int ref_count;
	unsigned int autoidle;
+1 −1
Original line number Diff line number Diff line
@@ -1608,7 +1608,7 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
	/* Wait for the CCDC to become idle. */
	if (ccdc_sbl_wait_idle(ccdc, 1000)) {
		dev_info(isp->dev, "CCDC won't become idle!\n");
		isp->crashed |= 1U << media_entity_id(&ccdc->subdev.entity);
		media_entity_enum_set(&isp->crashed, &ccdc->subdev.entity);
		omap3isp_pipeline_cancel_stream(pipe);
		return 0;
	}
+14 −6
Original line number Diff line number Diff line
@@ -241,7 +241,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
	while ((entity = media_entity_graph_walk_next(&graph))) {
		struct isp_video *__video;

		pipe->entities |= 1 << media_entity_id(entity);
		media_entity_enum_set(&pipe->ent_enum, entity);

		if (far_end != NULL)
			continue;
@@ -901,7 +901,6 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
	struct v4l2_ext_control ctrl;
	unsigned int i;
	int ret;
	u32 id;

	/* Memory-to-memory pipelines have no external subdev. */
	if (pipe->input != NULL)
@@ -909,7 +908,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,

	for (i = 0; i < ARRAY_SIZE(ents); i++) {
		/* Is the entity part of the pipeline? */
		if (!(pipe->entities & (1 << media_entity_id(ents[i]))))
		if (!media_entity_enum_test(&pipe->ent_enum, ents[i]))
			continue;

		/* ISP entities have always sink pad == 0. Find source. */
@@ -961,8 +960,8 @@ static int isp_video_check_external_subdevs(struct isp_video *video,

	pipe->external_rate = ctrl.value64;

	id = media_entity_id(&isp->isp_ccdc.subdev.entity);
	if (pipe->entities & (1 << id)) {
	if (media_entity_enum_test(&pipe->ent_enum,
				   &isp->isp_ccdc.subdev.entity)) {
		unsigned int rate = UINT_MAX;
		/*
		 * Check that maximum allowed CCDC pixel rate isn't
@@ -1028,7 +1027,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
	pipe = video->video.entity.pipe
	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;

	pipe->entities = 0;
	ret = media_entity_enum_init(&pipe->ent_enum, &video->isp->media_dev);
	if (ret)
		goto err_enum_init;

	/* TODO: Implement PM QoS */
	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1102,6 +1103,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
	}

	mutex_unlock(&video->stream_lock);

	return 0;

err_set_stream:
@@ -1122,7 +1124,11 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
	INIT_LIST_HEAD(&video->dmaqueue);
	video->queue = NULL;

	media_entity_enum_cleanup(&pipe->ent_enum);

err_enum_init:
	mutex_unlock(&video->stream_lock);

	return ret;
}

@@ -1174,6 +1180,8 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
	/* TODO: Implement PM QoS */
	media_entity_pipeline_stop(&video->video.entity);

	media_entity_enum_cleanup(&pipe->ent_enum);

done:
	mutex_unlock(&video->stream_lock);
	return 0;
+2 −2
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ enum isp_pipeline_state {
 * struct isp_pipeline - An ISP hardware pipeline
 * @field: The field being processed by the pipeline
 * @error: A hardware error occurred during capture
 * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
 * @ent_enum: Entities in the pipeline
 */
struct isp_pipeline {
	struct media_pipeline pipe;
@@ -89,7 +89,7 @@ struct isp_pipeline {
	enum isp_pipeline_stream_state stream_state;
	struct isp_video *input;
	struct isp_video *output;
	u32 entities;
	struct media_entity_enum ent_enum;
	unsigned long l3_ick;
	unsigned int max_rate;
	enum v4l2_field field;