@@ -125,21 +125,11 @@ static void brx_try_format(struct vsp1_brx *brx,
}
static int brx_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *fmt)
{
struct vsp1_brx *brx = to_brx(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- mutex_lock(&brx->entity.lock);
-
- state = vsp1_entity_get_state(&brx->entity, sd_state, fmt->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
brx_try_format(brx, state, fmt->pad, &fmt->format);
@@ -167,17 +157,14 @@ static int brx_set_format(struct v4l2_subdev *subdev,
}
}
-done:
- mutex_unlock(&brx->entity.lock);
- return ret;
+ return 0;
}
static int brx_get_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
struct vsp1_brx *brx = to_brx(subdev);
- struct v4l2_subdev_state *state;
if (sel->pad == brx->entity.source_pad)
return -EINVAL;
@@ -191,14 +178,7 @@ static int brx_get_selection(struct v4l2_subdev *subdev,
return 0;
case V4L2_SEL_TGT_COMPOSE:
- state = vsp1_entity_get_state(&brx->entity, sd_state,
- sel->which);
- if (!state)
- return -EINVAL;
-
- mutex_lock(&brx->entity.lock);
sel->r = *v4l2_subdev_state_get_compose(state, sel->pad);
- mutex_unlock(&brx->entity.lock);
return 0;
default:
@@ -207,14 +187,12 @@ static int brx_get_selection(struct v4l2_subdev *subdev,
}
static int brx_set_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
struct vsp1_brx *brx = to_brx(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *compose;
- int ret = 0;
if (sel->pad == brx->entity.source_pad)
return -EINVAL;
@@ -222,14 +200,6 @@ static int brx_set_selection(struct v4l2_subdev *subdev,
if (sel->target != V4L2_SEL_TGT_COMPOSE)
return -EINVAL;
- mutex_lock(&brx->entity.lock);
-
- state = vsp1_entity_get_state(&brx->entity, sd_state, sel->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
-
/*
* The compose rectangle top left corner must be inside the output
* frame.
@@ -249,15 +219,13 @@ static int brx_set_selection(struct v4l2_subdev *subdev,
compose = v4l2_subdev_state_get_compose(state, sel->pad);
*compose = sel->r;
-done:
- mutex_unlock(&brx->entity.lock);
- return ret;
+ return 0;
}
static const struct v4l2_subdev_pad_ops brx_pad_ops = {
.enum_mbus_code = brx_enum_mbus_code,
.enum_frame_size = brx_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = brx_set_format,
.get_selection = brx_get_selection,
.set_selection = brx_set_selection,
@@ -425,6 +393,8 @@ struct vsp1_brx *vsp1_brx_create(struct vsp1_device *vsp1,
/* Initialize the control handler. */
v4l2_ctrl_handler_init(&brx->ctrls, 1);
+ brx->ctrls.lock = &brx->entity.subdev.active_state->_lock;
+
v4l2_ctrl_new_std(&brx->ctrls, &brx_ctrl_ops, V4L2_CID_BG_COLOR,
0, 0xffffff, 1, 0);
@@ -157,7 +157,7 @@ static int clu_set_format(struct v4l2_subdev *subdev,
static const struct v4l2_subdev_pad_ops clu_pad_ops = {
.enum_mbus_code = clu_enum_mbus_code,
.enum_frame_size = clu_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = clu_set_format,
};
@@ -266,6 +266,8 @@ struct vsp1_clu *vsp1_clu_create(struct vsp1_device *vsp1)
/* Initialize the control handler. */
v4l2_ctrl_handler_init(&clu->ctrls, 2);
+ clu->ctrls.lock = &clu->entity.subdev.active_state->_lock;
+
v4l2_ctrl_new_custom(&clu->ctrls, &clu_table_control, NULL);
v4l2_ctrl_new_custom(&clu->ctrls, &clu_mode_control, NULL);
@@ -550,9 +550,6 @@ static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe)
struct vsp1_dl_body *dlb;
unsigned int dl_flags = 0;
- vsp1_pipeline_calculate_partition(pipe, &pipe->part_table[0],
- drm_pipe->width, 0);
-
if (drm_pipe->force_brx_release)
dl_flags |= VSP1_DL_FRAME_END_INTERNAL;
if (pipe->output->writeback)
@@ -561,8 +558,11 @@ static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe)
dl = vsp1_dl_list_get(pipe->output->dlm);
dlb = vsp1_dl_list_get_body0(dl);
+ /*
+ * Lock the state for all entities in the pipeline, disconnecting
+ * unused entities along the way.
+ */
list_for_each_entry_safe(entity, next, &pipe->entities, list_pipe) {
- /* Disconnect unused entities from the pipeline. */
if (!entity->pipe) {
vsp1_dl_body_write(dlb, entity->route->reg,
VI6_DPR_NODE_UNUSED);
@@ -573,14 +573,33 @@ static void vsp1_du_pipeline_configure(struct vsp1_pipeline *pipe)
continue;
}
+ v4l2_subdev_get_locked_active_state(&entity->subdev);
+ }
+
+ vsp1_pipeline_calculate_partition(pipe, &pipe->part_table[0],
+ drm_pipe->width, 0);
+
+ /* Configure the pipeline. */
+ list_for_each_entry(entity, &pipe->entities, list_pipe) {
+ struct v4l2_subdev_state *state;
+
+ state = v4l2_subdev_get_locked_active_state(&entity->subdev);
+
vsp1_entity_route_setup(entity, pipe, dlb);
- vsp1_entity_configure_stream(entity, entity->state, pipe,
- dl, dlb);
+ vsp1_entity_configure_stream(entity, state, pipe, dl, dlb);
vsp1_entity_configure_frame(entity, pipe, dl, dlb);
vsp1_entity_configure_partition(entity, pipe,
&pipe->part_table[0], dl, dlb);
}
+ /* Unlock all states. */
+ list_for_each_entry_reverse(entity, &pipe->entities, list_pipe) {
+ struct v4l2_subdev_state *state;
+
+ state = v4l2_subdev_get_unlocked_active_state(&entity->subdev);
+ v4l2_subdev_unlock_state(state);
+ }
+
vsp1_dl_list_commit(dl, dl_flags);
}
@@ -103,64 +103,10 @@ void vsp1_entity_configure_partition(struct vsp1_entity *entity,
* V4L2 Subdevice Operations
*/
-/**
- * vsp1_entity_get_state - Get the subdev state for an entity
- * @entity: the entity
- * @sd_state: the TRY state
- * @which: state selector (ACTIVE or TRY)
- *
- * When called with which set to V4L2_SUBDEV_FORMAT_ACTIVE the caller must hold
- * the entity lock to access the returned configuration.
- *
- * Return the subdev state requested by the which argument. The TRY state is
- * passed explicitly to the function through the sd_state argument and simply
- * returned when requested. The ACTIVE state comes from the entity structure.
- */
-struct v4l2_subdev_state *
-vsp1_entity_get_state(struct vsp1_entity *entity,
- struct v4l2_subdev_state *sd_state,
- enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return entity->state;
- case V4L2_SUBDEV_FORMAT_TRY:
- default:
- return sd_state;
- }
-}
-
-/*
- * vsp1_subdev_get_pad_format - Subdev pad get_fmt handler
- * @subdev: V4L2 subdevice
- * @sd_state: V4L2 subdev state
- * @fmt: V4L2 subdev format
- *
- * This function implements the subdev get_fmt pad operation. It can be used as
- * a direct drop-in for the operation handler.
- */
-int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct vsp1_entity *entity = to_vsp1_entity(subdev);
- struct v4l2_subdev_state *state;
-
- state = vsp1_entity_get_state(entity, sd_state, fmt->which);
- if (!state)
- return -EINVAL;
-
- mutex_lock(&entity->lock);
- fmt->format = *v4l2_subdev_state_get_format(state, fmt->pad);
- mutex_unlock(&entity->lock);
-
- return 0;
-}
-
/*
* vsp1_subdev_enum_mbus_code - Subdev pad enum_mbus_code handler
* @subdev: V4L2 subdevice
- * @sd_state: V4L2 subdev state
+ * @state: V4L2 subdev state
* @code: Media bus code enumeration
* @codes: Array of supported media bus codes
* @ncodes: Number of supported media bus codes
@@ -171,19 +117,16 @@ int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
* the sink pad.
*/
int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum *code,
const unsigned int *codes, unsigned int ncodes)
{
- struct vsp1_entity *entity = to_vsp1_entity(subdev);
-
if (code->pad == 0) {
if (code->index >= ncodes)
return -EINVAL;
code->code = codes[code->index];
} else {
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
/*
@@ -193,14 +136,8 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
if (code->index)
return -EINVAL;
- state = vsp1_entity_get_state(entity, sd_state, code->which);
- if (!state)
- return -EINVAL;
-
- mutex_lock(&entity->lock);
format = v4l2_subdev_state_get_format(state, 0);
code->code = format->code;
- mutex_unlock(&entity->lock);
}
return 0;
@@ -209,7 +146,7 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
/*
* vsp1_subdev_enum_frame_size - Subdev pad enum_frame_size handler
* @subdev: V4L2 subdevice
- * @sd_state: V4L2 subdev state
+ * @state: V4L2 subdev state
* @fse: Frame size enumeration
* @min_width: Minimum image width
* @min_height: Minimum image height
@@ -222,28 +159,17 @@ int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
* source pad size identical to the sink pad.
*/
int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_frame_size_enum *fse,
unsigned int min_width, unsigned int min_height,
unsigned int max_width, unsigned int max_height)
{
- struct vsp1_entity *entity = to_vsp1_entity(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- state = vsp1_entity_get_state(entity, sd_state, fse->which);
- if (!state)
- return -EINVAL;
format = v4l2_subdev_state_get_format(state, fse->pad);
- mutex_lock(&entity->lock);
-
- if (fse->index || fse->code != format->code) {
- ret = -EINVAL;
- goto done;
- }
+ if (fse->index || fse->code != format->code)
+ return -EINVAL;
if (fse->pad == 0) {
fse->min_width = min_width;
@@ -261,15 +187,13 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
fse->max_height = format->height;
}
-done:
- mutex_unlock(&entity->lock);
- return ret;
+ return 0;
}
/*
* vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
* @subdev: V4L2 subdevice
- * @sd_state: V4L2 subdev state
+ * @state: V4L2 subdev state
* @fmt: V4L2 subdev format
* @codes: Array of supported media bus codes
* @ncodes: Number of supported media bus codes
@@ -285,33 +209,23 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
* source pad.
*/
int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *fmt,
const unsigned int *codes, unsigned int ncodes,
unsigned int min_width, unsigned int min_height,
unsigned int max_width, unsigned int max_height)
{
struct vsp1_entity *entity = to_vsp1_entity(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *selection;
unsigned int i;
- int ret = 0;
-
- mutex_lock(&entity->lock);
-
- state = vsp1_entity_get_state(entity, sd_state, fmt->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
format = v4l2_subdev_state_get_format(state, fmt->pad);
if (fmt->pad == entity->source_pad) {
/* The output format can't be modified. */
fmt->format = *format;
- goto done;
+ return 0;
}
/*
@@ -350,9 +264,7 @@ int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
selection->width = format->width;
selection->height = format->height;
-done:
- mutex_unlock(&entity->lock);
- return ret;
+ return 0;
}
static int vsp1_entity_init_state(struct v4l2_subdev *subdev,
@@ -364,8 +276,6 @@ static int vsp1_entity_init_state(struct v4l2_subdev *subdev,
for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) {
struct v4l2_subdev_format format = {
.pad = pad,
- .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
- : V4L2_SUBDEV_FORMAT_ACTIVE,
};
v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &format);
@@ -563,7 +473,6 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
const char *name, unsigned int num_pads,
const struct v4l2_subdev_ops *ops, u32 function)
{
- static struct lock_class_key key;
struct v4l2_subdev *subdev;
unsigned int i;
int ret;
@@ -579,8 +488,6 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
if (i == ARRAY_SIZE(vsp1_routes))
return -EINVAL;
- mutex_init(&entity->lock);
-
entity->vsp1 = vsp1;
entity->source_pad = num_pads - 1;
@@ -621,21 +528,10 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
snprintf(subdev->name, sizeof(subdev->name), "%s %s",
dev_name(vsp1->dev), name);
- vsp1_entity_init_state(subdev, NULL);
-
- /*
- * Allocate the subdev state to store formats and selection
- * rectangles.
- */
- /*
- * FIXME: Drop this call, drivers are not supposed to use
- * __v4l2_subdev_state_alloc().
- */
- entity->state = __v4l2_subdev_state_alloc(&entity->subdev,
- "vsp1:state->lock", &key);
- if (IS_ERR(entity->state)) {
+ ret = v4l2_subdev_init_finalize(subdev);
+ if (ret) {
media_entity_cleanup(&entity->subdev.entity);
- return PTR_ERR(entity->state);
+ return ret;
}
return 0;
@@ -647,6 +543,6 @@ void vsp1_entity_destroy(struct vsp1_entity *entity)
entity->ops->destroy(entity);
if (entity->subdev.ctrl_handler)
v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
- __v4l2_subdev_state_free(entity->state);
+ v4l2_subdev_cleanup(&entity->subdev);
media_entity_cleanup(&entity->subdev.entity);
}
@@ -10,7 +10,6 @@
#define __VSP1_ENTITY_H__
#include <linux/list.h>
-#include <linux/mutex.h>
#include <media/v4l2-subdev.h>
@@ -125,9 +124,6 @@ struct vsp1_entity {
unsigned int sink_pad;
struct v4l2_subdev subdev;
- struct v4l2_subdev_state *state;
-
- struct mutex lock; /* Protects the state */
};
static inline struct vsp1_entity *to_vsp1_entity(struct v4l2_subdev *subdev)
@@ -144,11 +140,6 @@ int vsp1_entity_link_setup(struct media_entity *entity,
const struct media_pad *local,
const struct media_pad *remote, u32 flags);
-struct v4l2_subdev_state *
-vsp1_entity_get_state(struct vsp1_entity *entity,
- struct v4l2_subdev_state *sd_state,
- enum v4l2_subdev_format_whence which);
-
void vsp1_entity_route_setup(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
struct vsp1_dl_body *dlb);
@@ -172,21 +163,18 @@ void vsp1_entity_configure_partition(struct vsp1_entity *entity,
struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad);
-int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt);
int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *fmt,
const unsigned int *codes, unsigned int ncodes,
unsigned int min_width, unsigned int min_height,
unsigned int max_width, unsigned int max_height);
int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum *code,
const unsigned int *codes, unsigned int ncodes);
int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_frame_size_enum *fse,
unsigned int min_w, unsigned int min_h,
unsigned int max_w, unsigned int max_h);
@@ -205,6 +205,8 @@ struct vsp1_hgo *vsp1_hgo_create(struct vsp1_device *vsp1)
/* Initialize the control handler. */
v4l2_ctrl_handler_init(&hgo->ctrls.handler,
vsp1->info->gen >= 3 ? 2 : 1);
+ hgo->ctrls.handler.lock = &hgo->histo.entity.subdev.active_state->_lock;
+
hgo->ctrls.max_rgb = v4l2_ctrl_new_custom(&hgo->ctrls.handler,
&hgo_max_rgb_control, NULL);
if (vsp1->info->gen >= 3)
@@ -203,6 +203,8 @@ struct vsp1_hgt *vsp1_hgt_create(struct vsp1_device *vsp1)
/* Initialize the control handler. */
v4l2_ctrl_handler_init(&hgt->ctrls, 1);
+ hgt->ctrls.lock = &hgt->histo.entity.subdev.active_state->_lock;
+
v4l2_ctrl_new_custom(&hgt->ctrls, &hgt_hue_areas, NULL);
hgt->histo.entity.subdev.ctrl_handler = &hgt->ctrls;
@@ -195,26 +195,15 @@ static int histo_enum_frame_size(struct v4l2_subdev *subdev,
}
static int histo_get_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
- struct vsp1_histogram *histo = subdev_to_histo(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *crop;
- int ret = 0;
if (sel->pad != HISTO_PAD_SINK)
return -EINVAL;
- mutex_lock(&histo->entity.lock);
-
- state = vsp1_entity_get_state(&histo->entity, sd_state, sel->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
-
switch (sel->target) {
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
@@ -243,13 +232,10 @@ static int histo_get_selection(struct v4l2_subdev *subdev,
break;
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
-done:
- mutex_unlock(&histo->entity.lock);
- return ret;
+ return 0;
}
static int histo_set_crop(struct v4l2_subdev *subdev,
@@ -322,34 +308,18 @@ static int histo_set_compose(struct v4l2_subdev *subdev,
}
static int histo_set_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
- struct vsp1_histogram *histo = subdev_to_histo(subdev);
- struct v4l2_subdev_state *state;
- int ret;
-
if (sel->pad != HISTO_PAD_SINK)
return -EINVAL;
- mutex_lock(&histo->entity.lock);
-
- state = vsp1_entity_get_state(&histo->entity, sd_state, sel->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
-
if (sel->target == V4L2_SEL_TGT_CROP)
- ret = histo_set_crop(subdev, state, sel);
+ return histo_set_crop(subdev, state, sel);
else if (sel->target == V4L2_SEL_TGT_COMPOSE)
- ret = histo_set_compose(subdev, state, sel);
+ return histo_set_compose(subdev, state, sel);
else
- ret = -EINVAL;
-
-done:
- mutex_unlock(&histo->entity.lock);
- return ret;
+ return -EINVAL;
}
static int histo_set_format(struct v4l2_subdev *subdev,
@@ -377,7 +347,7 @@ static int histo_set_format(struct v4l2_subdev *subdev,
static const struct v4l2_subdev_pad_ops histo_pad_ops = {
.enum_mbus_code = histo_enum_mbus_code,
.enum_frame_size = histo_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = histo_set_format,
.get_selection = histo_get_selection,
.set_selection = histo_set_selection,
@@ -62,21 +62,11 @@ static int hsit_enum_frame_size(struct v4l2_subdev *subdev,
}
static int hsit_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *fmt)
{
struct vsp1_hsit *hsit = to_hsit(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- mutex_lock(&hsit->entity.lock);
-
- state = vsp1_entity_get_state(&hsit->entity, sd_state, fmt->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
format = v4l2_subdev_state_get_format(state, fmt->pad);
@@ -86,7 +76,7 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
* modified.
*/
fmt->format = *format;
- goto done;
+ return 0;
}
format->code = hsit->inverse ? MEDIA_BUS_FMT_AHSV8888_1X32
@@ -106,15 +96,13 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32
: MEDIA_BUS_FMT_AHSV8888_1X32;
-done:
- mutex_unlock(&hsit->entity.lock);
- return ret;
+ return 0;
}
static const struct v4l2_subdev_pad_ops hsit_pad_ops = {
.enum_mbus_code = hsit_enum_mbus_code,
.enum_frame_size = hsit_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = hsit_set_format,
};
@@ -70,7 +70,7 @@ static int lif_set_format(struct v4l2_subdev *subdev,
static const struct v4l2_subdev_pad_ops lif_pad_ops = {
.enum_mbus_code = lif_enum_mbus_code,
.enum_frame_size = lif_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = lif_set_format,
};
@@ -133,7 +133,7 @@ static int lut_set_format(struct v4l2_subdev *subdev,
static const struct v4l2_subdev_pad_ops lut_pad_ops = {
.enum_mbus_code = lut_enum_mbus_code,
.enum_frame_size = lut_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = lut_set_format,
};
@@ -225,6 +225,8 @@ struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1)
/* Initialize the control handler. */
v4l2_ctrl_handler_init(&lut->ctrls, 1);
+ lut->ctrls.lock = &lut->entity.subdev.active_state->_lock;
+
v4l2_ctrl_new_custom(&lut->ctrls, &lut_table_control, NULL);
lut->entity.subdev.ctrl_handler = &lut->ctrls;
@@ -486,9 +486,14 @@ static void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
struct vsp1_entity *entity;
list_for_each_entry_reverse(entity, &pipe->entities, list_pipe) {
- if (entity->ops->partition)
- entity->ops->partition(entity, entity->state, pipe,
- partition, index, window);
+ struct v4l2_subdev_state *state;
+
+ if (!entity->ops->partition)
+ continue;
+
+ state = v4l2_subdev_get_locked_active_state(&entity->subdev);
+ entity->ops->partition(entity, state, pipe, partition, index,
+ window);
}
}
@@ -507,6 +512,7 @@ void vsp1_pipeline_calculate_partition(struct vsp1_pipeline *pipe,
unsigned int index)
{
const struct v4l2_mbus_framefmt *format;
+ struct v4l2_subdev_state *state;
struct v4l2_rect window;
unsigned int modulus;
@@ -514,8 +520,8 @@ void vsp1_pipeline_calculate_partition(struct vsp1_pipeline *pipe,
* Partitions are computed on the size before rotation, use the format
* at the WPF sink.
*/
- format = v4l2_subdev_state_get_format(pipe->output->entity.state,
- RWPF_PAD_SINK);
+ state = v4l2_subdev_get_locked_active_state(&pipe->output->entity.subdev);
+ format = v4l2_subdev_state_get_format(state, RWPF_PAD_SINK);
/* Initialise the partition with sane starting conditions. */
window.left = index * div_size;
@@ -152,9 +152,13 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
/* Output location. */
if (pipe->brx) {
+ struct v4l2_subdev *brx_subdev = &pipe->brx->subdev;
+ struct v4l2_subdev_state *brx_state;
const struct v4l2_rect *compose;
- compose = v4l2_subdev_state_get_compose(pipe->brx->state,
+ brx_state = v4l2_subdev_get_locked_active_state(brx_subdev);
+
+ compose = v4l2_subdev_state_get_compose(brx_state,
rpf->brx_input);
left = compose->left;
top = compose->top;
@@ -51,21 +51,11 @@ static int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev,
}
static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *fmt)
{
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- mutex_lock(&rwpf->entity.lock);
-
- state = vsp1_entity_get_state(&rwpf->entity, sd_state, fmt->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
/* Default to YUV if the requested format is not supported. */
if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
@@ -82,7 +72,7 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
*/
format->code = fmt->format.code;
fmt->format = *format;
- goto done;
+ return 0;
}
format->code = fmt->format.code;
@@ -115,19 +105,15 @@ static int vsp1_rwpf_set_format(struct v4l2_subdev *subdev,
format->height = fmt->format.width;
}
-done:
- mutex_unlock(&rwpf->entity.lock);
- return ret;
+ return 0;
}
static int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
/*
* Cropping is only supported on the RPF and is implemented on the sink
@@ -136,14 +122,6 @@ static int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
if (rwpf->entity.type == VSP1_ENTITY_WPF || sel->pad != RWPF_PAD_SINK)
return -EINVAL;
- mutex_lock(&rwpf->entity.lock);
-
- state = vsp1_entity_get_state(&rwpf->entity, sd_state, sel->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
-
switch (sel->target) {
case V4L2_SEL_TGT_CROP:
sel->r = *v4l2_subdev_state_get_crop(state, RWPF_PAD_SINK);
@@ -158,24 +136,19 @@ static int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
break;
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
-done:
- mutex_unlock(&rwpf->entity.lock);
- return ret;
+ return 0;
}
static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
struct vsp1_rwpf *rwpf = to_rwpf(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *crop;
- int ret = 0;
/*
* Cropping is only supported on the RPF and is implemented on the sink
@@ -187,14 +160,6 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
if (sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
- mutex_lock(&rwpf->entity.lock);
-
- state = vsp1_entity_get_state(&rwpf->entity, sd_state, sel->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
-
/* Make sure the crop rectangle is entirely contained in the image. */
format = v4l2_subdev_state_get_format(state, RWPF_PAD_SINK);
@@ -224,15 +189,13 @@ static int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
format->width = crop->width;
format->height = crop->height;
-done:
- mutex_unlock(&rwpf->entity.lock);
- return ret;
+ return 0;
}
static const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops = {
.enum_mbus_code = vsp1_rwpf_enum_mbus_code,
.enum_frame_size = vsp1_rwpf_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = vsp1_rwpf_set_format,
.get_selection = vsp1_rwpf_get_selection,
.set_selection = vsp1_rwpf_set_selection,
@@ -267,6 +230,8 @@ static const struct v4l2_ctrl_ops vsp1_rwpf_ctrl_ops = {
int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf, unsigned int ncontrols)
{
v4l2_ctrl_handler_init(&rwpf->ctrls, ncontrols + 1);
+ rwpf->ctrls.lock = &rwpf->entity.subdev.active_state->_lock;
+
v4l2_ctrl_new_std(&rwpf->ctrls, &vsp1_rwpf_ctrl_ops,
V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
@@ -119,26 +119,15 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev,
}
static int sru_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_frame_size_enum *fse)
{
- struct vsp1_sru *sru = to_sru(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- state = vsp1_entity_get_state(&sru->entity, sd_state, fse->which);
- if (!state)
- return -EINVAL;
format = v4l2_subdev_state_get_format(state, SRU_PAD_SINK);
- mutex_lock(&sru->entity.lock);
-
- if (fse->index || fse->code != format->code) {
- ret = -EINVAL;
- goto done;
- }
+ if (fse->index || fse->code != format->code)
+ return -EINVAL;
if (fse->pad == SRU_PAD_SINK) {
fse->min_width = SRU_MIN_SIZE;
@@ -158,9 +147,7 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev,
}
}
-done:
- mutex_unlock(&sru->entity.lock);
- return ret;
+ return 0;
}
static void sru_try_format(struct vsp1_sru *sru,
@@ -215,21 +202,11 @@ static void sru_try_format(struct vsp1_sru *sru,
}
static int sru_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *fmt)
{
struct vsp1_sru *sru = to_sru(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- mutex_lock(&sru->entity.lock);
-
- state = vsp1_entity_get_state(&sru->entity, sd_state, fmt->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
sru_try_format(sru, state, fmt->pad, &fmt->format);
@@ -244,15 +221,13 @@ static int sru_set_format(struct v4l2_subdev *subdev,
sru_try_format(sru, state, SRU_PAD_SOURCE, format);
}
-done:
- mutex_unlock(&sru->entity.lock);
- return ret;
+ return 0;
}
static const struct v4l2_subdev_pad_ops sru_pad_ops = {
.enum_mbus_code = sru_enum_mbus_code,
.enum_frame_size = sru_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = sru_set_format,
};
@@ -371,6 +346,8 @@ struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1)
/* Initialize the control handler. */
v4l2_ctrl_handler_init(&sru->ctrls, 1);
+ sru->ctrls.lock = &sru->entity.subdev.active_state->_lock;
+
v4l2_ctrl_new_custom(&sru->ctrls, &sru_intensity_control, NULL);
sru->intensity = 1;
@@ -124,26 +124,15 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev,
}
static int uds_enum_frame_size(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_frame_size_enum *fse)
{
- struct vsp1_uds *uds = to_uds(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- state = vsp1_entity_get_state(&uds->entity, sd_state, fse->which);
- if (!state)
- return -EINVAL;
format = v4l2_subdev_state_get_format(state, UDS_PAD_SINK);
- mutex_lock(&uds->entity.lock);
-
- if (fse->index || fse->code != format->code) {
- ret = -EINVAL;
- goto done;
- }
+ if (fse->index || fse->code != format->code)
+ return -EINVAL;
if (fse->pad == UDS_PAD_SINK) {
fse->min_width = UDS_MIN_SIZE;
@@ -157,9 +146,7 @@ static int uds_enum_frame_size(struct v4l2_subdev *subdev,
&fse->max_height);
}
-done:
- mutex_unlock(&uds->entity.lock);
- return ret;
+ return 0;
}
static void uds_try_format(struct vsp1_uds *uds,
@@ -198,21 +185,11 @@ static void uds_try_format(struct vsp1_uds *uds,
}
static int uds_set_format(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_format *fmt)
{
struct vsp1_uds *uds = to_uds(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
-
- mutex_lock(&uds->entity.lock);
-
- state = vsp1_entity_get_state(&uds->entity, sd_state, fmt->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
uds_try_format(uds, state, fmt->pad, &fmt->format);
@@ -227,9 +204,7 @@ static int uds_set_format(struct v4l2_subdev *subdev,
uds_try_format(uds, state, UDS_PAD_SOURCE, format);
}
-done:
- mutex_unlock(&uds->entity.lock);
- return ret;
+ return 0;
}
/* -----------------------------------------------------------------------------
@@ -239,7 +214,7 @@ static int uds_set_format(struct v4l2_subdev *subdev,
static const struct v4l2_subdev_pad_ops uds_pad_ops = {
.enum_mbus_code = uds_enum_mbus_code,
.enum_frame_size = uds_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = uds_set_format,
};
@@ -82,25 +82,14 @@ static int uif_set_format(struct v4l2_subdev *subdev,
}
static int uif_get_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
- struct vsp1_uif *uif = to_uif(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
- int ret = 0;
if (sel->pad != UIF_PAD_SINK)
return -EINVAL;
- mutex_lock(&uif->entity.lock);
-
- state = vsp1_entity_get_state(&uif->entity, sd_state, sel->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
-
switch (sel->target) {
case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_CROP_DEFAULT:
@@ -116,37 +105,23 @@ static int uif_get_selection(struct v4l2_subdev *subdev,
break;
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
-done:
- mutex_unlock(&uif->entity.lock);
- return ret;
+ return 0;
}
static int uif_set_selection(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_state *state,
struct v4l2_subdev_selection *sel)
{
- struct vsp1_uif *uif = to_uif(subdev);
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *selection;
- int ret = 0;
if (sel->pad != UIF_PAD_SINK ||
sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
- mutex_lock(&uif->entity.lock);
-
- state = vsp1_entity_get_state(&uif->entity, sd_state, sel->which);
- if (!state) {
- ret = -EINVAL;
- goto done;
- }
-
/* The crop rectangle must be inside the input frame. */
format = v4l2_subdev_state_get_format(state, UIF_PAD_SINK);
@@ -161,9 +136,7 @@ static int uif_set_selection(struct v4l2_subdev *subdev,
selection = v4l2_subdev_state_get_crop(state, sel->pad);
*selection = sel->r;
-done:
- mutex_unlock(&uif->entity.lock);
- return ret;
+ return 0;
}
/* -----------------------------------------------------------------------------
@@ -173,7 +146,7 @@ static int uif_set_selection(struct v4l2_subdev *subdev,
static const struct v4l2_subdev_pad_ops uif_pad_ops = {
.enum_mbus_code = uif_enum_mbus_code,
.enum_frame_size = uif_enum_frame_size,
- .get_fmt = vsp1_subdev_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = uif_set_format,
.get_selection = uif_get_selection,
.set_selection = uif_set_selection,
@@ -676,6 +676,7 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe)
{
struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
const struct v4l2_mbus_framefmt *format;
+ struct v4l2_subdev_state *state;
struct vsp1_entity *entity;
unsigned int div_size;
unsigned int i;
@@ -684,8 +685,8 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe)
* Partitions are computed on the size before rotation, use the format
* at the WPF sink.
*/
- format = v4l2_subdev_state_get_format(pipe->output->entity.state,
- RWPF_PAD_SINK);
+ state = v4l2_subdev_get_locked_active_state(&pipe->output->entity.subdev);
+ format = v4l2_subdev_state_get_format(state, RWPF_PAD_SINK);
div_size = format->width;
/*
@@ -699,9 +700,8 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe)
if (!entity->ops->max_width)
continue;
- entity_max = entity->ops->max_width(entity,
- entity->state,
- pipe);
+ state = v4l2_subdev_get_locked_active_state(&entity->subdev);
+ entity_max = entity->ops->max_width(entity, state, pipe);
if (entity_max)
div_size = min(div_size, entity_max);
}
@@ -761,8 +761,11 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
return -ENOMEM;
list_for_each_entry(entity, &pipe->entities, list_pipe) {
+ struct v4l2_subdev_state *state;
+
+ state = v4l2_subdev_get_locked_active_state(&entity->subdev);
vsp1_entity_route_setup(entity, pipe, pipe->stream_config);
- vsp1_entity_configure_stream(entity, entity->state, pipe, NULL,
+ vsp1_entity_configure_stream(entity, state, pipe, NULL,
pipe->stream_config);
}
@@ -44,6 +44,7 @@ enum wpf_flip_ctrl {
static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
{
struct vsp1_video *video = wpf->video;
+ struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *sink_format;
struct v4l2_mbus_framefmt *source_format;
bool rotate;
@@ -65,12 +66,10 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
goto done;
}
- sink_format = v4l2_subdev_state_get_format(wpf->entity.state,
- RWPF_PAD_SINK);
- source_format = v4l2_subdev_state_get_format(wpf->entity.state,
- RWPF_PAD_SOURCE);
+ state = v4l2_subdev_get_locked_active_state(&wpf->entity.subdev);
- mutex_lock(&wpf->entity.lock);
+ sink_format = v4l2_subdev_state_get_format(state, RWPF_PAD_SINK);
+ source_format = v4l2_subdev_state_get_format(state, RWPF_PAD_SOURCE);
if (rotate) {
source_format->width = sink_format->height;
@@ -82,8 +81,6 @@ static int vsp1_wpf_set_rotation(struct vsp1_rwpf *wpf, unsigned int rotation)
wpf->flip.rotate = rotate;
- mutex_unlock(&wpf->entity.lock);
-
done:
mutex_unlock(&video->lock);
return ret;