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

[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
...@@ -896,7 +896,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) ...@@ -1122,7 +1124,11 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
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) ...@@ -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 { ...@@ -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 { ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment