brintos

brintos / linux-shallow public Read only

0
0
Text · 65.3 KiB · 3a4ba08 Raw
2570 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * V4L2 sub-device4 *5 * Copyright (C) 2010 Nokia Corporation6 *7 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>8 *	    Sakari Ailus <sakari.ailus@iki.fi>9 */10 11#include <linux/export.h>12#include <linux/ioctl.h>13#include <linux/leds.h>14#include <linux/mm.h>15#include <linux/module.h>16#include <linux/overflow.h>17#include <linux/slab.h>18#include <linux/string.h>19#include <linux/types.h>20#include <linux/version.h>21#include <linux/videodev2.h>22 23#include <media/v4l2-ctrls.h>24#include <media/v4l2-device.h>25#include <media/v4l2-event.h>26#include <media/v4l2-fh.h>27#include <media/v4l2-ioctl.h>28 29#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)30/*31 * The Streams API is an experimental feature. To use the Streams API, set32 * 'v4l2_subdev_enable_streams_api' to 1 below.33 */34 35static bool v4l2_subdev_enable_streams_api;36#endif37 38/*39 * Maximum stream ID is 63 for now, as we use u64 bitmask to represent a set40 * of streams.41 *42 * Note that V4L2_FRAME_DESC_ENTRY_MAX is related: V4L2_FRAME_DESC_ENTRY_MAX43 * restricts the total number of streams in a pad, although the stream ID is44 * not restricted.45 */46#define V4L2_SUBDEV_MAX_STREAM_ID 6347 48#include "v4l2-subdev-priv.h"49 50#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)51static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)52{53	struct v4l2_subdev_state *state;54	static struct lock_class_key key;55 56	state = __v4l2_subdev_state_alloc(sd, "fh->state->lock", &key);57	if (IS_ERR(state))58		return PTR_ERR(state);59 60	fh->state = state;61 62	return 0;63}64 65static void subdev_fh_free(struct v4l2_subdev_fh *fh)66{67	__v4l2_subdev_state_free(fh->state);68	fh->state = NULL;69}70 71static int subdev_open(struct file *file)72{73	struct video_device *vdev = video_devdata(file);74	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);75	struct v4l2_subdev_fh *subdev_fh;76	int ret;77 78	subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);79	if (subdev_fh == NULL)80		return -ENOMEM;81 82	ret = subdev_fh_init(subdev_fh, sd);83	if (ret) {84		kfree(subdev_fh);85		return ret;86	}87 88	v4l2_fh_init(&subdev_fh->vfh, vdev);89	v4l2_fh_add(&subdev_fh->vfh);90	file->private_data = &subdev_fh->vfh;91 92	if (sd->v4l2_dev->mdev && sd->entity.graph_obj.mdev->dev) {93		struct module *owner;94 95		owner = sd->entity.graph_obj.mdev->dev->driver->owner;96		if (!try_module_get(owner)) {97			ret = -EBUSY;98			goto err;99		}100		subdev_fh->owner = owner;101	}102 103	if (sd->internal_ops && sd->internal_ops->open) {104		ret = sd->internal_ops->open(sd, subdev_fh);105		if (ret < 0)106			goto err;107	}108 109	return 0;110 111err:112	module_put(subdev_fh->owner);113	v4l2_fh_del(&subdev_fh->vfh);114	v4l2_fh_exit(&subdev_fh->vfh);115	subdev_fh_free(subdev_fh);116	kfree(subdev_fh);117 118	return ret;119}120 121static int subdev_close(struct file *file)122{123	struct video_device *vdev = video_devdata(file);124	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);125	struct v4l2_fh *vfh = file->private_data;126	struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);127 128	if (sd->internal_ops && sd->internal_ops->close)129		sd->internal_ops->close(sd, subdev_fh);130	module_put(subdev_fh->owner);131	v4l2_fh_del(vfh);132	v4l2_fh_exit(vfh);133	subdev_fh_free(subdev_fh);134	kfree(subdev_fh);135	file->private_data = NULL;136 137	return 0;138}139#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */140static int subdev_open(struct file *file)141{142	return -ENODEV;143}144 145static int subdev_close(struct file *file)146{147	return -ENODEV;148}149#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */150 151static void v4l2_subdev_enable_privacy_led(struct v4l2_subdev *sd)152{153#if IS_REACHABLE(CONFIG_LEDS_CLASS)154	if (!IS_ERR_OR_NULL(sd->privacy_led))155		led_set_brightness(sd->privacy_led,156				   sd->privacy_led->max_brightness);157#endif158}159 160static void v4l2_subdev_disable_privacy_led(struct v4l2_subdev *sd)161{162#if IS_REACHABLE(CONFIG_LEDS_CLASS)163	if (!IS_ERR_OR_NULL(sd->privacy_led))164		led_set_brightness(sd->privacy_led, 0);165#endif166}167 168static inline int check_which(u32 which)169{170	if (which != V4L2_SUBDEV_FORMAT_TRY &&171	    which != V4L2_SUBDEV_FORMAT_ACTIVE)172		return -EINVAL;173 174	return 0;175}176 177static inline int check_pad(struct v4l2_subdev *sd, u32 pad)178{179#if defined(CONFIG_MEDIA_CONTROLLER)180	if (sd->entity.num_pads) {181		if (pad >= sd->entity.num_pads)182			return -EINVAL;183		return 0;184	}185#endif186	/* allow pad 0 on subdevices not registered as media entities */187	if (pad > 0)188		return -EINVAL;189	return 0;190}191 192static int check_state(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,193		       u32 which, u32 pad, u32 stream)194{195	if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {196#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)197		if (!v4l2_subdev_state_get_format(state, pad, stream))198			return -EINVAL;199		return 0;200#else201		return -EINVAL;202#endif203	}204 205	if (stream != 0)206		return -EINVAL;207 208	if (which == V4L2_SUBDEV_FORMAT_TRY && (!state || !state->pads))209		return -EINVAL;210 211	return 0;212}213 214static inline int check_format(struct v4l2_subdev *sd,215			       struct v4l2_subdev_state *state,216			       struct v4l2_subdev_format *format)217{218	if (!format)219		return -EINVAL;220 221	return check_which(format->which) ? : check_pad(sd, format->pad) ? :222	       check_state(sd, state, format->which, format->pad, format->stream);223}224 225static int call_get_fmt(struct v4l2_subdev *sd,226			struct v4l2_subdev_state *state,227			struct v4l2_subdev_format *format)228{229	return check_format(sd, state, format) ? :230	       sd->ops->pad->get_fmt(sd, state, format);231}232 233static int call_set_fmt(struct v4l2_subdev *sd,234			struct v4l2_subdev_state *state,235			struct v4l2_subdev_format *format)236{237	return check_format(sd, state, format) ? :238	       sd->ops->pad->set_fmt(sd, state, format);239}240 241static int call_enum_mbus_code(struct v4l2_subdev *sd,242			       struct v4l2_subdev_state *state,243			       struct v4l2_subdev_mbus_code_enum *code)244{245	if (!code)246		return -EINVAL;247 248	return check_which(code->which) ? : check_pad(sd, code->pad) ? :249	       check_state(sd, state, code->which, code->pad, code->stream) ? :250	       sd->ops->pad->enum_mbus_code(sd, state, code);251}252 253static int call_enum_frame_size(struct v4l2_subdev *sd,254				struct v4l2_subdev_state *state,255				struct v4l2_subdev_frame_size_enum *fse)256{257	if (!fse)258		return -EINVAL;259 260	return check_which(fse->which) ? : check_pad(sd, fse->pad) ? :261	       check_state(sd, state, fse->which, fse->pad, fse->stream) ? :262	       sd->ops->pad->enum_frame_size(sd, state, fse);263}264 265static int call_enum_frame_interval(struct v4l2_subdev *sd,266				    struct v4l2_subdev_state *state,267				    struct v4l2_subdev_frame_interval_enum *fie)268{269	if (!fie)270		return -EINVAL;271 272	return check_which(fie->which) ? : check_pad(sd, fie->pad) ? :273	       check_state(sd, state, fie->which, fie->pad, fie->stream) ? :274	       sd->ops->pad->enum_frame_interval(sd, state, fie);275}276 277static inline int check_selection(struct v4l2_subdev *sd,278				  struct v4l2_subdev_state *state,279				  struct v4l2_subdev_selection *sel)280{281	if (!sel)282		return -EINVAL;283 284	return check_which(sel->which) ? : check_pad(sd, sel->pad) ? :285	       check_state(sd, state, sel->which, sel->pad, sel->stream);286}287 288static int call_get_selection(struct v4l2_subdev *sd,289			      struct v4l2_subdev_state *state,290			      struct v4l2_subdev_selection *sel)291{292	return check_selection(sd, state, sel) ? :293	       sd->ops->pad->get_selection(sd, state, sel);294}295 296static int call_set_selection(struct v4l2_subdev *sd,297			      struct v4l2_subdev_state *state,298			      struct v4l2_subdev_selection *sel)299{300	return check_selection(sd, state, sel) ? :301	       sd->ops->pad->set_selection(sd, state, sel);302}303 304static inline int check_frame_interval(struct v4l2_subdev *sd,305				       struct v4l2_subdev_state *state,306				       struct v4l2_subdev_frame_interval *fi)307{308	if (!fi)309		return -EINVAL;310 311	return check_which(fi->which) ? : check_pad(sd, fi->pad) ? :312	       check_state(sd, state, fi->which, fi->pad, fi->stream);313}314 315static int call_get_frame_interval(struct v4l2_subdev *sd,316				   struct v4l2_subdev_state *state,317				   struct v4l2_subdev_frame_interval *fi)318{319	return check_frame_interval(sd, state, fi) ? :320	       sd->ops->pad->get_frame_interval(sd, state, fi);321}322 323static int call_set_frame_interval(struct v4l2_subdev *sd,324				   struct v4l2_subdev_state *state,325				   struct v4l2_subdev_frame_interval *fi)326{327	return check_frame_interval(sd, state, fi) ? :328	       sd->ops->pad->set_frame_interval(sd, state, fi);329}330 331static int call_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,332			       struct v4l2_mbus_frame_desc *fd)333{334	unsigned int i;335	int ret;336 337	memset(fd, 0, sizeof(*fd));338 339	ret = sd->ops->pad->get_frame_desc(sd, pad, fd);340	if (ret)341		return ret;342 343	dev_dbg(sd->dev, "Frame descriptor on pad %u, type %s\n", pad,344		fd->type == V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL ? "parallel" :345		fd->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2 ? "CSI-2" :346		"unknown");347 348	for (i = 0; i < fd->num_entries; i++) {349		struct v4l2_mbus_frame_desc_entry *entry = &fd->entry[i];350		char buf[20] = "";351 352		if (fd->type == V4L2_MBUS_FRAME_DESC_TYPE_CSI2)353			WARN_ON(snprintf(buf, sizeof(buf),354					 ", vc %u, dt 0x%02x",355					 entry->bus.csi2.vc,356					 entry->bus.csi2.dt) >= sizeof(buf));357 358		dev_dbg(sd->dev,359			"\tstream %u, code 0x%04x, length %u, flags 0x%04x%s\n",360			entry->stream, entry->pixelcode, entry->length,361			entry->flags, buf);362	}363 364	return 0;365}366 367static inline int check_edid(struct v4l2_subdev *sd,368			     struct v4l2_subdev_edid *edid)369{370	if (!edid)371		return -EINVAL;372 373	if (edid->blocks && edid->edid == NULL)374		return -EINVAL;375 376	return check_pad(sd, edid->pad);377}378 379static int call_get_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)380{381	return check_edid(sd, edid) ? : sd->ops->pad->get_edid(sd, edid);382}383 384static int call_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)385{386	return check_edid(sd, edid) ? : sd->ops->pad->set_edid(sd, edid);387}388 389static int call_s_dv_timings(struct v4l2_subdev *sd, unsigned int pad,390			     struct v4l2_dv_timings *timings)391{392	if (!timings)393		return -EINVAL;394 395	return check_pad(sd, pad) ? :396	       sd->ops->pad->s_dv_timings(sd, pad, timings);397}398 399static int call_g_dv_timings(struct v4l2_subdev *sd, unsigned int pad,400			     struct v4l2_dv_timings *timings)401{402	if (!timings)403		return -EINVAL;404 405	return check_pad(sd, pad) ? :406	       sd->ops->pad->g_dv_timings(sd, pad, timings);407}408 409static int call_query_dv_timings(struct v4l2_subdev *sd, unsigned int pad,410				 struct v4l2_dv_timings *timings)411{412	if (!timings)413		return -EINVAL;414 415	return check_pad(sd, pad) ? :416	       sd->ops->pad->query_dv_timings(sd, pad, timings);417}418 419static int call_dv_timings_cap(struct v4l2_subdev *sd,420			       struct v4l2_dv_timings_cap *cap)421{422	if (!cap)423		return -EINVAL;424 425	return check_pad(sd, cap->pad) ? :426	       sd->ops->pad->dv_timings_cap(sd, cap);427}428 429static int call_enum_dv_timings(struct v4l2_subdev *sd,430				struct v4l2_enum_dv_timings *dvt)431{432	if (!dvt)433		return -EINVAL;434 435	return check_pad(sd, dvt->pad) ? :436	       sd->ops->pad->enum_dv_timings(sd, dvt);437}438 439static int call_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,440				struct v4l2_mbus_config *config)441{442	return check_pad(sd, pad) ? :443	       sd->ops->pad->get_mbus_config(sd, pad, config);444}445 446static int call_s_stream(struct v4l2_subdev *sd, int enable)447{448	int ret;449 450	/*451	 * The .s_stream() operation must never be called to start or stop an452	 * already started or stopped subdev. Catch offenders but don't return453	 * an error yet to avoid regressions.454	 */455	if (WARN_ON(sd->s_stream_enabled == !!enable))456		return 0;457 458	ret = sd->ops->video->s_stream(sd, enable);459 460	if (!enable && ret < 0) {461		dev_warn(sd->dev, "disabling streaming failed (%d)\n", ret);462		ret = 0;463	}464 465	if (!ret) {466		sd->s_stream_enabled = enable;467 468		if (enable)469			v4l2_subdev_enable_privacy_led(sd);470		else471			v4l2_subdev_disable_privacy_led(sd);472	}473 474	return ret;475}476 477#ifdef CONFIG_MEDIA_CONTROLLER478/*479 * Create state-management wrapper for pad ops dealing with subdev state. The480 * wrapper handles the case where the caller does not provide the called481 * subdev's state. This should be removed when all the callers are fixed.482 */483#define DEFINE_STATE_WRAPPER(f, arg_type)                                  \484	static int call_##f##_state(struct v4l2_subdev *sd,                \485				    struct v4l2_subdev_state *_state,      \486				    arg_type *arg)                         \487	{                                                                  \488		struct v4l2_subdev_state *state = _state;                  \489		int ret;                                                   \490		if (!_state)                                               \491			state = v4l2_subdev_lock_and_get_active_state(sd); \492		ret = call_##f(sd, state, arg);                            \493		if (!_state && state)                                      \494			v4l2_subdev_unlock_state(state);                   \495		return ret;                                                \496	}497 498#else /* CONFIG_MEDIA_CONTROLLER */499 500#define DEFINE_STATE_WRAPPER(f, arg_type)                            \501	static int call_##f##_state(struct v4l2_subdev *sd,          \502				    struct v4l2_subdev_state *state, \503				    arg_type *arg)                   \504	{                                                            \505		return call_##f(sd, state, arg);                     \506	}507 508#endif /* CONFIG_MEDIA_CONTROLLER */509 510DEFINE_STATE_WRAPPER(get_fmt, struct v4l2_subdev_format);511DEFINE_STATE_WRAPPER(set_fmt, struct v4l2_subdev_format);512DEFINE_STATE_WRAPPER(enum_mbus_code, struct v4l2_subdev_mbus_code_enum);513DEFINE_STATE_WRAPPER(enum_frame_size, struct v4l2_subdev_frame_size_enum);514DEFINE_STATE_WRAPPER(enum_frame_interval, struct v4l2_subdev_frame_interval_enum);515DEFINE_STATE_WRAPPER(get_selection, struct v4l2_subdev_selection);516DEFINE_STATE_WRAPPER(set_selection, struct v4l2_subdev_selection);517 518static const struct v4l2_subdev_pad_ops v4l2_subdev_call_pad_wrappers = {519	.get_fmt		= call_get_fmt_state,520	.set_fmt		= call_set_fmt_state,521	.enum_mbus_code		= call_enum_mbus_code_state,522	.enum_frame_size	= call_enum_frame_size_state,523	.enum_frame_interval	= call_enum_frame_interval_state,524	.get_selection		= call_get_selection_state,525	.set_selection		= call_set_selection_state,526	.get_frame_interval	= call_get_frame_interval,527	.set_frame_interval	= call_set_frame_interval,528	.get_edid		= call_get_edid,529	.set_edid		= call_set_edid,530	.s_dv_timings		= call_s_dv_timings,531	.g_dv_timings		= call_g_dv_timings,532	.query_dv_timings	= call_query_dv_timings,533	.dv_timings_cap		= call_dv_timings_cap,534	.enum_dv_timings	= call_enum_dv_timings,535	.get_frame_desc		= call_get_frame_desc,536	.get_mbus_config	= call_get_mbus_config,537};538 539static const struct v4l2_subdev_video_ops v4l2_subdev_call_video_wrappers = {540	.s_stream		= call_s_stream,541};542 543const struct v4l2_subdev_ops v4l2_subdev_call_wrappers = {544	.pad	= &v4l2_subdev_call_pad_wrappers,545	.video	= &v4l2_subdev_call_video_wrappers,546};547EXPORT_SYMBOL(v4l2_subdev_call_wrappers);548 549#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)550 551static struct v4l2_subdev_state *552subdev_ioctl_get_state(struct v4l2_subdev *sd, struct v4l2_subdev_fh *subdev_fh,553		       unsigned int cmd, void *arg)554{555	u32 which;556 557	switch (cmd) {558	default:559		return NULL;560	case VIDIOC_SUBDEV_G_FMT:561	case VIDIOC_SUBDEV_S_FMT:562		which = ((struct v4l2_subdev_format *)arg)->which;563		break;564	case VIDIOC_SUBDEV_G_CROP:565	case VIDIOC_SUBDEV_S_CROP:566		which = ((struct v4l2_subdev_crop *)arg)->which;567		break;568	case VIDIOC_SUBDEV_ENUM_MBUS_CODE:569		which = ((struct v4l2_subdev_mbus_code_enum *)arg)->which;570		break;571	case VIDIOC_SUBDEV_ENUM_FRAME_SIZE:572		which = ((struct v4l2_subdev_frame_size_enum *)arg)->which;573		break;574	case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL:575		which = ((struct v4l2_subdev_frame_interval_enum *)arg)->which;576		break;577	case VIDIOC_SUBDEV_G_SELECTION:578	case VIDIOC_SUBDEV_S_SELECTION:579		which = ((struct v4l2_subdev_selection *)arg)->which;580		break;581	case VIDIOC_SUBDEV_G_FRAME_INTERVAL:582	case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {583		struct v4l2_subdev_frame_interval *fi = arg;584 585		if (!(subdev_fh->client_caps &586		      V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH))587			fi->which = V4L2_SUBDEV_FORMAT_ACTIVE;588 589		which = fi->which;590		break;591	}592	case VIDIOC_SUBDEV_G_ROUTING:593	case VIDIOC_SUBDEV_S_ROUTING:594		which = ((struct v4l2_subdev_routing *)arg)->which;595		break;596	}597 598	return which == V4L2_SUBDEV_FORMAT_TRY ?599			     subdev_fh->state :600			     v4l2_subdev_get_unlocked_active_state(sd);601}602 603static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg,604			    struct v4l2_subdev_state *state)605{606	struct video_device *vdev = video_devdata(file);607	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);608	struct v4l2_fh *vfh = file->private_data;609	struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);610	bool ro_subdev = test_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags);611	bool streams_subdev = sd->flags & V4L2_SUBDEV_FL_STREAMS;612	bool client_supports_streams = subdev_fh->client_caps &613				       V4L2_SUBDEV_CLIENT_CAP_STREAMS;614	int rval;615 616	/*617	 * If the streams API is not enabled, remove V4L2_SUBDEV_CAP_STREAMS.618	 * Remove this when the API is no longer experimental.619	 */620	if (!v4l2_subdev_enable_streams_api)621		streams_subdev = false;622 623	switch (cmd) {624	case VIDIOC_SUBDEV_QUERYCAP: {625		struct v4l2_subdev_capability *cap = arg;626 627		memset(cap->reserved, 0, sizeof(cap->reserved));628		cap->version = LINUX_VERSION_CODE;629		cap->capabilities =630			(ro_subdev ? V4L2_SUBDEV_CAP_RO_SUBDEV : 0) |631			(streams_subdev ? V4L2_SUBDEV_CAP_STREAMS : 0);632 633		return 0;634	}635 636	case VIDIOC_QUERYCTRL:637		/*638		 * TODO: this really should be folded into v4l2_queryctrl (this639		 * currently returns -EINVAL for NULL control handlers).640		 * However, v4l2_queryctrl() is still called directly by641		 * drivers as well and until that has been addressed I believe642		 * it is safer to do the check here. The same is true for the643		 * other control ioctls below.644		 */645		if (!vfh->ctrl_handler)646			return -ENOTTY;647		return v4l2_queryctrl(vfh->ctrl_handler, arg);648 649	case VIDIOC_QUERY_EXT_CTRL:650		if (!vfh->ctrl_handler)651			return -ENOTTY;652		return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg);653 654	case VIDIOC_QUERYMENU:655		if (!vfh->ctrl_handler)656			return -ENOTTY;657		return v4l2_querymenu(vfh->ctrl_handler, arg);658 659	case VIDIOC_G_CTRL:660		if (!vfh->ctrl_handler)661			return -ENOTTY;662		return v4l2_g_ctrl(vfh->ctrl_handler, arg);663 664	case VIDIOC_S_CTRL:665		if (!vfh->ctrl_handler)666			return -ENOTTY;667		return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg);668 669	case VIDIOC_G_EXT_CTRLS:670		if (!vfh->ctrl_handler)671			return -ENOTTY;672		return v4l2_g_ext_ctrls(vfh->ctrl_handler,673					vdev, sd->v4l2_dev->mdev, arg);674 675	case VIDIOC_S_EXT_CTRLS:676		if (!vfh->ctrl_handler)677			return -ENOTTY;678		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,679					vdev, sd->v4l2_dev->mdev, arg);680 681	case VIDIOC_TRY_EXT_CTRLS:682		if (!vfh->ctrl_handler)683			return -ENOTTY;684		return v4l2_try_ext_ctrls(vfh->ctrl_handler,685					  vdev, sd->v4l2_dev->mdev, arg);686 687	case VIDIOC_DQEVENT:688		if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))689			return -ENOIOCTLCMD;690 691		return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);692 693	case VIDIOC_SUBSCRIBE_EVENT:694		return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);695 696	case VIDIOC_UNSUBSCRIBE_EVENT:697		return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);698 699#ifdef CONFIG_VIDEO_ADV_DEBUG700	case VIDIOC_DBG_G_REGISTER:701	{702		struct v4l2_dbg_register *p = arg;703 704		if (!capable(CAP_SYS_ADMIN))705			return -EPERM;706		return v4l2_subdev_call(sd, core, g_register, p);707	}708	case VIDIOC_DBG_S_REGISTER:709	{710		struct v4l2_dbg_register *p = arg;711 712		if (!capable(CAP_SYS_ADMIN))713			return -EPERM;714		return v4l2_subdev_call(sd, core, s_register, p);715	}716	case VIDIOC_DBG_G_CHIP_INFO:717	{718		struct v4l2_dbg_chip_info *p = arg;719 720		if (p->match.type != V4L2_CHIP_MATCH_SUBDEV || p->match.addr)721			return -EINVAL;722		if (sd->ops->core && sd->ops->core->s_register)723			p->flags |= V4L2_CHIP_FL_WRITABLE;724		if (sd->ops->core && sd->ops->core->g_register)725			p->flags |= V4L2_CHIP_FL_READABLE;726		strscpy(p->name, sd->name, sizeof(p->name));727		return 0;728	}729#endif730 731	case VIDIOC_LOG_STATUS: {732		int ret;733 734		pr_info("%s: =================  START STATUS  =================\n",735			sd->name);736		ret = v4l2_subdev_call(sd, core, log_status);737		pr_info("%s: ==================  END STATUS  ==================\n",738			sd->name);739		return ret;740	}741 742	case VIDIOC_SUBDEV_G_FMT: {743		struct v4l2_subdev_format *format = arg;744 745		if (!client_supports_streams)746			format->stream = 0;747 748		memset(format->reserved, 0, sizeof(format->reserved));749		memset(format->format.reserved, 0, sizeof(format->format.reserved));750		return v4l2_subdev_call(sd, pad, get_fmt, state, format);751	}752 753	case VIDIOC_SUBDEV_S_FMT: {754		struct v4l2_subdev_format *format = arg;755 756		if (format->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)757			return -EPERM;758 759		if (!client_supports_streams)760			format->stream = 0;761 762		memset(format->reserved, 0, sizeof(format->reserved));763		memset(format->format.reserved, 0, sizeof(format->format.reserved));764		return v4l2_subdev_call(sd, pad, set_fmt, state, format);765	}766 767	case VIDIOC_SUBDEV_G_CROP: {768		struct v4l2_subdev_crop *crop = arg;769		struct v4l2_subdev_selection sel;770 771		if (!client_supports_streams)772			crop->stream = 0;773 774		memset(crop->reserved, 0, sizeof(crop->reserved));775		memset(&sel, 0, sizeof(sel));776		sel.which = crop->which;777		sel.pad = crop->pad;778		sel.stream = crop->stream;779		sel.target = V4L2_SEL_TGT_CROP;780 781		rval = v4l2_subdev_call(782			sd, pad, get_selection, state, &sel);783 784		crop->rect = sel.r;785 786		return rval;787	}788 789	case VIDIOC_SUBDEV_S_CROP: {790		struct v4l2_subdev_crop *crop = arg;791		struct v4l2_subdev_selection sel;792 793		if (crop->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)794			return -EPERM;795 796		if (!client_supports_streams)797			crop->stream = 0;798 799		memset(crop->reserved, 0, sizeof(crop->reserved));800		memset(&sel, 0, sizeof(sel));801		sel.which = crop->which;802		sel.pad = crop->pad;803		sel.stream = crop->stream;804		sel.target = V4L2_SEL_TGT_CROP;805		sel.r = crop->rect;806 807		rval = v4l2_subdev_call(808			sd, pad, set_selection, state, &sel);809 810		crop->rect = sel.r;811 812		return rval;813	}814 815	case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {816		struct v4l2_subdev_mbus_code_enum *code = arg;817 818		if (!client_supports_streams)819			code->stream = 0;820 821		memset(code->reserved, 0, sizeof(code->reserved));822		return v4l2_subdev_call(sd, pad, enum_mbus_code, state,823					code);824	}825 826	case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {827		struct v4l2_subdev_frame_size_enum *fse = arg;828 829		if (!client_supports_streams)830			fse->stream = 0;831 832		memset(fse->reserved, 0, sizeof(fse->reserved));833		return v4l2_subdev_call(sd, pad, enum_frame_size, state,834					fse);835	}836 837	case VIDIOC_SUBDEV_G_FRAME_INTERVAL: {838		struct v4l2_subdev_frame_interval *fi = arg;839 840		if (!client_supports_streams)841			fi->stream = 0;842 843		memset(fi->reserved, 0, sizeof(fi->reserved));844		return v4l2_subdev_call(sd, pad, get_frame_interval, state, fi);845	}846 847	case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {848		struct v4l2_subdev_frame_interval *fi = arg;849 850		if (!client_supports_streams)851			fi->stream = 0;852 853		if (fi->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)854			return -EPERM;855 856		memset(fi->reserved, 0, sizeof(fi->reserved));857		return v4l2_subdev_call(sd, pad, set_frame_interval, state, fi);858	}859 860	case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {861		struct v4l2_subdev_frame_interval_enum *fie = arg;862 863		if (!client_supports_streams)864			fie->stream = 0;865 866		memset(fie->reserved, 0, sizeof(fie->reserved));867		return v4l2_subdev_call(sd, pad, enum_frame_interval, state,868					fie);869	}870 871	case VIDIOC_SUBDEV_G_SELECTION: {872		struct v4l2_subdev_selection *sel = arg;873 874		if (!client_supports_streams)875			sel->stream = 0;876 877		memset(sel->reserved, 0, sizeof(sel->reserved));878		return v4l2_subdev_call(879			sd, pad, get_selection, state, sel);880	}881 882	case VIDIOC_SUBDEV_S_SELECTION: {883		struct v4l2_subdev_selection *sel = arg;884 885		if (sel->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)886			return -EPERM;887 888		if (!client_supports_streams)889			sel->stream = 0;890 891		memset(sel->reserved, 0, sizeof(sel->reserved));892		return v4l2_subdev_call(893			sd, pad, set_selection, state, sel);894	}895 896	case VIDIOC_G_EDID: {897		struct v4l2_subdev_edid *edid = arg;898 899		return v4l2_subdev_call(sd, pad, get_edid, edid);900	}901 902	case VIDIOC_S_EDID: {903		struct v4l2_subdev_edid *edid = arg;904 905		return v4l2_subdev_call(sd, pad, set_edid, edid);906	}907 908	case VIDIOC_SUBDEV_DV_TIMINGS_CAP: {909		struct v4l2_dv_timings_cap *cap = arg;910 911		return v4l2_subdev_call(sd, pad, dv_timings_cap, cap);912	}913 914	case VIDIOC_SUBDEV_ENUM_DV_TIMINGS: {915		struct v4l2_enum_dv_timings *dvt = arg;916 917		return v4l2_subdev_call(sd, pad, enum_dv_timings, dvt);918	}919 920	case VIDIOC_SUBDEV_QUERY_DV_TIMINGS:921		return v4l2_subdev_call(sd, pad, query_dv_timings, 0, arg);922 923	case VIDIOC_SUBDEV_G_DV_TIMINGS:924		return v4l2_subdev_call(sd, pad, g_dv_timings, 0, arg);925 926	case VIDIOC_SUBDEV_S_DV_TIMINGS:927		if (ro_subdev)928			return -EPERM;929 930		return v4l2_subdev_call(sd, pad, s_dv_timings, 0, arg);931 932	case VIDIOC_SUBDEV_G_STD:933		return v4l2_subdev_call(sd, video, g_std, arg);934 935	case VIDIOC_SUBDEV_S_STD: {936		v4l2_std_id *std = arg;937 938		if (ro_subdev)939			return -EPERM;940 941		return v4l2_subdev_call(sd, video, s_std, *std);942	}943 944	case VIDIOC_SUBDEV_ENUMSTD: {945		struct v4l2_standard *p = arg;946		v4l2_std_id id;947 948		if (v4l2_subdev_call(sd, video, g_tvnorms, &id))949			return -EINVAL;950 951		return v4l_video_std_enumstd(p, id);952	}953 954	case VIDIOC_SUBDEV_QUERYSTD:955		return v4l2_subdev_call(sd, video, querystd, arg);956 957	case VIDIOC_SUBDEV_G_ROUTING: {958		struct v4l2_subdev_routing *routing = arg;959		struct v4l2_subdev_krouting *krouting;960 961		if (!v4l2_subdev_enable_streams_api)962			return -ENOIOCTLCMD;963 964		if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))965			return -ENOIOCTLCMD;966 967		memset(routing->reserved, 0, sizeof(routing->reserved));968 969		krouting = &state->routing;970 971		memcpy((struct v4l2_subdev_route *)(uintptr_t)routing->routes,972		       krouting->routes,973		       min(krouting->num_routes, routing->len_routes) *974		       sizeof(*krouting->routes));975		routing->num_routes = krouting->num_routes;976 977		return 0;978	}979 980	case VIDIOC_SUBDEV_S_ROUTING: {981		struct v4l2_subdev_routing *routing = arg;982		struct v4l2_subdev_route *routes =983			(struct v4l2_subdev_route *)(uintptr_t)routing->routes;984		struct v4l2_subdev_krouting krouting = {};985		unsigned int i;986 987		if (!v4l2_subdev_enable_streams_api)988			return -ENOIOCTLCMD;989 990		if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))991			return -ENOIOCTLCMD;992 993		if (routing->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev)994			return -EPERM;995 996		if (routing->num_routes > routing->len_routes)997			return -EINVAL;998 999		memset(routing->reserved, 0, sizeof(routing->reserved));1000 1001		for (i = 0; i < routing->num_routes; ++i) {1002			const struct v4l2_subdev_route *route = &routes[i];1003			const struct media_pad *pads = sd->entity.pads;1004 1005			if (route->sink_stream > V4L2_SUBDEV_MAX_STREAM_ID ||1006			    route->source_stream > V4L2_SUBDEV_MAX_STREAM_ID)1007				return -EINVAL;1008 1009			if (route->sink_pad >= sd->entity.num_pads)1010				return -EINVAL;1011 1012			if (!(pads[route->sink_pad].flags &1013			      MEDIA_PAD_FL_SINK))1014				return -EINVAL;1015 1016			if (route->source_pad >= sd->entity.num_pads)1017				return -EINVAL;1018 1019			if (!(pads[route->source_pad].flags &1020			      MEDIA_PAD_FL_SOURCE))1021				return -EINVAL;1022		}1023 1024		/*1025		 * If the driver doesn't support setting routing, just return1026		 * the routing table.1027		 */1028		if (!v4l2_subdev_has_op(sd, pad, set_routing)) {1029			memcpy((struct v4l2_subdev_route *)(uintptr_t)routing->routes,1030			       state->routing.routes,1031			       min(state->routing.num_routes, routing->len_routes) *1032			       sizeof(*state->routing.routes));1033			routing->num_routes = state->routing.num_routes;1034 1035			return 0;1036		}1037 1038		krouting.num_routes = routing->num_routes;1039		krouting.len_routes = routing->len_routes;1040		krouting.routes = routes;1041 1042		rval = v4l2_subdev_call(sd, pad, set_routing, state,1043					routing->which, &krouting);1044		if (rval < 0)1045			return rval;1046 1047		memcpy((struct v4l2_subdev_route *)(uintptr_t)routing->routes,1048		       state->routing.routes,1049		       min(state->routing.num_routes, routing->len_routes) *1050		       sizeof(*state->routing.routes));1051		routing->num_routes = state->routing.num_routes;1052 1053		return 0;1054	}1055 1056	case VIDIOC_SUBDEV_G_CLIENT_CAP: {1057		struct v4l2_subdev_client_capability *client_cap = arg;1058 1059		client_cap->capabilities = subdev_fh->client_caps;1060 1061		return 0;1062	}1063 1064	case VIDIOC_SUBDEV_S_CLIENT_CAP: {1065		struct v4l2_subdev_client_capability *client_cap = arg;1066 1067		/*1068		 * Clear V4L2_SUBDEV_CLIENT_CAP_STREAMS if streams API is not1069		 * enabled. Remove this when streams API is no longer1070		 * experimental.1071		 */1072		if (!v4l2_subdev_enable_streams_api)1073			client_cap->capabilities &= ~V4L2_SUBDEV_CLIENT_CAP_STREAMS;1074 1075		/* Filter out unsupported capabilities */1076		client_cap->capabilities &= (V4L2_SUBDEV_CLIENT_CAP_STREAMS |1077					     V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH);1078 1079		subdev_fh->client_caps = client_cap->capabilities;1080 1081		return 0;1082	}1083 1084	default:1085		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);1086	}1087 1088	return 0;1089}1090 1091static long subdev_do_ioctl_lock(struct file *file, unsigned int cmd, void *arg)1092{1093	struct video_device *vdev = video_devdata(file);1094	struct mutex *lock = vdev->lock;1095	long ret = -ENODEV;1096 1097	if (lock && mutex_lock_interruptible(lock))1098		return -ERESTARTSYS;1099 1100	if (video_is_registered(vdev)) {1101		struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);1102		struct v4l2_fh *vfh = file->private_data;1103		struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);1104		struct v4l2_subdev_state *state;1105 1106		state = subdev_ioctl_get_state(sd, subdev_fh, cmd, arg);1107 1108		if (state)1109			v4l2_subdev_lock_state(state);1110 1111		ret = subdev_do_ioctl(file, cmd, arg, state);1112 1113		if (state)1114			v4l2_subdev_unlock_state(state);1115	}1116 1117	if (lock)1118		mutex_unlock(lock);1119	return ret;1120}1121 1122static long subdev_ioctl(struct file *file, unsigned int cmd,1123	unsigned long arg)1124{1125	return video_usercopy(file, cmd, arg, subdev_do_ioctl_lock);1126}1127 1128#ifdef CONFIG_COMPAT1129static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,1130	unsigned long arg)1131{1132	struct video_device *vdev = video_devdata(file);1133	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);1134 1135	return v4l2_subdev_call(sd, core, compat_ioctl32, cmd, arg);1136}1137#endif1138 1139#else /* CONFIG_VIDEO_V4L2_SUBDEV_API */1140static long subdev_ioctl(struct file *file, unsigned int cmd,1141			 unsigned long arg)1142{1143	return -ENODEV;1144}1145 1146#ifdef CONFIG_COMPAT1147static long subdev_compat_ioctl32(struct file *file, unsigned int cmd,1148				  unsigned long arg)1149{1150	return -ENODEV;1151}1152#endif1153#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */1154 1155static __poll_t subdev_poll(struct file *file, poll_table *wait)1156{1157	struct video_device *vdev = video_devdata(file);1158	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);1159	struct v4l2_fh *fh = file->private_data;1160 1161	if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))1162		return EPOLLERR;1163 1164	poll_wait(file, &fh->wait, wait);1165 1166	if (v4l2_event_pending(fh))1167		return EPOLLPRI;1168 1169	return 0;1170}1171 1172const struct v4l2_file_operations v4l2_subdev_fops = {1173	.owner = THIS_MODULE,1174	.open = subdev_open,1175	.unlocked_ioctl = subdev_ioctl,1176#ifdef CONFIG_COMPAT1177	.compat_ioctl32 = subdev_compat_ioctl32,1178#endif1179	.release = subdev_close,1180	.poll = subdev_poll,1181};1182 1183#ifdef CONFIG_MEDIA_CONTROLLER1184 1185int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity *entity,1186				      struct fwnode_endpoint *endpoint)1187{1188	struct fwnode_handle *fwnode;1189	struct v4l2_subdev *sd;1190 1191	if (!is_media_entity_v4l2_subdev(entity))1192		return -EINVAL;1193 1194	sd = media_entity_to_v4l2_subdev(entity);1195 1196	fwnode = fwnode_graph_get_port_parent(endpoint->local_fwnode);1197	fwnode_handle_put(fwnode);1198 1199	if (device_match_fwnode(sd->dev, fwnode))1200		return endpoint->port;1201 1202	return -ENXIO;1203}1204EXPORT_SYMBOL_GPL(v4l2_subdev_get_fwnode_pad_1_to_1);1205 1206int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,1207				      struct media_link *link,1208				      struct v4l2_subdev_format *source_fmt,1209				      struct v4l2_subdev_format *sink_fmt)1210{1211	bool pass = true;1212 1213	/* The width, height and code must match. */1214	if (source_fmt->format.width != sink_fmt->format.width) {1215		dev_dbg(sd->entity.graph_obj.mdev->dev,1216			"%s: width does not match (source %u, sink %u)\n",1217			__func__,1218			source_fmt->format.width, sink_fmt->format.width);1219		pass = false;1220	}1221 1222	if (source_fmt->format.height != sink_fmt->format.height) {1223		dev_dbg(sd->entity.graph_obj.mdev->dev,1224			"%s: height does not match (source %u, sink %u)\n",1225			__func__,1226			source_fmt->format.height, sink_fmt->format.height);1227		pass = false;1228	}1229 1230	if (source_fmt->format.code != sink_fmt->format.code) {1231		dev_dbg(sd->entity.graph_obj.mdev->dev,1232			"%s: media bus code does not match (source 0x%8.8x, sink 0x%8.8x)\n",1233			__func__,1234			source_fmt->format.code, sink_fmt->format.code);1235		pass = false;1236	}1237 1238	/* The field order must match, or the sink field order must be NONE1239	 * to support interlaced hardware connected to bridges that support1240	 * progressive formats only.1241	 */1242	if (source_fmt->format.field != sink_fmt->format.field &&1243	    sink_fmt->format.field != V4L2_FIELD_NONE) {1244		dev_dbg(sd->entity.graph_obj.mdev->dev,1245			"%s: field does not match (source %u, sink %u)\n",1246			__func__,1247			source_fmt->format.field, sink_fmt->format.field);1248		pass = false;1249	}1250 1251	if (pass)1252		return 0;1253 1254	dev_dbg(sd->entity.graph_obj.mdev->dev,1255		"%s: link was \"%s\":%u -> \"%s\":%u\n", __func__,1256		link->source->entity->name, link->source->index,1257		link->sink->entity->name, link->sink->index);1258 1259	return -EPIPE;1260}1261EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);1262 1263static int1264v4l2_subdev_link_validate_get_format(struct media_pad *pad, u32 stream,1265				     struct v4l2_subdev_format *fmt,1266				     bool states_locked)1267{1268	struct v4l2_subdev_state *state;1269	struct v4l2_subdev *sd;1270	int ret;1271 1272	sd = media_entity_to_v4l2_subdev(pad->entity);1273 1274	fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;1275	fmt->pad = pad->index;1276	fmt->stream = stream;1277 1278	if (states_locked)1279		state = v4l2_subdev_get_locked_active_state(sd);1280	else1281		state = v4l2_subdev_lock_and_get_active_state(sd);1282 1283	ret = v4l2_subdev_call(sd, pad, get_fmt, state, fmt);1284 1285	if (!states_locked && state)1286		v4l2_subdev_unlock_state(state);1287 1288	return ret;1289}1290 1291#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)1292 1293static void __v4l2_link_validate_get_streams(struct media_pad *pad,1294					     u64 *streams_mask,1295					     bool states_locked)1296{1297	struct v4l2_subdev_route *route;1298	struct v4l2_subdev_state *state;1299	struct v4l2_subdev *subdev;1300 1301	subdev = media_entity_to_v4l2_subdev(pad->entity);1302 1303	*streams_mask = 0;1304 1305	if (states_locked)1306		state = v4l2_subdev_get_locked_active_state(subdev);1307	else1308		state = v4l2_subdev_lock_and_get_active_state(subdev);1309 1310	if (WARN_ON(!state))1311		return;1312 1313	for_each_active_route(&state->routing, route) {1314		u32 route_pad;1315		u32 route_stream;1316 1317		if (pad->flags & MEDIA_PAD_FL_SOURCE) {1318			route_pad = route->source_pad;1319			route_stream = route->source_stream;1320		} else {1321			route_pad = route->sink_pad;1322			route_stream = route->sink_stream;1323		}1324 1325		if (route_pad != pad->index)1326			continue;1327 1328		*streams_mask |= BIT_ULL(route_stream);1329	}1330 1331	if (!states_locked)1332		v4l2_subdev_unlock_state(state);1333}1334 1335#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */1336 1337static void v4l2_link_validate_get_streams(struct media_pad *pad,1338					   u64 *streams_mask,1339					   bool states_locked)1340{1341	struct v4l2_subdev *subdev = media_entity_to_v4l2_subdev(pad->entity);1342 1343	if (!(subdev->flags & V4L2_SUBDEV_FL_STREAMS)) {1344		/* Non-streams subdevs have an implicit stream 0 */1345		*streams_mask = BIT_ULL(0);1346		return;1347	}1348 1349#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)1350	__v4l2_link_validate_get_streams(pad, streams_mask, states_locked);1351#else1352	/* This shouldn't happen */1353	*streams_mask = 0;1354#endif1355}1356 1357static int v4l2_subdev_link_validate_locked(struct media_link *link, bool states_locked)1358{1359	struct v4l2_subdev *sink_subdev =1360		media_entity_to_v4l2_subdev(link->sink->entity);1361	struct device *dev = sink_subdev->entity.graph_obj.mdev->dev;1362	u64 source_streams_mask;1363	u64 sink_streams_mask;1364	u64 dangling_sink_streams;1365	u32 stream;1366	int ret;1367 1368	dev_dbg(dev, "validating link \"%s\":%u -> \"%s\":%u\n",1369		link->source->entity->name, link->source->index,1370		link->sink->entity->name, link->sink->index);1371 1372	v4l2_link_validate_get_streams(link->source, &source_streams_mask, states_locked);1373	v4l2_link_validate_get_streams(link->sink, &sink_streams_mask, states_locked);1374 1375	/*1376	 * It is ok to have more source streams than sink streams as extra1377	 * source streams can just be ignored by the receiver, but having extra1378	 * sink streams is an error as streams must have a source.1379	 */1380	dangling_sink_streams = (source_streams_mask ^ sink_streams_mask) &1381				sink_streams_mask;1382	if (dangling_sink_streams) {1383		dev_err(dev, "Dangling sink streams: mask %#llx\n",1384			dangling_sink_streams);1385		return -EINVAL;1386	}1387 1388	/* Validate source and sink stream formats */1389 1390	for (stream = 0; stream < sizeof(sink_streams_mask) * 8; ++stream) {1391		struct v4l2_subdev_format sink_fmt, source_fmt;1392 1393		if (!(sink_streams_mask & BIT_ULL(stream)))1394			continue;1395 1396		dev_dbg(dev, "validating stream \"%s\":%u:%u -> \"%s\":%u:%u\n",1397			link->source->entity->name, link->source->index, stream,1398			link->sink->entity->name, link->sink->index, stream);1399 1400		ret = v4l2_subdev_link_validate_get_format(link->source, stream,1401							   &source_fmt, states_locked);1402		if (ret < 0) {1403			dev_dbg(dev,1404				"Failed to get format for \"%s\":%u:%u (but that's ok)\n",1405				link->source->entity->name, link->source->index,1406				stream);1407			continue;1408		}1409 1410		ret = v4l2_subdev_link_validate_get_format(link->sink, stream,1411							   &sink_fmt, states_locked);1412		if (ret < 0) {1413			dev_dbg(dev,1414				"Failed to get format for \"%s\":%u:%u (but that's ok)\n",1415				link->sink->entity->name, link->sink->index,1416				stream);1417			continue;1418		}1419 1420		/* TODO: add stream number to link_validate() */1421		ret = v4l2_subdev_call(sink_subdev, pad, link_validate, link,1422				       &source_fmt, &sink_fmt);1423		if (!ret)1424			continue;1425 1426		if (ret != -ENOIOCTLCMD)1427			return ret;1428 1429		ret = v4l2_subdev_link_validate_default(sink_subdev, link,1430							&source_fmt, &sink_fmt);1431 1432		if (ret)1433			return ret;1434	}1435 1436	return 0;1437}1438 1439int v4l2_subdev_link_validate(struct media_link *link)1440{1441	struct v4l2_subdev *source_sd, *sink_sd;1442	struct v4l2_subdev_state *source_state, *sink_state;1443	bool states_locked;1444	int ret;1445 1446	/*1447	 * Links are validated in the context of the sink entity. Usage of this1448	 * helper on a sink that is not a subdev is a clear driver bug.1449	 */1450	if (WARN_ON_ONCE(!is_media_entity_v4l2_subdev(link->sink->entity)))1451		return -EINVAL;1452 1453	/*1454	 * If the source is a video device, delegate link validation to it. This1455	 * allows usage of this helper for subdev connected to a video output1456	 * device, provided that the driver implement the video output device's1457	 * .link_validate() operation.1458	 */1459	if (is_media_entity_v4l2_video_device(link->source->entity)) {1460		struct media_entity *source = link->source->entity;1461 1462		if (!source->ops || !source->ops->link_validate) {1463			/*1464			 * Many existing drivers do not implement the required1465			 * .link_validate() operation for their video devices.1466			 * Print a warning to get the drivers fixed, and return1467			 * 0 to avoid breaking userspace. This should1468			 * eventually be turned into a WARN_ON() when all1469			 * drivers will have been fixed.1470			 */1471			pr_warn_once("video device '%s' does not implement .link_validate(), driver bug!\n",1472				     source->name);1473			return 0;1474		}1475 1476		/*1477		 * Avoid infinite loops in case a video device incorrectly uses1478		 * this helper function as its .link_validate() handler.1479		 */1480		if (WARN_ON(source->ops->link_validate == v4l2_subdev_link_validate))1481			return -EINVAL;1482 1483		return source->ops->link_validate(link);1484	}1485 1486	/*1487	 * If the source is still not a subdev, usage of this helper is a clear1488	 * driver bug.1489	 */1490	if (WARN_ON(!is_media_entity_v4l2_subdev(link->source->entity)))1491		return -EINVAL;1492 1493	sink_sd = media_entity_to_v4l2_subdev(link->sink->entity);1494	source_sd = media_entity_to_v4l2_subdev(link->source->entity);1495 1496	sink_state = v4l2_subdev_get_unlocked_active_state(sink_sd);1497	source_state = v4l2_subdev_get_unlocked_active_state(source_sd);1498 1499	states_locked = sink_state && source_state;1500 1501	if (states_locked)1502		v4l2_subdev_lock_states(sink_state, source_state);1503 1504	ret = v4l2_subdev_link_validate_locked(link, states_locked);1505 1506	if (states_locked)1507		v4l2_subdev_unlock_states(sink_state, source_state);1508 1509	return ret;1510}1511EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate);1512 1513bool v4l2_subdev_has_pad_interdep(struct media_entity *entity,1514				  unsigned int pad0, unsigned int pad1)1515{1516	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);1517	struct v4l2_subdev_krouting *routing;1518	struct v4l2_subdev_state *state;1519	unsigned int i;1520 1521	state = v4l2_subdev_lock_and_get_active_state(sd);1522 1523	routing = &state->routing;1524 1525	for (i = 0; i < routing->num_routes; ++i) {1526		struct v4l2_subdev_route *route = &routing->routes[i];1527 1528		if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))1529			continue;1530 1531		if ((route->sink_pad == pad0 && route->source_pad == pad1) ||1532		    (route->source_pad == pad0 && route->sink_pad == pad1)) {1533			v4l2_subdev_unlock_state(state);1534			return true;1535		}1536	}1537 1538	v4l2_subdev_unlock_state(state);1539 1540	return false;1541}1542EXPORT_SYMBOL_GPL(v4l2_subdev_has_pad_interdep);1543 1544struct v4l2_subdev_state *1545__v4l2_subdev_state_alloc(struct v4l2_subdev *sd, const char *lock_name,1546			  struct lock_class_key *lock_key)1547{1548	struct v4l2_subdev_state *state;1549	int ret;1550 1551	state = kzalloc(sizeof(*state), GFP_KERNEL);1552	if (!state)1553		return ERR_PTR(-ENOMEM);1554 1555	__mutex_init(&state->_lock, lock_name, lock_key);1556	if (sd->state_lock)1557		state->lock = sd->state_lock;1558	else1559		state->lock = &state->_lock;1560 1561	state->sd = sd;1562 1563	/* Drivers that support streams do not need the legacy pad config */1564	if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS) && sd->entity.num_pads) {1565		state->pads = kvcalloc(sd->entity.num_pads,1566				       sizeof(*state->pads), GFP_KERNEL);1567		if (!state->pads) {1568			ret = -ENOMEM;1569			goto err;1570		}1571	}1572 1573	if (sd->internal_ops && sd->internal_ops->init_state) {1574		/*1575		 * There can be no race at this point, but we lock the state1576		 * anyway to satisfy lockdep checks.1577		 */1578		v4l2_subdev_lock_state(state);1579		ret = sd->internal_ops->init_state(sd, state);1580		v4l2_subdev_unlock_state(state);1581 1582		if (ret)1583			goto err;1584	}1585 1586	return state;1587 1588err:1589	if (state && state->pads)1590		kvfree(state->pads);1591 1592	kfree(state);1593 1594	return ERR_PTR(ret);1595}1596EXPORT_SYMBOL_GPL(__v4l2_subdev_state_alloc);1597 1598void __v4l2_subdev_state_free(struct v4l2_subdev_state *state)1599{1600	if (!state)1601		return;1602 1603	mutex_destroy(&state->_lock);1604 1605	kfree(state->routing.routes);1606	kvfree(state->stream_configs.configs);1607	kvfree(state->pads);1608	kfree(state);1609}1610EXPORT_SYMBOL_GPL(__v4l2_subdev_state_free);1611 1612int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name,1613				struct lock_class_key *key)1614{1615	struct v4l2_subdev_state *state;1616	struct device *dev = sd->dev;1617	bool has_disable_streams;1618	bool has_enable_streams;1619	bool has_s_stream;1620 1621	/* Check that the subdevice implements the required features */1622 1623	has_s_stream = v4l2_subdev_has_op(sd, video, s_stream);1624	has_enable_streams = v4l2_subdev_has_op(sd, pad, enable_streams);1625	has_disable_streams = v4l2_subdev_has_op(sd, pad, disable_streams);1626 1627	if (has_enable_streams != has_disable_streams) {1628		dev_err(dev,1629			"subdev '%s' must implement both or neither of .enable_streams() and .disable_streams()\n",1630			sd->name);1631		return -EINVAL;1632	}1633 1634	if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {1635		if (has_s_stream && !has_enable_streams) {1636			dev_err(dev,1637				"subdev '%s' must implement .enable/disable_streams()\n",1638				sd->name);1639 1640			return -EINVAL;1641		}1642	}1643 1644	state = __v4l2_subdev_state_alloc(sd, name, key);1645	if (IS_ERR(state))1646		return PTR_ERR(state);1647 1648	sd->active_state = state;1649 1650	return 0;1651}1652EXPORT_SYMBOL_GPL(__v4l2_subdev_init_finalize);1653 1654void v4l2_subdev_cleanup(struct v4l2_subdev *sd)1655{1656	struct v4l2_async_subdev_endpoint *ase, *ase_tmp;1657 1658	__v4l2_subdev_state_free(sd->active_state);1659	sd->active_state = NULL;1660 1661	/* Uninitialised sub-device, bail out here. */1662	if (!sd->async_subdev_endpoint_list.next)1663		return;1664 1665	list_for_each_entry_safe(ase, ase_tmp, &sd->async_subdev_endpoint_list,1666				 async_subdev_endpoint_entry) {1667		list_del(&ase->async_subdev_endpoint_entry);1668 1669		kfree(ase);1670	}1671}1672EXPORT_SYMBOL_GPL(v4l2_subdev_cleanup);1673 1674struct v4l2_mbus_framefmt *1675__v4l2_subdev_state_get_format(struct v4l2_subdev_state *state,1676			       unsigned int pad, u32 stream)1677{1678	struct v4l2_subdev_stream_configs *stream_configs;1679	unsigned int i;1680 1681	if (WARN_ON_ONCE(!state))1682		return NULL;1683 1684	if (state->pads) {1685		if (stream)1686			return NULL;1687 1688		if (pad >= state->sd->entity.num_pads)1689			return NULL;1690 1691		return &state->pads[pad].format;1692	}1693 1694	lockdep_assert_held(state->lock);1695 1696	stream_configs = &state->stream_configs;1697 1698	for (i = 0; i < stream_configs->num_configs; ++i) {1699		if (stream_configs->configs[i].pad == pad &&1700		    stream_configs->configs[i].stream == stream)1701			return &stream_configs->configs[i].fmt;1702	}1703 1704	return NULL;1705}1706EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_format);1707 1708struct v4l2_rect *1709__v4l2_subdev_state_get_crop(struct v4l2_subdev_state *state, unsigned int pad,1710			     u32 stream)1711{1712	struct v4l2_subdev_stream_configs *stream_configs;1713	unsigned int i;1714 1715	if (WARN_ON_ONCE(!state))1716		return NULL;1717 1718	if (state->pads) {1719		if (stream)1720			return NULL;1721 1722		if (pad >= state->sd->entity.num_pads)1723			return NULL;1724 1725		return &state->pads[pad].crop;1726	}1727 1728	lockdep_assert_held(state->lock);1729 1730	stream_configs = &state->stream_configs;1731 1732	for (i = 0; i < stream_configs->num_configs; ++i) {1733		if (stream_configs->configs[i].pad == pad &&1734		    stream_configs->configs[i].stream == stream)1735			return &stream_configs->configs[i].crop;1736	}1737 1738	return NULL;1739}1740EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_crop);1741 1742struct v4l2_rect *1743__v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state,1744				unsigned int pad, u32 stream)1745{1746	struct v4l2_subdev_stream_configs *stream_configs;1747	unsigned int i;1748 1749	if (WARN_ON_ONCE(!state))1750		return NULL;1751 1752	if (state->pads) {1753		if (stream)1754			return NULL;1755 1756		if (pad >= state->sd->entity.num_pads)1757			return NULL;1758 1759		return &state->pads[pad].compose;1760	}1761 1762	lockdep_assert_held(state->lock);1763 1764	stream_configs = &state->stream_configs;1765 1766	for (i = 0; i < stream_configs->num_configs; ++i) {1767		if (stream_configs->configs[i].pad == pad &&1768		    stream_configs->configs[i].stream == stream)1769			return &stream_configs->configs[i].compose;1770	}1771 1772	return NULL;1773}1774EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_compose);1775 1776struct v4l2_fract *1777__v4l2_subdev_state_get_interval(struct v4l2_subdev_state *state,1778				 unsigned int pad, u32 stream)1779{1780	struct v4l2_subdev_stream_configs *stream_configs;1781	unsigned int i;1782 1783	if (WARN_ON(!state))1784		return NULL;1785 1786	lockdep_assert_held(state->lock);1787 1788	if (state->pads) {1789		if (stream)1790			return NULL;1791 1792		if (pad >= state->sd->entity.num_pads)1793			return NULL;1794 1795		return &state->pads[pad].interval;1796	}1797 1798	lockdep_assert_held(state->lock);1799 1800	stream_configs = &state->stream_configs;1801 1802	for (i = 0; i < stream_configs->num_configs; ++i) {1803		if (stream_configs->configs[i].pad == pad &&1804		    stream_configs->configs[i].stream == stream)1805			return &stream_configs->configs[i].interval;1806	}1807 1808	return NULL;1809}1810EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_interval);1811 1812#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)1813 1814static int1815v4l2_subdev_init_stream_configs(struct v4l2_subdev_stream_configs *stream_configs,1816				const struct v4l2_subdev_krouting *routing)1817{1818	struct v4l2_subdev_stream_configs new_configs = { 0 };1819	struct v4l2_subdev_route *route;1820	u32 idx;1821 1822	/* Count number of formats needed */1823	for_each_active_route(routing, route) {1824		/*1825		 * Each route needs a format on both ends of the route.1826		 */1827		new_configs.num_configs += 2;1828	}1829 1830	if (new_configs.num_configs) {1831		new_configs.configs = kvcalloc(new_configs.num_configs,1832					       sizeof(*new_configs.configs),1833					       GFP_KERNEL);1834 1835		if (!new_configs.configs)1836			return -ENOMEM;1837	}1838 1839	/*1840	 * Fill in the 'pad' and stream' value for each item in the array from1841	 * the routing table1842	 */1843	idx = 0;1844 1845	for_each_active_route(routing, route) {1846		new_configs.configs[idx].pad = route->sink_pad;1847		new_configs.configs[idx].stream = route->sink_stream;1848 1849		idx++;1850 1851		new_configs.configs[idx].pad = route->source_pad;1852		new_configs.configs[idx].stream = route->source_stream;1853 1854		idx++;1855	}1856 1857	kvfree(stream_configs->configs);1858	*stream_configs = new_configs;1859 1860	return 0;1861}1862 1863int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,1864			struct v4l2_subdev_format *format)1865{1866	struct v4l2_mbus_framefmt *fmt;1867 1868	fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);1869	if (!fmt)1870		return -EINVAL;1871 1872	format->format = *fmt;1873 1874	return 0;1875}1876EXPORT_SYMBOL_GPL(v4l2_subdev_get_fmt);1877 1878int v4l2_subdev_get_frame_interval(struct v4l2_subdev *sd,1879				   struct v4l2_subdev_state *state,1880				   struct v4l2_subdev_frame_interval *fi)1881{1882	struct v4l2_fract *interval;1883 1884	interval = v4l2_subdev_state_get_interval(state, fi->pad, fi->stream);1885	if (!interval)1886		return -EINVAL;1887 1888	fi->interval = *interval;1889 1890	return 0;1891}1892EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_interval);1893 1894int v4l2_subdev_set_routing(struct v4l2_subdev *sd,1895			    struct v4l2_subdev_state *state,1896			    const struct v4l2_subdev_krouting *routing)1897{1898	struct v4l2_subdev_krouting *dst = &state->routing;1899	const struct v4l2_subdev_krouting *src = routing;1900	struct v4l2_subdev_krouting new_routing = { 0 };1901	size_t bytes;1902	int r;1903 1904	if (unlikely(check_mul_overflow((size_t)src->num_routes,1905					sizeof(*src->routes), &bytes)))1906		return -EOVERFLOW;1907 1908	lockdep_assert_held(state->lock);1909 1910	if (src->num_routes > 0) {1911		new_routing.routes = kmemdup(src->routes, bytes, GFP_KERNEL);1912		if (!new_routing.routes)1913			return -ENOMEM;1914	}1915 1916	new_routing.num_routes = src->num_routes;1917 1918	r = v4l2_subdev_init_stream_configs(&state->stream_configs,1919					    &new_routing);1920	if (r) {1921		kfree(new_routing.routes);1922		return r;1923	}1924 1925	kfree(dst->routes);1926	*dst = new_routing;1927 1928	return 0;1929}1930EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing);1931 1932struct v4l2_subdev_route *1933__v4l2_subdev_next_active_route(const struct v4l2_subdev_krouting *routing,1934				struct v4l2_subdev_route *route)1935{1936	if (route)1937		++route;1938	else1939		route = &routing->routes[0];1940 1941	for (; route < routing->routes + routing->num_routes; ++route) {1942		if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))1943			continue;1944 1945		return route;1946	}1947 1948	return NULL;1949}1950EXPORT_SYMBOL_GPL(__v4l2_subdev_next_active_route);1951 1952int v4l2_subdev_set_routing_with_fmt(struct v4l2_subdev *sd,1953				     struct v4l2_subdev_state *state,1954				     const struct v4l2_subdev_krouting *routing,1955				     const struct v4l2_mbus_framefmt *fmt)1956{1957	struct v4l2_subdev_stream_configs *stream_configs;1958	unsigned int i;1959	int ret;1960 1961	ret = v4l2_subdev_set_routing(sd, state, routing);1962	if (ret)1963		return ret;1964 1965	stream_configs = &state->stream_configs;1966 1967	for (i = 0; i < stream_configs->num_configs; ++i)1968		stream_configs->configs[i].fmt = *fmt;1969 1970	return 0;1971}1972EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing_with_fmt);1973 1974int v4l2_subdev_routing_find_opposite_end(const struct v4l2_subdev_krouting *routing,1975					  u32 pad, u32 stream, u32 *other_pad,1976					  u32 *other_stream)1977{1978	unsigned int i;1979 1980	for (i = 0; i < routing->num_routes; ++i) {1981		struct v4l2_subdev_route *route = &routing->routes[i];1982 1983		if (route->source_pad == pad &&1984		    route->source_stream == stream) {1985			if (other_pad)1986				*other_pad = route->sink_pad;1987			if (other_stream)1988				*other_stream = route->sink_stream;1989			return 0;1990		}1991 1992		if (route->sink_pad == pad && route->sink_stream == stream) {1993			if (other_pad)1994				*other_pad = route->source_pad;1995			if (other_stream)1996				*other_stream = route->source_stream;1997			return 0;1998		}1999	}2000 2001	return -EINVAL;2002}2003EXPORT_SYMBOL_GPL(v4l2_subdev_routing_find_opposite_end);2004 2005struct v4l2_mbus_framefmt *2006v4l2_subdev_state_get_opposite_stream_format(struct v4l2_subdev_state *state,2007					     u32 pad, u32 stream)2008{2009	u32 other_pad, other_stream;2010	int ret;2011 2012	ret = v4l2_subdev_routing_find_opposite_end(&state->routing,2013						    pad, stream,2014						    &other_pad, &other_stream);2015	if (ret)2016		return NULL;2017 2018	return v4l2_subdev_state_get_format(state, other_pad, other_stream);2019}2020EXPORT_SYMBOL_GPL(v4l2_subdev_state_get_opposite_stream_format);2021 2022u64 v4l2_subdev_state_xlate_streams(const struct v4l2_subdev_state *state,2023				    u32 pad0, u32 pad1, u64 *streams)2024{2025	const struct v4l2_subdev_krouting *routing = &state->routing;2026	struct v4l2_subdev_route *route;2027	u64 streams0 = 0;2028	u64 streams1 = 0;2029 2030	for_each_active_route(routing, route) {2031		if (route->sink_pad == pad0 && route->source_pad == pad1 &&2032		    (*streams & BIT_ULL(route->sink_stream))) {2033			streams0 |= BIT_ULL(route->sink_stream);2034			streams1 |= BIT_ULL(route->source_stream);2035		}2036		if (route->source_pad == pad0 && route->sink_pad == pad1 &&2037		    (*streams & BIT_ULL(route->source_stream))) {2038			streams0 |= BIT_ULL(route->source_stream);2039			streams1 |= BIT_ULL(route->sink_stream);2040		}2041	}2042 2043	*streams = streams0;2044	return streams1;2045}2046EXPORT_SYMBOL_GPL(v4l2_subdev_state_xlate_streams);2047 2048int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,2049				 const struct v4l2_subdev_krouting *routing,2050				 enum v4l2_subdev_routing_restriction disallow)2051{2052	u32 *remote_pads = NULL;2053	unsigned int i, j;2054	int ret = -EINVAL;2055 2056	if (disallow & (V4L2_SUBDEV_ROUTING_NO_STREAM_MIX |2057			V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING)) {2058		remote_pads = kcalloc(sd->entity.num_pads, sizeof(*remote_pads),2059				      GFP_KERNEL);2060		if (!remote_pads)2061			return -ENOMEM;2062 2063		for (i = 0; i < sd->entity.num_pads; ++i)2064			remote_pads[i] = U32_MAX;2065	}2066 2067	for (i = 0; i < routing->num_routes; ++i) {2068		const struct v4l2_subdev_route *route = &routing->routes[i];2069 2070		/* Validate the sink and source pad numbers. */2071		if (route->sink_pad >= sd->entity.num_pads ||2072		    !(sd->entity.pads[route->sink_pad].flags & MEDIA_PAD_FL_SINK)) {2073			dev_dbg(sd->dev, "route %u sink (%u) is not a sink pad\n",2074				i, route->sink_pad);2075			goto out;2076		}2077 2078		if (route->source_pad >= sd->entity.num_pads ||2079		    !(sd->entity.pads[route->source_pad].flags & MEDIA_PAD_FL_SOURCE)) {2080			dev_dbg(sd->dev, "route %u source (%u) is not a source pad\n",2081				i, route->source_pad);2082			goto out;2083		}2084 2085		/*2086		 * V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX: all streams from a2087		 * sink pad must be routed to a single source pad.2088		 */2089		if (disallow & V4L2_SUBDEV_ROUTING_NO_SINK_STREAM_MIX) {2090			if (remote_pads[route->sink_pad] != U32_MAX &&2091			    remote_pads[route->sink_pad] != route->source_pad) {2092				dev_dbg(sd->dev,2093					"route %u attempts to mix %s streams\n",2094					i, "sink");2095				goto out;2096			}2097		}2098 2099		/*2100		 * V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX: all streams on a2101		 * source pad must originate from a single sink pad.2102		 */2103		if (disallow & V4L2_SUBDEV_ROUTING_NO_SOURCE_STREAM_MIX) {2104			if (remote_pads[route->source_pad] != U32_MAX &&2105			    remote_pads[route->source_pad] != route->sink_pad) {2106				dev_dbg(sd->dev,2107					"route %u attempts to mix %s streams\n",2108					i, "source");2109				goto out;2110			}2111		}2112 2113		/*2114		 * V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING: Pads on the sink2115		 * side can not do stream multiplexing, i.e. there can be only2116		 * a single stream in a sink pad.2117		 */2118		if (disallow & V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING) {2119			if (remote_pads[route->sink_pad] != U32_MAX) {2120				dev_dbg(sd->dev,2121					"route %u attempts to multiplex on %s pad %u\n",2122					i, "sink", route->sink_pad);2123				goto out;2124			}2125		}2126 2127		/*2128		 * V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING: Pads on the2129		 * source side can not do stream multiplexing, i.e. there can2130		 * be only a single stream in a source pad.2131		 */2132		if (disallow & V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING) {2133			if (remote_pads[route->source_pad] != U32_MAX) {2134				dev_dbg(sd->dev,2135					"route %u attempts to multiplex on %s pad %u\n",2136					i, "source", route->source_pad);2137				goto out;2138			}2139		}2140 2141		if (remote_pads) {2142			remote_pads[route->sink_pad] = route->source_pad;2143			remote_pads[route->source_pad] = route->sink_pad;2144		}2145 2146		for (j = i + 1; j < routing->num_routes; ++j) {2147			const struct v4l2_subdev_route *r = &routing->routes[j];2148 2149			/*2150			 * V4L2_SUBDEV_ROUTING_NO_1_TO_N: No two routes can2151			 * originate from the same (sink) stream.2152			 */2153			if ((disallow & V4L2_SUBDEV_ROUTING_NO_1_TO_N) &&2154			    route->sink_pad == r->sink_pad &&2155			    route->sink_stream == r->sink_stream) {2156				dev_dbg(sd->dev,2157					"routes %u and %u originate from same sink (%u/%u)\n",2158					i, j, route->sink_pad,2159					route->sink_stream);2160				goto out;2161			}2162 2163			/*2164			 * V4L2_SUBDEV_ROUTING_NO_N_TO_1: No two routes can end2165			 * at the same (source) stream.2166			 */2167			if ((disallow & V4L2_SUBDEV_ROUTING_NO_N_TO_1) &&2168			    route->source_pad == r->source_pad &&2169			    route->source_stream == r->source_stream) {2170				dev_dbg(sd->dev,2171					"routes %u and %u end at same source (%u/%u)\n",2172					i, j, route->source_pad,2173					route->source_stream);2174				goto out;2175			}2176		}2177	}2178 2179	ret = 0;2180 2181out:2182	kfree(remote_pads);2183	return ret;2184}2185EXPORT_SYMBOL_GPL(v4l2_subdev_routing_validate);2186 2187static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd,2188					struct v4l2_subdev_state *state,2189					u32 pad, u64 streams_mask,2190					u64 *found_streams,2191					u64 *enabled_streams)2192{2193	if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS)) {2194		*found_streams = BIT_ULL(0);2195		*enabled_streams =2196			(sd->enabled_pads & BIT_ULL(pad)) ? BIT_ULL(0) : 0;2197		return;2198	}2199 2200	*found_streams = 0;2201	*enabled_streams = 0;2202 2203	for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {2204		const struct v4l2_subdev_stream_config *cfg =2205			&state->stream_configs.configs[i];2206 2207		if (cfg->pad != pad || !(streams_mask & BIT_ULL(cfg->stream)))2208			continue;2209 2210		*found_streams |= BIT_ULL(cfg->stream);2211		if (cfg->enabled)2212			*enabled_streams |= BIT_ULL(cfg->stream);2213	}2214}2215 2216static void v4l2_subdev_set_streams_enabled(struct v4l2_subdev *sd,2217					    struct v4l2_subdev_state *state,2218					    u32 pad, u64 streams_mask,2219					    bool enabled)2220{2221	if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS)) {2222		if (enabled)2223			sd->enabled_pads |= BIT_ULL(pad);2224		else2225			sd->enabled_pads &= ~BIT_ULL(pad);2226		return;2227	}2228 2229	for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {2230		struct v4l2_subdev_stream_config *cfg =2231			&state->stream_configs.configs[i];2232 2233		if (cfg->pad == pad && (streams_mask & BIT_ULL(cfg->stream)))2234			cfg->enabled = enabled;2235	}2236}2237 2238int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad,2239			       u64 streams_mask)2240{2241	struct device *dev = sd->entity.graph_obj.mdev->dev;2242	struct v4l2_subdev_state *state;2243	bool already_streaming;2244	u64 enabled_streams;2245	u64 found_streams;2246	bool use_s_stream;2247	int ret;2248 2249	/* A few basic sanity checks first. */2250	if (pad >= sd->entity.num_pads)2251		return -EINVAL;2252 2253	if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))2254		return -EOPNOTSUPP;2255 2256	/*2257	 * We use a 64-bit bitmask for tracking enabled pads, so only subdevices2258	 * with 64 pads or less can be supported.2259	 */2260	if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)2261		return -EOPNOTSUPP;2262 2263	if (!streams_mask)2264		return 0;2265 2266	/* Fallback on .s_stream() if .enable_streams() isn't available. */2267	use_s_stream = !v4l2_subdev_has_op(sd, pad, enable_streams);2268 2269	if (!use_s_stream)2270		state = v4l2_subdev_lock_and_get_active_state(sd);2271	else2272		state = NULL;2273 2274	/*2275	 * Verify that the requested streams exist and that they are not2276	 * already enabled.2277	 */2278 2279	v4l2_subdev_collect_streams(sd, state, pad, streams_mask,2280				    &found_streams, &enabled_streams);2281 2282	if (found_streams != streams_mask) {2283		dev_dbg(dev, "streams 0x%llx not found on %s:%u\n",2284			streams_mask & ~found_streams, sd->entity.name, pad);2285		ret = -EINVAL;2286		goto done;2287	}2288 2289	if (enabled_streams) {2290		dev_dbg(dev, "streams 0x%llx already enabled on %s:%u\n",2291			enabled_streams, sd->entity.name, pad);2292		ret = -EALREADY;2293		goto done;2294	}2295 2296	dev_dbg(dev, "enable streams %u:%#llx\n", pad, streams_mask);2297 2298	already_streaming = v4l2_subdev_is_streaming(sd);2299 2300	if (!use_s_stream) {2301		/* Call the .enable_streams() operation. */2302		ret = v4l2_subdev_call(sd, pad, enable_streams, state, pad,2303				       streams_mask);2304	} else {2305		/* Start streaming when the first pad is enabled. */2306		if (!already_streaming)2307			ret = v4l2_subdev_call(sd, video, s_stream, 1);2308		else2309			ret = 0;2310	}2311 2312	if (ret) {2313		dev_dbg(dev, "enable streams %u:%#llx failed: %d\n", pad,2314			streams_mask, ret);2315		goto done;2316	}2317 2318	/* Mark the streams as enabled. */2319	v4l2_subdev_set_streams_enabled(sd, state, pad, streams_mask, true);2320 2321	/*2322	 * TODO: When all the drivers have been changed to use2323	 * v4l2_subdev_enable_streams() and v4l2_subdev_disable_streams(),2324	 * instead of calling .s_stream() operation directly, we can remove2325	 * the privacy LED handling from call_s_stream() and do it here2326	 * for all cases.2327	 */2328	if (!use_s_stream && !already_streaming)2329		v4l2_subdev_enable_privacy_led(sd);2330 2331done:2332	if (!use_s_stream)2333		v4l2_subdev_unlock_state(state);2334 2335	return ret;2336}2337EXPORT_SYMBOL_GPL(v4l2_subdev_enable_streams);2338 2339int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad,2340				u64 streams_mask)2341{2342	struct device *dev = sd->entity.graph_obj.mdev->dev;2343	struct v4l2_subdev_state *state;2344	u64 enabled_streams;2345	u64 found_streams;2346	bool use_s_stream;2347	int ret;2348 2349	/* A few basic sanity checks first. */2350	if (pad >= sd->entity.num_pads)2351		return -EINVAL;2352 2353	if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))2354		return -EOPNOTSUPP;2355 2356	/*2357	 * We use a 64-bit bitmask for tracking enabled pads, so only subdevices2358	 * with 64 pads or less can be supported.2359	 */2360	if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)2361		return -EOPNOTSUPP;2362 2363	if (!streams_mask)2364		return 0;2365 2366	/* Fallback on .s_stream() if .disable_streams() isn't available. */2367	use_s_stream = !v4l2_subdev_has_op(sd, pad, disable_streams);2368 2369	if (!use_s_stream)2370		state = v4l2_subdev_lock_and_get_active_state(sd);2371	else2372		state = NULL;2373 2374	/*2375	 * Verify that the requested streams exist and that they are not2376	 * already disabled.2377	 */2378 2379	v4l2_subdev_collect_streams(sd, state, pad, streams_mask,2380				    &found_streams, &enabled_streams);2381 2382	if (found_streams != streams_mask) {2383		dev_dbg(dev, "streams 0x%llx not found on %s:%u\n",2384			streams_mask & ~found_streams, sd->entity.name, pad);2385		ret = -EINVAL;2386		goto done;2387	}2388 2389	if (enabled_streams != streams_mask) {2390		dev_dbg(dev, "streams 0x%llx already disabled on %s:%u\n",2391			streams_mask & ~enabled_streams, sd->entity.name, pad);2392		ret = -EALREADY;2393		goto done;2394	}2395 2396	dev_dbg(dev, "disable streams %u:%#llx\n", pad, streams_mask);2397 2398	if (!use_s_stream) {2399		/* Call the .disable_streams() operation. */2400		ret = v4l2_subdev_call(sd, pad, disable_streams, state, pad,2401				       streams_mask);2402	} else {2403		/* Stop streaming when the last streams are disabled. */2404 2405		if (!(sd->enabled_pads & ~BIT_ULL(pad)))2406			ret = v4l2_subdev_call(sd, video, s_stream, 0);2407		else2408			ret = 0;2409	}2410 2411	if (ret) {2412		dev_dbg(dev, "disable streams %u:%#llx failed: %d\n", pad,2413			streams_mask, ret);2414		goto done;2415	}2416 2417	v4l2_subdev_set_streams_enabled(sd, state, pad, streams_mask, false);2418 2419done:2420	if (!use_s_stream) {2421		if (!v4l2_subdev_is_streaming(sd))2422			v4l2_subdev_disable_privacy_led(sd);2423 2424		v4l2_subdev_unlock_state(state);2425	}2426 2427	return ret;2428}2429EXPORT_SYMBOL_GPL(v4l2_subdev_disable_streams);2430 2431int v4l2_subdev_s_stream_helper(struct v4l2_subdev *sd, int enable)2432{2433	struct v4l2_subdev_state *state;2434	struct v4l2_subdev_route *route;2435	struct media_pad *pad;2436	u64 source_mask = 0;2437	int pad_index = -1;2438 2439	/*2440	 * Find the source pad. This helper is meant for subdevs that have a2441	 * single source pad, so failures shouldn't happen, but catch them2442	 * loudly nonetheless as they indicate a driver bug.2443	 */2444	media_entity_for_each_pad(&sd->entity, pad) {2445		if (pad->flags & MEDIA_PAD_FL_SOURCE) {2446			pad_index = pad->index;2447			break;2448		}2449	}2450 2451	if (WARN_ON(pad_index == -1))2452		return -EINVAL;2453 2454	if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {2455		/*2456		 * As there's a single source pad, just collect all the source2457		 * streams.2458		 */2459		state = v4l2_subdev_lock_and_get_active_state(sd);2460 2461		for_each_active_route(&state->routing, route)2462			source_mask |= BIT_ULL(route->source_stream);2463 2464		v4l2_subdev_unlock_state(state);2465	} else {2466		/*2467		 * For non-streams subdevices, there's a single implicit stream2468		 * per pad.2469		 */2470		source_mask = BIT_ULL(0);2471	}2472 2473	if (enable)2474		return v4l2_subdev_enable_streams(sd, pad_index, source_mask);2475	else2476		return v4l2_subdev_disable_streams(sd, pad_index, source_mask);2477}2478EXPORT_SYMBOL_GPL(v4l2_subdev_s_stream_helper);2479 2480#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */2481 2482#endif /* CONFIG_MEDIA_CONTROLLER */2483 2484void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)2485{2486	INIT_LIST_HEAD(&sd->list);2487	BUG_ON(!ops);2488	sd->ops = ops;2489	sd->v4l2_dev = NULL;2490	sd->flags = 0;2491	sd->name[0] = '\0';2492	sd->grp_id = 0;2493	sd->dev_priv = NULL;2494	sd->host_priv = NULL;2495	sd->privacy_led = NULL;2496	INIT_LIST_HEAD(&sd->async_subdev_endpoint_list);2497#if defined(CONFIG_MEDIA_CONTROLLER)2498	sd->entity.name = sd->name;2499	sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV;2500	sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;2501#endif2502}2503EXPORT_SYMBOL(v4l2_subdev_init);2504 2505void v4l2_subdev_notify_event(struct v4l2_subdev *sd,2506			      const struct v4l2_event *ev)2507{2508	v4l2_event_queue(sd->devnode, ev);2509	v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, (void *)ev);2510}2511EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event);2512 2513bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd)2514{2515	struct v4l2_subdev_state *state;2516 2517	if (!v4l2_subdev_has_op(sd, pad, enable_streams))2518		return sd->s_stream_enabled;2519 2520	if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))2521		return !!sd->enabled_pads;2522 2523	state = v4l2_subdev_get_locked_active_state(sd);2524 2525	for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {2526		const struct v4l2_subdev_stream_config *cfg;2527 2528		cfg = &state->stream_configs.configs[i];2529 2530		if (cfg->enabled)2531			return true;2532	}2533 2534	return false;2535}2536EXPORT_SYMBOL_GPL(v4l2_subdev_is_streaming);2537 2538int v4l2_subdev_get_privacy_led(struct v4l2_subdev *sd)2539{2540#if IS_REACHABLE(CONFIG_LEDS_CLASS)2541	sd->privacy_led = led_get(sd->dev, "privacy-led");2542	if (IS_ERR(sd->privacy_led) && PTR_ERR(sd->privacy_led) != -ENOENT)2543		return dev_err_probe(sd->dev, PTR_ERR(sd->privacy_led),2544				     "getting privacy LED\n");2545 2546	if (!IS_ERR_OR_NULL(sd->privacy_led)) {2547		mutex_lock(&sd->privacy_led->led_access);2548		led_sysfs_disable(sd->privacy_led);2549		led_trigger_remove(sd->privacy_led);2550		led_set_brightness(sd->privacy_led, 0);2551		mutex_unlock(&sd->privacy_led->led_access);2552	}2553#endif2554	return 0;2555}2556EXPORT_SYMBOL_GPL(v4l2_subdev_get_privacy_led);2557 2558void v4l2_subdev_put_privacy_led(struct v4l2_subdev *sd)2559{2560#if IS_REACHABLE(CONFIG_LEDS_CLASS)2561	if (!IS_ERR_OR_NULL(sd->privacy_led)) {2562		mutex_lock(&sd->privacy_led->led_access);2563		led_sysfs_enable(sd->privacy_led);2564		mutex_unlock(&sd->privacy_led->led_access);2565		led_put(sd->privacy_led);2566	}2567#endif2568}2569EXPORT_SYMBOL_GPL(v4l2_subdev_put_privacy_led);2570