aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core/v4l2-subdev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-18 17:03:51 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-18 17:03:51 -0700
commit19c5abcb74b712a7824ae7c55862932534e7dfec (patch)
tree006822aa663cb9ee886773e819d4793fe3947626 /drivers/media/v4l2-core/v4l2-subdev.c
parent675e0655c12209ba1f40af0dff7cd76b17a1315c (diff)
parentaff093d4bbca91f543e24cde2135f393b8130f4b (diff)
downloadlinux-19c5abcb74b712a7824ae7c55862932534e7dfec.tar.gz
linux-19c5abcb74b712a7824ae7c55862932534e7dfec.tar.bz2
linux-19c5abcb74b712a7824ae7c55862932534e7dfec.zip
Merge tag 'media/v4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - added support for Intersil/Techwell TW686x-based video capture cards - v4l PCI skeleton driver moved to samples directory - Documentation cleanups and improvements - RC: reduced the memory footprint for IR raw events - tpg: Export the tpg code from vivid as a module - adv7180: Add device tree binding documentation - lots of driver improvements and fixes * tag 'media/v4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (173 commits) [media] exynos-gsc: avoid build warning without CONFIG_OF [media] samples: v4l: from Documentation to samples directory [media] dib0700: add USB ID for another STK8096-PVR ref design based card [media] tvp5150: propagate I2C write error in .s_register callback [media] tvp5150: return I2C write operation failure to callers [media] em28xx: add support for Hauppauge WinTV-dualHD DVB tuner [media] em28xx: add missing USB IDs [media] update cx23885 and em28xx cardlists [media] media: au0828 fix au0828_v4l2_device_register() to not unlock and free [media] c8sectpfe: Rework firmware loading mechanism [media] c8sectpfe: Demote print to dev_dbg [media] c8sectpfe: Fix broken circular buffer wp management [media] media-device: Simplify compat32 logic [media] media: i2c: ths7303: remove redundant assignment on bt [media] dvb-usb: hide unused functions [media] xilinx-vipp: remove unnecessary of_node_put [media] drivers/media/media-devnode: clear private_data before put_device() [media] drivers/media/media-device: move debug log before _devnode_unregister() [media] drivers/media/rc: postpone kfree(rc_dev) [media] media/dvb-core: forward media_create_pad_links() return value ...
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-subdev.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index d63083803144..953eab08e420 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -35,9 +35,11 @@
static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
{
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
- fh->pad = kzalloc(sizeof(*fh->pad) * sd->entity.num_pads, GFP_KERNEL);
- if (fh->pad == NULL)
- return -ENOMEM;
+ if (sd->entity.num_pads) {
+ fh->pad = v4l2_subdev_alloc_pad_config(sd);
+ if (fh->pad == NULL)
+ return -ENOMEM;
+ }
#endif
return 0;
}
@@ -45,7 +47,7 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
static void subdev_fh_free(struct v4l2_subdev_fh *fh)
{
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
- kfree(fh->pad);
+ v4l2_subdev_free_pad_config(fh->pad);
fh->pad = NULL;
#endif
}
@@ -508,7 +510,7 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
if (source_fmt->format.width != sink_fmt->format.width
|| source_fmt->format.height != sink_fmt->format.height
|| source_fmt->format.code != sink_fmt->format.code)
- return -EINVAL;
+ return -EPIPE;
/* The field order must match, or the sink field order must be NONE
* to support interlaced hardware connected to bridges that support
@@ -516,7 +518,7 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
*/
if (source_fmt->format.field != sink_fmt->format.field &&
sink_fmt->format.field != V4L2_FIELD_NONE)
- return -EINVAL;
+ return -EPIPE;
return 0;
}
@@ -569,6 +571,35 @@ int v4l2_subdev_link_validate(struct media_link *link)
sink, link, &source_fmt, &sink_fmt);
}
EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate);
+
+struct v4l2_subdev_pad_config *
+v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd)
+{
+ struct v4l2_subdev_pad_config *cfg;
+ int ret;
+
+ if (!sd->entity.num_pads)
+ return NULL;
+
+ cfg = kcalloc(sd->entity.num_pads, sizeof(*cfg), GFP_KERNEL);
+ if (!cfg)
+ return NULL;
+
+ ret = v4l2_subdev_call(sd, pad, init_cfg, cfg);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ kfree(cfg);
+ return NULL;
+ }
+
+ return cfg;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_pad_config);
+
+void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg)
+{
+ kfree(cfg);
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_free_pad_config);
#endif /* CONFIG_MEDIA_CONTROLLER */
void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
@@ -584,6 +615,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
sd->host_priv = NULL;
#if defined(CONFIG_MEDIA_CONTROLLER)
sd->entity.name = sd->name;
+ sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV;
sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
#endif
}