[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: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
74a4133079
commit
17d3d4058a
@ -896,7 +896,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
|
|||||||
* starting entities if the pipeline won't start anyway (those entities
|
* starting entities if the pipeline won't start anyway (those entities
|
||||||
* would then likely fail to stop, making the problem worse).
|
* 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;
|
return -EIO;
|
||||||
|
|
||||||
spin_lock_irqsave(&pipe->lock, flags);
|
spin_lock_irqsave(&pipe->lock, flags);
|
||||||
@ -989,7 +989,6 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
|
|||||||
struct v4l2_subdev *subdev;
|
struct v4l2_subdev *subdev;
|
||||||
int failure = 0;
|
int failure = 0;
|
||||||
int ret;
|
int ret;
|
||||||
u32 id;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to stop all the modules after CCDC first or they'll
|
* 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) {
|
if (ret) {
|
||||||
dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
|
dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
|
||||||
isp->stop_failure = true;
|
isp->stop_failure = true;
|
||||||
if (subdev == &isp->isp_prev.subdev) {
|
if (subdev == &isp->isp_prev.subdev)
|
||||||
id = media_entity_id(&subdev->entity);
|
media_entity_enum_set(&isp->crashed,
|
||||||
isp->crashed |= 1U << id;
|
&subdev->entity);
|
||||||
}
|
|
||||||
failure = -ETIMEDOUT;
|
failure = -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1250,7 +1248,7 @@ static int isp_reset(struct isp_device *isp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
isp->stop_failure = false;
|
isp->stop_failure = false;
|
||||||
isp->crashed = 0;
|
media_entity_enum_zero(&isp->crashed);
|
||||||
return 0;
|
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
|
/* Reset the ISP if an entity has failed to stop. This is the
|
||||||
* only way to recover from such conditions.
|
* 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_reset(isp);
|
||||||
isp_disable_clocks(isp);
|
isp_disable_clocks(isp);
|
||||||
}
|
}
|
||||||
@ -2219,6 +2218,8 @@ static int isp_remove(struct platform_device *pdev)
|
|||||||
isp_detach_iommu(isp);
|
isp_detach_iommu(isp);
|
||||||
__omap3isp_put(isp, false);
|
__omap3isp_put(isp, false);
|
||||||
|
|
||||||
|
media_entity_enum_cleanup(&isp->crashed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2366,6 +2367,10 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
|
|||||||
struct isp_bus_cfg *bus;
|
struct isp_bus_cfg *bus;
|
||||||
int ret;
|
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) {
|
list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
|
||||||
/* Only try to link entities whose interface was set on bound */
|
/* Only try to link entities whose interface was set on bound */
|
||||||
if (sd->host_priv) {
|
if (sd->host_priv) {
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#ifndef OMAP3_ISP_CORE_H
|
#ifndef OMAP3_ISP_CORE_H
|
||||||
#define OMAP3_ISP_CORE_H
|
#define OMAP3_ISP_CORE_H
|
||||||
|
|
||||||
|
#include <media/media-entity.h>
|
||||||
#include <media/v4l2-async.h>
|
#include <media/v4l2-async.h>
|
||||||
#include <media/v4l2-device.h>
|
#include <media/v4l2-device.h>
|
||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
@ -152,7 +153,7 @@ struct isp_xclk {
|
|||||||
* @stat_lock: Spinlock for handling statistics
|
* @stat_lock: Spinlock for handling statistics
|
||||||
* @isp_mutex: Mutex for serializing requests to ISP.
|
* @isp_mutex: Mutex for serializing requests to ISP.
|
||||||
* @stop_failure: Indicates that an entity failed to stop.
|
* @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.
|
* @has_context: Context has been saved at least once and can be restored.
|
||||||
* @ref_count: Reference count for handling multiple ISP requests.
|
* @ref_count: Reference count for handling multiple ISP requests.
|
||||||
* @cam_ick: Pointer to camera interface clock structure.
|
* @cam_ick: Pointer to camera interface clock structure.
|
||||||
@ -195,7 +196,7 @@ struct isp_device {
|
|||||||
spinlock_t stat_lock; /* common lock for statistic drivers */
|
spinlock_t stat_lock; /* common lock for statistic drivers */
|
||||||
struct mutex isp_mutex; /* For handling ref_count field */
|
struct mutex isp_mutex; /* For handling ref_count field */
|
||||||
bool stop_failure;
|
bool stop_failure;
|
||||||
u32 crashed;
|
struct media_entity_enum crashed;
|
||||||
int has_context;
|
int has_context;
|
||||||
int ref_count;
|
int ref_count;
|
||||||
unsigned int autoidle;
|
unsigned int autoidle;
|
||||||
|
@ -1608,7 +1608,7 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
|
|||||||
/* Wait for the CCDC to become idle. */
|
/* Wait for the CCDC to become idle. */
|
||||||
if (ccdc_sbl_wait_idle(ccdc, 1000)) {
|
if (ccdc_sbl_wait_idle(ccdc, 1000)) {
|
||||||
dev_info(isp->dev, "CCDC won't become idle!\n");
|
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);
|
omap3isp_pipeline_cancel_stream(pipe);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
|
|||||||
while ((entity = media_entity_graph_walk_next(&graph))) {
|
while ((entity = media_entity_graph_walk_next(&graph))) {
|
||||||
struct isp_video *__video;
|
struct isp_video *__video;
|
||||||
|
|
||||||
pipe->entities |= 1 << media_entity_id(entity);
|
media_entity_enum_set(&pipe->ent_enum, entity);
|
||||||
|
|
||||||
if (far_end != NULL)
|
if (far_end != NULL)
|
||||||
continue;
|
continue;
|
||||||
@ -901,7 +901,6 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
|
|||||||
struct v4l2_ext_control ctrl;
|
struct v4l2_ext_control ctrl;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
u32 id;
|
|
||||||
|
|
||||||
/* Memory-to-memory pipelines have no external subdev. */
|
/* Memory-to-memory pipelines have no external subdev. */
|
||||||
if (pipe->input != NULL)
|
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++) {
|
for (i = 0; i < ARRAY_SIZE(ents); i++) {
|
||||||
/* Is the entity part of the pipeline? */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
/* ISP entities have always sink pad == 0. Find source. */
|
/* 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;
|
pipe->external_rate = ctrl.value64;
|
||||||
|
|
||||||
id = media_entity_id(&isp->isp_ccdc.subdev.entity);
|
if (media_entity_enum_test(&pipe->ent_enum,
|
||||||
if (pipe->entities & (1 << id)) {
|
&isp->isp_ccdc.subdev.entity)) {
|
||||||
unsigned int rate = UINT_MAX;
|
unsigned int rate = UINT_MAX;
|
||||||
/*
|
/*
|
||||||
* Check that maximum allowed CCDC pixel rate isn't
|
* 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
|
pipe = video->video.entity.pipe
|
||||||
? to_isp_pipeline(&video->video.entity) : &video->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 */
|
/* TODO: Implement PM QoS */
|
||||||
pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
|
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);
|
mutex_unlock(&video->stream_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_set_stream:
|
err_set_stream:
|
||||||
@ -1122,7 +1124,11 @@ err_pipeline_start:
|
|||||||
INIT_LIST_HEAD(&video->dmaqueue);
|
INIT_LIST_HEAD(&video->dmaqueue);
|
||||||
video->queue = NULL;
|
video->queue = NULL;
|
||||||
|
|
||||||
|
media_entity_enum_cleanup(&pipe->ent_enum);
|
||||||
|
|
||||||
|
err_enum_init:
|
||||||
mutex_unlock(&video->stream_lock);
|
mutex_unlock(&video->stream_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,6 +1180,8 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
|
|||||||
/* TODO: Implement PM QoS */
|
/* TODO: Implement PM QoS */
|
||||||
media_entity_pipeline_stop(&video->video.entity);
|
media_entity_pipeline_stop(&video->video.entity);
|
||||||
|
|
||||||
|
media_entity_enum_cleanup(&pipe->ent_enum);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mutex_unlock(&video->stream_lock);
|
mutex_unlock(&video->stream_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -80,7 +80,7 @@ enum isp_pipeline_state {
|
|||||||
* struct isp_pipeline - An ISP hardware pipeline
|
* struct isp_pipeline - An ISP hardware pipeline
|
||||||
* @field: The field being processed by the pipeline
|
* @field: The field being processed by the pipeline
|
||||||
* @error: A hardware error occurred during capture
|
* @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 isp_pipeline {
|
||||||
struct media_pipeline pipe;
|
struct media_pipeline pipe;
|
||||||
@ -89,7 +89,7 @@ struct isp_pipeline {
|
|||||||
enum isp_pipeline_stream_state stream_state;
|
enum isp_pipeline_stream_state stream_state;
|
||||||
struct isp_video *input;
|
struct isp_video *input;
|
||||||
struct isp_video *output;
|
struct isp_video *output;
|
||||||
u32 entities;
|
struct media_entity_enum ent_enum;
|
||||||
unsigned long l3_ick;
|
unsigned long l3_ick;
|
||||||
unsigned int max_rate;
|
unsigned int max_rate;
|
||||||
enum v4l2_field field;
|
enum v4l2_field field;
|
||||||
|
Loading…
Reference in New Issue
Block a user