From patchwork Mon Aug 30 11:00:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504827 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 099CBC4320E for ; Mon, 30 Aug 2021 11:02:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E3A7561107 for ; Mon, 30 Aug 2021 11:02:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236408AbhH3LDI (ORCPT ); Mon, 30 Aug 2021 07:03:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56098 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236394AbhH3LDH (ORCPT ); Mon, 30 Aug 2021 07:03:07 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38C5EC06175F for ; Mon, 30 Aug 2021 04:02:14 -0700 (PDT) Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 84B328AD; Mon, 30 Aug 2021 13:02:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321331; bh=OkzH4CusK1IQ4GrZtmEiH3oJV7ezbnjSgjAf9XPreVk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tcw+dyH/Gm0wWQ5Cq84CbjleB8zLvJeYcjaPyjJlP8nwbKnsrgbrkGdSXTHHcO5Sz oz9eXWJikZr1zAZTwdQqfoXKvaJxjUbqKLaDbF951oIxIHCEnm+rh7UUEsHM/AFqtb 5DXNiXdA6+HkTNLcYFikvgJPcuvcryGcfrS/cE1g= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 01/36] media: subdev: rename subdev-state alloc & free Date: Mon, 30 Aug 2021 14:00:41 +0300 Message-Id: <20210830110116.488338-2-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The recently added v4l2_subdev_alloc_state() and v4l2_subdev_free_state() were somewhat badly named. They allocate/free the state that can be used for a subdev, but they don't change the subdev itself in any way. In the future we want to have the subdev state available easily for all subdevs, and we want to store the state to subdev struct. Thus we will be needing a new function which allocates the state and stores it into the subdev struct. This patch renames v4l2_subdev_alloc/free_state functions to v4l2_alloc/free_subdev_state, so that we can later use v4l2_subdev_alloc/free_state for the versions which work on the subdev struct. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 4 ++-- drivers/media/platform/vsp1/vsp1_entity.c | 4 ++-- drivers/media/v4l2-core/v4l2-subdev.c | 12 ++++++------ drivers/staging/media/tegra-video/vi.c | 4 ++-- include/media/v4l2-subdev.h | 10 +++++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 0d141155f0e3..5f4fa8c48f68 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -252,7 +252,7 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, u32 width, height; int ret; - sd_state = v4l2_subdev_alloc_state(sd); + sd_state = v4l2_alloc_subdev_state(sd); if (IS_ERR(sd_state)) return PTR_ERR(sd_state); @@ -288,7 +288,7 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, rvin_format_align(vin, pix); done: - v4l2_subdev_free_state(sd_state); + v4l2_free_subdev_state(sd_state); return ret; } diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index 823c15facd1b..e40bca254b8b 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -675,7 +675,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, * Allocate the pad configuration to store formats and selection * rectangles. */ - entity->config = v4l2_subdev_alloc_state(&entity->subdev); + entity->config = v4l2_alloc_subdev_state(&entity->subdev); if (IS_ERR(entity->config)) { media_entity_cleanup(&entity->subdev.entity); return PTR_ERR(entity->config); @@ -690,6 +690,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_free_state(entity->config); + v4l2_free_subdev_state(entity->config); media_entity_cleanup(&entity->subdev.entity); } diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 5d27a27cc2f2..26a34a8e3d37 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -28,7 +28,7 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) { struct v4l2_subdev_state *state; - state = v4l2_subdev_alloc_state(sd); + state = v4l2_alloc_subdev_state(sd); if (IS_ERR(state)) return PTR_ERR(state); @@ -39,7 +39,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) { - v4l2_subdev_free_state(fh->state); + v4l2_free_subdev_state(fh->state); fh->state = NULL; } @@ -870,7 +870,7 @@ int v4l2_subdev_link_validate(struct media_link *link) } EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); -struct v4l2_subdev_state *v4l2_subdev_alloc_state(struct v4l2_subdev *sd) +struct v4l2_subdev_state *v4l2_alloc_subdev_state(struct v4l2_subdev *sd) { struct v4l2_subdev_state *state; int ret; @@ -903,9 +903,9 @@ struct v4l2_subdev_state *v4l2_subdev_alloc_state(struct v4l2_subdev *sd) return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_state); +EXPORT_SYMBOL_GPL(v4l2_alloc_subdev_state); -void v4l2_subdev_free_state(struct v4l2_subdev_state *state) +void v4l2_free_subdev_state(struct v4l2_subdev_state *state) { if (!state) return; @@ -913,7 +913,7 @@ void v4l2_subdev_free_state(struct v4l2_subdev_state *state) kvfree(state->pads); kfree(state); } -EXPORT_SYMBOL_GPL(v4l2_subdev_free_state); +EXPORT_SYMBOL_GPL(v4l2_free_subdev_state); #endif /* CONFIG_MEDIA_CONTROLLER */ diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index d321790b07d9..a94d19e2a67c 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -507,7 +507,7 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, if (!subdev) return -ENODEV; - sd_state = v4l2_subdev_alloc_state(subdev); + sd_state = v4l2_alloc_subdev_state(subdev); if (IS_ERR(sd_state)) return PTR_ERR(sd_state); /* @@ -558,7 +558,7 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, v4l2_fill_pix_format(pix, &fmt.format); tegra_channel_fmt_align(chan, pix, fmtinfo->bpp); - v4l2_subdev_free_state(sd_state); + v4l2_free_subdev_state(sd_state); return 0; } diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 95ec18c2f49c..8701d2e7d893 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1135,20 +1135,20 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, int v4l2_subdev_link_validate(struct media_link *link); /** - * v4l2_subdev_alloc_state - allocate v4l2_subdev_state + * v4l2_alloc_subdev_state - allocate v4l2_subdev_state * * @sd: pointer to &struct v4l2_subdev for which the state is being allocated. * - * Must call v4l2_subdev_free_state() when state is no longer needed. + * Must call v4l2_free_subdev_state() when state is no longer needed. */ -struct v4l2_subdev_state *v4l2_subdev_alloc_state(struct v4l2_subdev *sd); +struct v4l2_subdev_state *v4l2_alloc_subdev_state(struct v4l2_subdev *sd); /** - * v4l2_subdev_free_state - free a v4l2_subdev_state + * v4l2_free_subdev_state - free a v4l2_subdev_state * * @state: v4l2_subdev_state to be freed. */ -void v4l2_subdev_free_state(struct v4l2_subdev_state *state); +void v4l2_free_subdev_state(struct v4l2_subdev_state *state); #endif /* CONFIG_MEDIA_CONTROLLER */ From patchwork Mon Aug 30 11:00:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504826 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5948CC43214 for ; Mon, 30 Aug 2021 11:02:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3AE486112D for ; Mon, 30 Aug 2021 11:02:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236415AbhH3LDI (ORCPT ); Mon, 30 Aug 2021 07:03:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235818AbhH3LDH (ORCPT ); Mon, 30 Aug 2021 07:03:07 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3301AC061575 for ; Mon, 30 Aug 2021 04:02:14 -0700 (PDT) Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 807C9B7E; Mon, 30 Aug 2021 13:02:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321332; bh=TqC8KE4m6EQXQb81jhWD4hKKuzOiVDbnOxQvEHkZcXI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vgIJnoBbQhY53dML8E+kTEvVsbXnYuUB8lPXdxQVVqeL97ZdNsYsdPPleyGQqdZdk 9+RJcuxUCRpk58epvUk0ImyvSTKRw93FT1GJE/lQVPnkpo8IjBqcoC/kFr1ztkY4Wf KF2iKobkWNO20JkNfLjfVKeZWR11rKAZquDEPl1U= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 02/36] media: subdev: add active state to struct v4l2_subdev Date: Mon, 30 Aug 2021 14:00:42 +0300 Message-Id: <20210830110116.488338-3-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add a new 'state' field to struct v4l2_subdev to which we can store the active state of a subdev. This will place the subdev configuration into a known place, allowing us to use the state directly from the v4l2 framework, thus simplifying the drivers. We also add v4l2_subdev_alloc_state() and v4l2_subdev_free_state(), which need to be used by the drivers that support subdev state in struct v4l2_subdev. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 21 ++++++++++++++++ include/media/v4l2-subdev.h | 36 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 26a34a8e3d37..e1a794f69815 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -943,3 +943,24 @@ void v4l2_subdev_notify_event(struct v4l2_subdev *sd, v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, (void *)ev); } EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event); + +int v4l2_subdev_alloc_state(struct v4l2_subdev *sd) +{ + struct v4l2_subdev_state *state; + + state = v4l2_alloc_subdev_state(sd); + if (IS_ERR(state)) + return PTR_ERR(state); + + sd->state = state; + + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_state); + +void v4l2_subdev_free_state(struct v4l2_subdev *sd) +{ + v4l2_free_subdev_state(sd->state); + sd->state = NULL; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_free_state); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 8701d2e7d893..ecaf040ead57 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -898,6 +898,8 @@ struct v4l2_subdev_platform_data { * @subdev_notifier: A sub-device notifier implicitly registered for the sub- * device using v4l2_async_register_subdev_sensor(). * @pdata: common part of subdevice platform data + * @state: active state for the subdev (NULL for subdevs tracking the state + * internally) * * Each instance of a subdev driver should create this struct, either * stand-alone or embedded in a larger struct. @@ -929,6 +931,7 @@ struct v4l2_subdev { struct v4l2_async_notifier *notifier; struct v4l2_async_notifier *subdev_notifier; struct v4l2_subdev_platform_data *pdata; + struct v4l2_subdev_state *state; }; @@ -1217,4 +1220,37 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers; void v4l2_subdev_notify_event(struct v4l2_subdev *sd, const struct v4l2_event *ev); +/** + * v4l2_subdev_alloc_state() - Allocate active subdev state for subdevice + * @sd: The subdev for which the state is allocated + * + * This will allocate a subdev state and store it to + * &struct v4l2_subdev->state. + * + * Must call v4l2_subdev_free_state() when the state is no longer needed. + */ +int v4l2_subdev_alloc_state(struct v4l2_subdev *sd); + +/** + * v4l2_subdev_free_state() - Free the active subdev state for subdevice + * @sd: The subdevice + * + * This will free the subdev's state and set + * &struct v4l2_subdev->state to NULL. + */ +void v4l2_subdev_free_state(struct v4l2_subdev *sd); + +/** + * v4l2_subdev_get_active_state() - Return the active subdev state for subdevice + * @sd: The subdevice + * + * Return the active state for the subdevice, or NULL if the subdev does not + * support active state. + */ +static inline struct v4l2_subdev_state * +v4l2_subdev_get_active_state(struct v4l2_subdev *sd) +{ + return sd->state; +} + #endif From patchwork Mon Aug 30 11:00:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504501 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1ADFC43216 for ; Mon, 30 Aug 2021 11:02:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CA6076113E for ; Mon, 30 Aug 2021 11:02:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236434AbhH3LDJ (ORCPT ); Mon, 30 Aug 2021 07:03:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56106 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235818AbhH3LDJ (ORCPT ); Mon, 30 Aug 2021 07:03:09 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B774BC061575 for ; Mon, 30 Aug 2021 04:02:15 -0700 (PDT) Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 69149B9C; Mon, 30 Aug 2021 13:02:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321333; bh=6ixnkitdFV8wkw/jxpb4KNH0fDO9jVN/+XJikhlaYf4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ghxigdf8aN6FZvQc6sZypTHhhHSm6q3BXA0AYDphfq1R8kZ70MACcDbDvyWz1/b4S s3lTPrDxq3ldwgOS3Pbc8IXFXcI0OT2j/claw71OfN1gfsdEZnvJY1Y1ESW/4mVrDF hZViKQ/DLS1sb3xtUJqG3aLPElZcuZO1Isb0arhQ= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 03/36] media: subdev: add 'which' to subdev state Date: Mon, 30 Aug 2021 14:00:43 +0300 Message-Id: <20210830110116.488338-4-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The subdev state is passed to functions in the media drivers, and usually either V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY is also given to the function in one way or another. One op where this is not the case is v4l2_subdev_pad_ops.init_cfg. One could argue that the initialization of the state should be the same for both ACTIVE and TRY cases, but unfortunately that is not the case: - Some drivers do also other things than just touch the state when dealing with ACTIVE, e.g. if there is extra state outside the standard subdev state. - Some drivers might need to create, say, struct v4l2_subdev_format which has 'which' field, and that needs to be filled with either ACTIVE or TRY. Currently init_cfg is only called for TRY case from the v4l2 framework, passing the TRY state. Some drivers call their own init_cfg, passing NULL as the state, which is used to indicate ACTIVE case. In the future we want to pass subdev's active state from the v4l2 framework side, so we need a solution to this. We could change the init_cfg() to include the TRY/ACTIVE value, which would require changing more or less all the drivers. Instead, I have added 'which' field to the subdev state itself, filled at state allocation time, which only requires changes to the drivers that allocate a state themselves. Signed-off-by: Tomi Valkeinen --- drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +- drivers/media/platform/vsp1/vsp1_entity.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 10 +++++++--- drivers/staging/media/tegra-video/vi.c | 2 +- include/media/v4l2-subdev.h | 7 ++++++- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 5f4fa8c48f68..1de30d5b437f 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -252,7 +252,7 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, u32 width, height; int ret; - sd_state = v4l2_alloc_subdev_state(sd); + sd_state = v4l2_alloc_subdev_state(sd, V4L2_SUBDEV_FORMAT_ACTIVE); if (IS_ERR(sd_state)) return PTR_ERR(sd_state); diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c index e40bca254b8b..63ea5e472c33 100644 --- a/drivers/media/platform/vsp1/vsp1_entity.c +++ b/drivers/media/platform/vsp1/vsp1_entity.c @@ -675,7 +675,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, * Allocate the pad configuration to store formats and selection * rectangles. */ - entity->config = v4l2_alloc_subdev_state(&entity->subdev); + entity->config = v4l2_alloc_subdev_state(&entity->subdev, V4L2_SUBDEV_FORMAT_ACTIVE); if (IS_ERR(entity->config)) { media_entity_cleanup(&entity->subdev.entity); return PTR_ERR(entity->config); diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index e1a794f69815..04ad319fb150 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -28,7 +28,7 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) { struct v4l2_subdev_state *state; - state = v4l2_alloc_subdev_state(sd); + state = v4l2_alloc_subdev_state(sd, V4L2_SUBDEV_FORMAT_TRY); if (IS_ERR(state)) return PTR_ERR(state); @@ -870,7 +870,9 @@ int v4l2_subdev_link_validate(struct media_link *link) } EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); -struct v4l2_subdev_state *v4l2_alloc_subdev_state(struct v4l2_subdev *sd) +struct v4l2_subdev_state * +v4l2_alloc_subdev_state(struct v4l2_subdev *sd, + enum v4l2_subdev_format_whence which) { struct v4l2_subdev_state *state; int ret; @@ -879,6 +881,8 @@ struct v4l2_subdev_state *v4l2_alloc_subdev_state(struct v4l2_subdev *sd) if (!state) return ERR_PTR(-ENOMEM); + state->which = which; + if (sd->entity.num_pads) { state->pads = kvmalloc_array(sd->entity.num_pads, sizeof(*state->pads), @@ -948,7 +952,7 @@ int v4l2_subdev_alloc_state(struct v4l2_subdev *sd) { struct v4l2_subdev_state *state; - state = v4l2_alloc_subdev_state(sd); + state = v4l2_alloc_subdev_state(sd, V4L2_SUBDEV_FORMAT_ACTIVE); if (IS_ERR(state)) return PTR_ERR(state); diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index a94d19e2a67c..691f5e04b0a1 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -507,7 +507,7 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan, if (!subdev) return -ENODEV; - sd_state = v4l2_alloc_subdev_state(subdev); + sd_state = v4l2_alloc_subdev_state(subdev, V4L2_SUBDEV_FORMAT_ACTIVE); if (IS_ERR(sd_state)) return PTR_ERR(sd_state); /* diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index ecaf040ead57..5ec78ffda4f5 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -655,6 +655,7 @@ struct v4l2_subdev_pad_config { /** * struct v4l2_subdev_state - Used for storing subdev state information. * + * @which: state type (from enum v4l2_subdev_format_whence) * @pads: &struct v4l2_subdev_pad_config array * * This structure only needs to be passed to the pad op if the 'which' field @@ -662,6 +663,7 @@ struct v4l2_subdev_pad_config { * %V4L2_SUBDEV_FORMAT_ACTIVE it is safe to pass %NULL. */ struct v4l2_subdev_state { + u32 which; struct v4l2_subdev_pad_config *pads; }; @@ -1141,10 +1143,13 @@ int v4l2_subdev_link_validate(struct media_link *link); * v4l2_alloc_subdev_state - allocate v4l2_subdev_state * * @sd: pointer to &struct v4l2_subdev for which the state is being allocated. + * @which: configuration type for the state (from enum v4l2_subdev_format_whence) * * Must call v4l2_free_subdev_state() when state is no longer needed. */ -struct v4l2_subdev_state *v4l2_alloc_subdev_state(struct v4l2_subdev *sd); +struct v4l2_subdev_state * +v4l2_alloc_subdev_state(struct v4l2_subdev *sd, + enum v4l2_subdev_format_whence which); /** * v4l2_free_subdev_state - free a v4l2_subdev_state From patchwork Mon Aug 30 11:00:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504825 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE938C432BE for ; Mon, 30 Aug 2021 11:02:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D2B2761102 for ; Mon, 30 Aug 2021 11:02:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236437AbhH3LDK (ORCPT ); Mon, 30 Aug 2021 07:03:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236429AbhH3LDJ (ORCPT ); Mon, 30 Aug 2021 07:03:09 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BCC43C06175F for ; Mon, 30 Aug 2021 04:02:15 -0700 (PDT) Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 49E6DBB0; Mon, 30 Aug 2021 13:02:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321334; bh=rmr8KW10QsSv+WzZoW9tYbOeAz5HxGFwGWeov7ay35Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TWnA+5+kXZM0yQi6h3cLoBzcxxeQx2PA4SSifvxFvXaYBShaE5xj69Bf8K49QHmkU RPgq7OlX3oDkA9A7oOrizexKX3x2zR1jVFbCvsSKcHVsXjsuG9jXqg+oqgAR10P8bc x98nlLwyd8TOdPDeg7K8eE2fq+erwJl5OHNJZeFk= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 04/36] media: subdev: pass also the active state to subdevs from ioctls Date: Mon, 30 Aug 2021 14:00:44 +0300 Message-Id: <20210830110116.488338-5-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org At the moment when a subdev op is called, the TRY subdev state (subdev_fh->state) is passed as a parameter even for ACTIVE case, or alternatively a NULL can be passed for ACTIVE case. This used to make sense, as the ACTIVE state was handled internally by the subdev drivers. We now have a state for ACTIVE case in a standard place, and can pass that alto to the drivers. This patch changes the subdev ioctls to either pass the TRY or ACTIVE state to the subdev. Unfortunately many drivers call ops from other subdevs, and implicitly pass NULL as the state, so this is just a partial solution. A coccinelle spatch could perhaps be created which fixes the drivers' subdev calls. For all current upstream drivers this doesn't matter, as they do not expect to get a valid state for ACTIVE case. But future drivers which support multiplexed streaming and routing will depend on getting a state for both active and try cases, and the simplest way to avoid this problem is to introduce a helper function, used by the new drivers, which makes sure the driver has either the TRY or ACTIVE state. This helper will be introduced in a follow-up patch. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 73 +++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 04ad319fb150..b3637cddca58 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -353,6 +353,53 @@ const struct v4l2_subdev_ops v4l2_subdev_call_wrappers = { EXPORT_SYMBOL(v4l2_subdev_call_wrappers); #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) + +static struct v4l2_subdev_state * +subdev_ioctl_get_state(struct v4l2_subdev *sd, struct v4l2_subdev_fh *subdev_fh, + unsigned int cmd, void *arg) +{ + u32 which; + + switch (cmd) { + default: + return NULL; + + case VIDIOC_SUBDEV_G_FMT: + case VIDIOC_SUBDEV_S_FMT: { + which = ((struct v4l2_subdev_format *)arg)->which; + break; + } + case VIDIOC_SUBDEV_G_CROP: + case VIDIOC_SUBDEV_S_CROP: { + which = ((struct v4l2_subdev_crop *)arg)->which; + break; + } + case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { + which = ((struct v4l2_subdev_mbus_code_enum *)arg)->which; + break; + } + case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: { + which = ((struct v4l2_subdev_frame_size_enum *)arg)->which; + break; + } + + case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { + which = ((struct v4l2_subdev_frame_interval_enum *)arg)->which; + break; + } + + case VIDIOC_SUBDEV_G_SELECTION: + case VIDIOC_SUBDEV_S_SELECTION: { + which = ((struct v4l2_subdev_selection *)arg)->which; + break; + } + } + + return which == V4L2_SUBDEV_FORMAT_TRY ? + subdev_fh->state : + v4l2_subdev_get_active_state(sd); +} + static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); @@ -360,8 +407,11 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_fh *vfh = file->private_data; struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); bool ro_subdev = test_bit(V4L2_FL_SUBDEV_RO_DEVNODE, &vdev->flags); + struct v4l2_subdev_state *state; int rval; + state = subdev_ioctl_get_state(sd, subdev_fh, cmd, arg); + switch (cmd) { case VIDIOC_SUBDEV_QUERYCAP: { struct v4l2_subdev_capability *cap = arg; @@ -484,7 +534,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(format->reserved, 0, sizeof(format->reserved)); memset(format->format.reserved, 0, sizeof(format->format.reserved)); - return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->state, format); + return v4l2_subdev_call(sd, pad, get_fmt, state, format); } case VIDIOC_SUBDEV_S_FMT: { @@ -495,7 +545,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(format->reserved, 0, sizeof(format->reserved)); memset(format->format.reserved, 0, sizeof(format->format.reserved)); - return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->state, format); + return v4l2_subdev_call(sd, pad, set_fmt, state, format); } case VIDIOC_SUBDEV_G_CROP: { @@ -509,7 +559,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) sel.target = V4L2_SEL_TGT_CROP; rval = v4l2_subdev_call( - sd, pad, get_selection, subdev_fh->state, &sel); + sd, pad, get_selection, state, &sel); crop->rect = sel.r; @@ -531,7 +581,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) sel.r = crop->rect; rval = v4l2_subdev_call( - sd, pad, set_selection, subdev_fh->state, &sel); + sd, pad, set_selection, state, &sel); crop->rect = sel.r; @@ -542,7 +592,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_subdev_mbus_code_enum *code = arg; memset(code->reserved, 0, sizeof(code->reserved)); - return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->state, + return v4l2_subdev_call(sd, pad, enum_mbus_code, state, code); } @@ -550,7 +600,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_subdev_frame_size_enum *fse = arg; memset(fse->reserved, 0, sizeof(fse->reserved)); - return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->state, + return v4l2_subdev_call(sd, pad, enum_frame_size, state, fse); } @@ -575,7 +625,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_subdev_frame_interval_enum *fie = arg; memset(fie->reserved, 0, sizeof(fie->reserved)); - return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->state, + return v4l2_subdev_call(sd, pad, enum_frame_interval, state, fie); } @@ -584,7 +634,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(sel->reserved, 0, sizeof(sel->reserved)); return v4l2_subdev_call( - sd, pad, get_selection, subdev_fh->state, sel); + sd, pad, get_selection, state, sel); } case VIDIOC_SUBDEV_S_SELECTION: { @@ -595,7 +645,7 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(sel->reserved, 0, sizeof(sel->reserved)); return v4l2_subdev_call( - sd, pad, set_selection, subdev_fh->state, sel); + sd, pad, set_selection, state, sel); } case VIDIOC_G_EDID: { @@ -829,10 +879,13 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad, if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(pad->entity); + struct v4l2_subdev_state *state; + + state = v4l2_subdev_get_active_state(sd); fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; fmt->pad = pad->index; - return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt); + return v4l2_subdev_call(sd, pad, get_fmt, state, fmt); } WARN(pad->entity->function != MEDIA_ENT_F_IO_V4L, From patchwork Mon Aug 30 11:00:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504500 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A625C432BE for ; Mon, 30 Aug 2021 11:02:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 74C6461102 for ; Mon, 30 Aug 2021 11:02:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236453AbhH3LDR (ORCPT ); Mon, 30 Aug 2021 07:03:17 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236431AbhH3LDK (ORCPT ); Mon, 30 Aug 2021 07:03:10 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 344051334; Mon, 30 Aug 2021 13:02:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321334; bh=cKSN2obaXwMr9sCSMsqB3zSSV8if3KHpc6HmSQrLIgU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HETh2JDbAyJopwn+F9nV/If6TnGJpE00wInFbmQSkC7HEXdxY9pslIK8IrhbsXqtb NOlz6XZC/35SiUFjkMJNL/TgDCZI9+ItXofmThyFR/lA4jPjC0jec8Letg92p+tVFl XRiXsR/2mH0qS2FKaLeVl2panH4tdGRteZcN4XnI= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 05/36] media: subdev: add subdev state locking Date: Mon, 30 Aug 2021 14:00:45 +0300 Message-Id: <20210830110116.488338-6-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The V4L2 subdevs have managed without centralized locking for the state (previously pad_config), as the TRY state is supposedly safe (although I believe two TRY ioctls for the same fd would race), and the ACTIVE state, and its locking, is managed by the drivers internally. We now have ACTIVE state in a centralized position, and need locking. Strictly speaking the locking is only needed for new drivers that use the new state, as the current drivers continue behaving as they used to. Add a mutex to the struct v4l2_subdev_state, along with a few helper functions for locking/unlocking. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 43 +++++++++++++++++---- include/media/v4l2-subdev.h | 55 +++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b3637cddca58..b1e65488210d 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -26,9 +26,11 @@ #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) { + static struct lock_class_key __key; struct v4l2_subdev_state *state; - state = v4l2_alloc_subdev_state(sd, V4L2_SUBDEV_FORMAT_TRY); + state = __v4l2_alloc_subdev_state(sd, V4L2_SUBDEV_FORMAT_TRY, + "v4l2_subdev_fh->state", &__key); if (IS_ERR(state)) return PTR_ERR(state); @@ -924,8 +926,10 @@ int v4l2_subdev_link_validate(struct media_link *link) EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); struct v4l2_subdev_state * -v4l2_alloc_subdev_state(struct v4l2_subdev *sd, - enum v4l2_subdev_format_whence which) +__v4l2_alloc_subdev_state(struct v4l2_subdev *sd, + enum v4l2_subdev_format_whence which, + const char *lock_name, + struct lock_class_key *lock_key) { struct v4l2_subdev_state *state; int ret; @@ -934,6 +938,8 @@ v4l2_alloc_subdev_state(struct v4l2_subdev *sd, if (!state) return ERR_PTR(-ENOMEM); + __mutex_init(&state->lock, lock_name, lock_key); + state->which = which; if (sd->entity.num_pads) { @@ -960,13 +966,15 @@ v4l2_alloc_subdev_state(struct v4l2_subdev *sd, return ERR_PTR(ret); } -EXPORT_SYMBOL_GPL(v4l2_alloc_subdev_state); +EXPORT_SYMBOL_GPL(__v4l2_alloc_subdev_state); void v4l2_free_subdev_state(struct v4l2_subdev_state *state) { if (!state) return; + mutex_destroy(&state->lock); + kvfree(state->pads); kfree(state); } @@ -1001,11 +1009,12 @@ void v4l2_subdev_notify_event(struct v4l2_subdev *sd, } EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event); -int v4l2_subdev_alloc_state(struct v4l2_subdev *sd) +int __v4l2_subdev_alloc_state(struct v4l2_subdev *sd, const char *name, + struct lock_class_key *key) { struct v4l2_subdev_state *state; - state = v4l2_alloc_subdev_state(sd, V4L2_SUBDEV_FORMAT_ACTIVE); + state = __v4l2_alloc_subdev_state(sd, V4L2_SUBDEV_FORMAT_ACTIVE, name, key); if (IS_ERR(state)) return PTR_ERR(state); @@ -1013,7 +1022,7 @@ int v4l2_subdev_alloc_state(struct v4l2_subdev *sd) return 0; } -EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_state); +EXPORT_SYMBOL_GPL(__v4l2_subdev_alloc_state); void v4l2_subdev_free_state(struct v4l2_subdev *sd) { @@ -1021,3 +1030,23 @@ void v4l2_subdev_free_state(struct v4l2_subdev *sd) sd->state = NULL; } EXPORT_SYMBOL_GPL(v4l2_subdev_free_state); + +struct v4l2_subdev_state *v4l2_subdev_lock_active_state(struct v4l2_subdev *sd) +{ + mutex_lock(&sd->state->lock); + + return sd->state; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_lock_active_state); + +void v4l2_subdev_lock_state(struct v4l2_subdev_state *state) +{ + mutex_lock(&state->lock); +} +EXPORT_SYMBOL_GPL(v4l2_subdev_lock_state); + +void v4l2_subdev_unlock_state(struct v4l2_subdev_state *state) +{ + mutex_unlock(&state->lock); +} +EXPORT_SYMBOL_GPL(v4l2_subdev_unlock_state); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 5ec78ffda4f5..52a725281b23 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -655,6 +655,7 @@ struct v4l2_subdev_pad_config { /** * struct v4l2_subdev_state - Used for storing subdev state information. * + * @lock: mutex for the state * @which: state type (from enum v4l2_subdev_format_whence) * @pads: &struct v4l2_subdev_pad_config array * @@ -663,6 +664,7 @@ struct v4l2_subdev_pad_config { * %V4L2_SUBDEV_FORMAT_ACTIVE it is safe to pass %NULL. */ struct v4l2_subdev_state { + struct mutex lock; u32 which; struct v4l2_subdev_pad_config *pads; }; @@ -1147,9 +1149,18 @@ int v4l2_subdev_link_validate(struct media_link *link); * * Must call v4l2_free_subdev_state() when state is no longer needed. */ +#define v4l2_alloc_subdev_state(sd, which) \ + ({ \ + static struct lock_class_key __key; \ + const char *name = KBUILD_BASENAME \ + ":" __stringify(__LINE__) ":sd->state->lock"; \ + __v4l2_alloc_subdev_state(sd, which, name, &__key); \ + }) + struct v4l2_subdev_state * -v4l2_alloc_subdev_state(struct v4l2_subdev *sd, - enum v4l2_subdev_format_whence which); +__v4l2_alloc_subdev_state(struct v4l2_subdev *sd, + enum v4l2_subdev_format_whence which, + const char *lock_name, struct lock_class_key *key); /** * v4l2_free_subdev_state - free a v4l2_subdev_state @@ -1234,7 +1245,16 @@ void v4l2_subdev_notify_event(struct v4l2_subdev *sd, * * Must call v4l2_subdev_free_state() when the state is no longer needed. */ -int v4l2_subdev_alloc_state(struct v4l2_subdev *sd); +#define v4l2_subdev_alloc_state(sd) \ + ({ \ + static struct lock_class_key __key; \ + const char *name = KBUILD_BASENAME \ + ":" __stringify(__LINE__) ":sd->state->lock"; \ + __v4l2_subdev_alloc_state(sd, name, &__key); \ + }) + +int __v4l2_subdev_alloc_state(struct v4l2_subdev *sd, const char *name, + struct lock_class_key *key); /** * v4l2_subdev_free_state() - Free the active subdev state for subdevice @@ -1258,4 +1278,33 @@ v4l2_subdev_get_active_state(struct v4l2_subdev *sd) return sd->state; } +/** + * v4l2_subdev_lock_active_state() - Lock and return the active subdev state for subdevice + * @sd: The subdevice + * + * Return the locked active state for the subdevice, or NULL if the subdev + * does not support active state. + * + * Must be unlocked with v4l2_subdev_unlock_state() after use. + */ +struct v4l2_subdev_state *v4l2_subdev_lock_active_state(struct v4l2_subdev *sd); + +/** + * v4l2_subdev_lock_state() - Lock the subdev state + * @state: The subdevice state + * + * Lock the given subdev state. + * + * Must be unlocked with v4l2_subdev_unlock_state() after use. + */ +void v4l2_subdev_lock_state(struct v4l2_subdev_state *state); + +/** + * v4l2_subdev_unlock_state() - Unlock the subdev state + * @state: The subdevice state + * + * Unlock the given subdev state. + */ +void v4l2_subdev_unlock_state(struct v4l2_subdev_state *state); + #endif From patchwork Mon Aug 30 11:00:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504499 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25200C432BE for ; Mon, 30 Aug 2021 11:02:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0E8F16112D for ; Mon, 30 Aug 2021 11:02:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236463AbhH3LDW (ORCPT ); Mon, 30 Aug 2021 07:03:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56112 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236441AbhH3LDK (ORCPT ); Mon, 30 Aug 2021 07:03:10 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36443C061575 for ; Mon, 30 Aug 2021 04:02:17 -0700 (PDT) Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1706A1279; Mon, 30 Aug 2021 13:02:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321335; bh=77/kGOwAmfB7XR0MAHbi0ZBIQYCI8yOU2NxtlsUStmk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qlHsJ0UdWK6seonQemfGP4cTFPA1rvF+teGSjph9twcrLzLx9n7tI0rQDHQDlpZmO nJ20IVHLZv89LTA2kSQqcIOd4GguQcf0DmaX+WyRnClh0hpoDrK5fIJG/OorqvLY8W wzF2tcIa4fw86A7/B8C+xnm68dTCvrl2BsxYc2r4= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 06/36] media: subdev: Add v4l2_subdev_validate(_and_lock)_state() Date: Mon, 30 Aug 2021 14:00:46 +0300 Message-Id: <20210830110116.488338-7-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org All suitable subdev ops are now passed either the TRY or the ACTIVE state by the v4l2 core. However, other subdrivers can still call the ops passing NULL as the state, implying the active case. Thus all subdev drivers supporting active state need to handle the NULL state case. Additionally, the subdev drivers usually need to lock the state. Add two helper functions to easen the transition to centrally managed ACTIVE state. v4l2_subdev_validate_state() ensures that the state is not NULL, and v4l2_subdev_validate_and_lock_state() does the same and additionally locks the state. Signed-off-by: Tomi Valkeinen --- include/media/v4l2-subdev.h | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 52a725281b23..2290b5025fc0 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1307,4 +1307,45 @@ void v4l2_subdev_lock_state(struct v4l2_subdev_state *state); */ void v4l2_subdev_unlock_state(struct v4l2_subdev_state *state); +/** + * v4l2_subdev_validate_state() - Gets the TRY or ACTIVE subdev state + * @sd: subdevice + * @state: subdevice state as passed to the subdev op + * + * Subdev ops used to be sometimes called with NULL as the state for ACTIVE + * case. Even if the v4l2 core now passes proper state for both TRY and + * ACTIVE cases, a subdev driver may call an op in another subdev driver, + * passing NULL. + * + * This function can be used as a helper to get the state also for the ACTIVE + * case. The subdev driver that supports ACTIVE state can use this function + * as the first thing in its ops, ensuring that the state variable contains + * either the TRY or ACTIVE state. + */ +static inline struct v4l2_subdev_state * +v4l2_subdev_validate_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + return state ? state : sd->state; +} + +/** + * v4l2_subdev_validate_and_lock_state() - Gets locked TRY or ACTIVE subdev state + * @sd: subdevice + * @state: subdevice state as passed to the subdev op + * + * This is a helper function which does the same as v4l2_subdev_validate_state + * () except that it also locks the state. + */ +static inline struct v4l2_subdev_state * +v4l2_subdev_validate_and_lock_state(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + state = state ? state : sd->state; + + v4l2_subdev_lock_state(state); + + return state; +} + #endif From patchwork Mon Aug 30 11:00:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504824 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4AED9C4320A for ; Mon, 30 Aug 2021 11:02:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 353326112D for ; Mon, 30 Aug 2021 11:02:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236445AbhH3LDU (ORCPT ); Mon, 30 Aug 2021 07:03:20 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236440AbhH3LDL (ORCPT ); Mon, 30 Aug 2021 07:03:11 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F0278146F; Mon, 30 Aug 2021 13:02:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321336; bh=MrJ4HkADrgP9n/o3SsEiZg1PZ2QwedPdLMqwSWtdQp4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y3Y700105/d0i+YhGtpUptRxEE8AKBIzgJjjkeEf/vJnQ3DWnvgNjrJenxCYZgdtd 8nFnbXtpEPUvuMLz2cKaKuu3O5lYoZA9ZLlmtFYNipVb3tJrInZY35HK49605FWlMA YC7rS1UlkJqlJyJDsz+8HUgc5wcLHfQkQJagP/G0= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 07/36] media: Documentation: add documentation about subdev state Date: Mon, 30 Aug 2021 14:00:47 +0300 Message-Id: <20210830110116.488338-8-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add documentation about centrally managed subdev state. Signed-off-by: Tomi Valkeinen --- .../driver-api/media/v4l2-subdev.rst | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst index 7736da077fb8..b28607c3fc79 100644 --- a/Documentation/driver-api/media/v4l2-subdev.rst +++ b/Documentation/driver-api/media/v4l2-subdev.rst @@ -518,6 +518,31 @@ The :c:func:`v4l2_i2c_new_subdev` function will call :c:type:`i2c_board_info` structure using the ``client_type`` and the ``addr`` to fill it. +Centrally managed subdev active state +------------------------------------- + +Traditionally V4L2 subdev drivers maintained internal state for the active +configuration for the subdev. This is often implemented as an array of struct +v4l2_mbus_framefmt, on entry for each pad. + +In addition to the active configuration, each subdev filehandle has contained +an array of struct v4l2_subdev_pad_config, managed by V4L2 core, which +contains the TRY configuration. + +To simplify the subdev drivers the V4L2 subdev API now optionally supports a +centrally managed active configuration. A subdev driver must use +v4l2_subdev_alloc_state() to initialize the active state between calls to +media_entity_pads_init() and v4l2_*_register_subdev(). + +The active state must be locked before access, and can be done with e.g. +v4l2_subdev_lock_state() or v4l2_subdev_lock_active_state(). + +The V4L2 core will pass either the TRY or ACTIVE state to various subdev ops. +Unfortunately all the subdev drivers do not comply with this yet, and may +pass NULL for the ACTIVE case, so the called subdev ops must also handle the +NULL case. This can be easily managed by the helpers +v4l2_subdev_validate_state() or v4l2_subdev_validate_and_lock_state(). + V4L2 sub-device functions and data structures --------------------------------------------- From patchwork Mon Aug 30 11:00:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504823 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E9251C4320E for ; Mon, 30 Aug 2021 11:02:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CC6AD6113D for ; Mon, 30 Aug 2021 11:02:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236441AbhH3LDX (ORCPT ); Mon, 30 Aug 2021 07:03:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236448AbhH3LDM (ORCPT ); Mon, 30 Aug 2021 07:03:12 -0400 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9DA1C061764 for ; Mon, 30 Aug 2021 04:02:18 -0700 (PDT) Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D8EBA5A7; Mon, 30 Aug 2021 13:02:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321337; bh=2PHsxmwR3MHZUDL03a60jsqmdnIZr74QvlxS7er1i4Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iooAkZCUUcVWxp5e/wiGu2ZVVGupTko8dcskzPfXB9KJcQI3XcxYJLxCzgpcqj6yH I5mwgR7uSMSwLK9VY0kTZD9ptV8cSm4n7VB4oHO4dRWhVtEW1VFpNpDl+PlIgf1ZR0 srDDvqjt2gjHJ75s0Gx5tw3nGp8v1e5zgtVsIs64= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 08/36] media: entity: Use pad as a starting point for graph walk Date: Mon, 30 Aug 2021 14:00:48 +0300 Message-Id: <20210830110116.488338-9-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus With the upcoming use of the recently added has_route() media entity op, all the pads in an entity will no longer be considered interconnected. This has an effect where the media graph is traversed: the starting pad does make a difference. Prepare for this change by using pad instead of the entity as an argument for the graph walk operations. The actual graph traversal algorithm change is in further patches. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- Documentation/driver-api/media/mc-core.rst | 2 +- drivers/media/mc/mc-entity.c | 17 ++++++++--------- drivers/media/platform/exynos4-is/media-dev.c | 4 ++-- drivers/media/platform/omap3isp/ispvideo.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/v4l2-core/v4l2-mc.c | 6 +++--- drivers/staging/media/omap4iss/iss_video.c | 4 ++-- include/media/media-entity.h | 10 ++++------ 9 files changed, 23 insertions(+), 26 deletions(-) diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst index 57b5bbba944e..ba0aee982124 100644 --- a/Documentation/driver-api/media/mc-core.rst +++ b/Documentation/driver-api/media/mc-core.rst @@ -167,7 +167,7 @@ Drivers initiate a graph traversal by calling :c:func:`media_graph_walk_start()` The graph structure, provided by the caller, is initialized to start graph -traversal at the given entity. +traversal at the given pad in an entity. Drivers can then retrieve the next entity by calling :c:func:`media_graph_walk_next()` diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index f40f41977142..47cdaa301838 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -291,17 +291,16 @@ void media_graph_walk_cleanup(struct media_graph *graph) } EXPORT_SYMBOL_GPL(media_graph_walk_cleanup); -void media_graph_walk_start(struct media_graph *graph, - struct media_entity *entity) +void media_graph_walk_start(struct media_graph *graph, struct media_pad *pad) { media_entity_enum_zero(&graph->ent_enum); - media_entity_enum_set(&graph->ent_enum, entity); + media_entity_enum_set(&graph->ent_enum, pad->entity); graph->top = 0; graph->stack[graph->top].entity = NULL; - stack_push(graph, entity); - dev_dbg(entity->graph_obj.mdev->dev, - "begin graph walk at '%s'\n", entity->name); + stack_push(graph, pad->entity); + dev_dbg(pad->graph_obj.mdev->dev, + "begin graph walk at '%s':%u\n", pad->entity->name, pad->index); } EXPORT_SYMBOL_GPL(media_graph_walk_start); @@ -420,7 +419,7 @@ __must_check int __media_pipeline_start(struct media_entity *entity, goto error_graph_walk_start; } - media_graph_walk_start(&pipe->graph, entity); + media_graph_walk_start(&pipe->graph, entity->pads); while ((entity = media_graph_walk_next(graph))) { DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); @@ -504,7 +503,7 @@ __must_check int __media_pipeline_start(struct media_entity *entity, * Link validation on graph failed. We revert what we did and * return the error. */ - media_graph_walk_start(graph, entity_err); + media_graph_walk_start(graph, entity_err->pads); while ((entity_err = media_graph_walk_next(graph))) { /* Sanity check for negative stream_count */ @@ -555,7 +554,7 @@ void __media_pipeline_stop(struct media_entity *entity) if (WARN_ON(!pipe)) return; - media_graph_walk_start(graph, entity); + media_graph_walk_start(graph, entity->pads); while ((entity = media_graph_walk_next(graph))) { /* Sanity check for negative stream_count */ diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index fa648721eaab..4ec7f7a6b0f6 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1173,7 +1173,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable, * through active links. This is needed as we cannot power on/off the * subdevs in random order. */ - media_graph_walk_start(graph, entity); + media_graph_walk_start(graph, entity->pads); while ((entity = media_graph_walk_next(graph))) { if (!is_media_entity_v4l2_video_device(entity)) @@ -1188,7 +1188,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable, return 0; err: - media_graph_walk_start(graph, entity_err); + media_graph_walk_start(graph, entity_err->pads); while ((entity_err = media_graph_walk_next(graph))) { if (!is_media_entity_v4l2_video_device(entity_err)) diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 8811d6dd4ee7..3c1485d59404 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -234,7 +234,7 @@ static int isp_video_get_graph_data(struct isp_video *video, return ret; } - media_graph_walk_start(&graph, entity); + media_graph_walk_start(&graph, entity->pads); while ((entity = media_graph_walk_next(&graph))) { struct isp_video *__video; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 044eb5778820..61e4fbaba7b7 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -569,7 +569,7 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe, if (ret) return ret; - media_graph_walk_start(&graph, entity); + media_graph_walk_start(&graph, entity->pads); while ((entity = media_graph_walk_next(&graph))) { struct v4l2_subdev *subdev; diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 338c3661d809..af0d55ab6c15 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -189,7 +189,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, return ret; } - media_graph_walk_start(&graph, entity); + media_graph_walk_start(&graph, entity->pads); while ((entity = media_graph_walk_next(&graph))) { struct xvip_dma *dma; diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index b01474717dca..d215fe31b9a2 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -436,7 +436,7 @@ static int pipeline_pm_use_count(struct media_entity *entity, { int use = 0; - media_graph_walk_start(graph, entity); + media_graph_walk_start(graph, entity->pads); while ((entity = media_graph_walk_next(graph))) { if (is_media_entity_v4l2_video_device(entity)) @@ -499,7 +499,7 @@ static int pipeline_pm_power(struct media_entity *entity, int change, if (!change) return 0; - media_graph_walk_start(graph, entity); + media_graph_walk_start(graph, entity->pads); while (!ret && (entity = media_graph_walk_next(graph))) if (is_media_entity_v4l2_subdev(entity)) @@ -508,7 +508,7 @@ static int pipeline_pm_power(struct media_entity *entity, int change, if (!ret) return ret; - media_graph_walk_start(graph, first); + media_graph_walk_start(graph, first->pads); while ((first = media_graph_walk_next(graph)) && first != entity) diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index d0da083deed5..760cd0ab1feb 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -217,7 +217,7 @@ iss_video_far_end(struct iss_video *video) return NULL; } - media_graph_walk_start(&graph, entity); + media_graph_walk_start(&graph, entity->pads); while ((entity = media_graph_walk_next(&graph))) { if (entity == &video->video.entity) @@ -892,7 +892,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) goto err_media_pipeline_start; mutex_lock(&mdev->graph_mutex); - media_graph_walk_start(&graph, entity); + media_graph_walk_start(&graph, entity->pads); while ((entity = media_graph_walk_next(&graph))) media_entity_enum_set(&pipe->ent_enum, entity); mutex_unlock(&mdev->graph_mutex); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 09737b47881f..b9bfcf34eb0a 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -902,22 +902,20 @@ __must_check int media_graph_walk_init( void media_graph_walk_cleanup(struct media_graph *graph); /** - * media_graph_walk_start - Start walking the media graph at a - * given entity + * media_graph_walk_start - Start walking the media graph at a given pad * * @graph: Media graph structure that will be used to walk the graph - * @entity: Starting entity + * @pad: Starting pad * * Before using this function, media_graph_walk_init() must be * used to allocate resources used for walking the graph. This * function initializes the graph traversal structure to walk the - * entities graph starting at the given entity. The traversal + * entities graph starting at the given pad. The traversal * structure must not be modified by the caller during graph * traversal. After the graph walk, the resources must be released * using media_graph_walk_cleanup(). */ -void media_graph_walk_start(struct media_graph *graph, - struct media_entity *entity); +void media_graph_walk_start(struct media_graph *graph, struct media_pad *pad); /** * media_graph_walk_next - Get the next entity in the graph From patchwork Mon Aug 30 11:00:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504498 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D451C4320A for ; Mon, 30 Aug 2021 11:02:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77B1661139 for ; Mon, 30 Aug 2021 11:02:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236457AbhH3LDX (ORCPT ); Mon, 30 Aug 2021 07:03:23 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236449AbhH3LDN (ORCPT ); Mon, 30 Aug 2021 07:03:13 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C249B8AD; Mon, 30 Aug 2021 13:02:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321338; bh=LGq2o/zj47uebcoiZENm8LikE4EuFX892IA21bSPMy8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sy90Tk37u7c58sGfH25ymKkvV5UVa9VVQIEz1Nf3I+MlFU4C8CpWi66L4rD9ql2PO EQN1GTOw8LdCAh9kY/SkXOW09LTr1fKtGWv9Q2cIU9tB4tBDmZIbsd2TVLCX5UcLOJ 9XwbUHFXfH+8FJkgl8TtPQMwiKNH35/HdWamV9TA= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 09/36] media: entity: Use pads instead of entities in the media graph walk stack Date: Mon, 30 Aug 2021 14:00:49 +0300 Message-Id: <20210830110116.488338-10-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus Change the media graph walk stack structure to use media pads instead of using media entities. In addition to the entity, the pad contains the information which pad in the entity are being dealt with. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- drivers/media/mc/mc-entity.c | 55 ++++++++++++++++++------------------ include/media/media-entity.h | 8 +++--- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 47cdaa301838..e3a932ab9abd 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -228,40 +228,39 @@ EXPORT_SYMBOL_GPL(media_entity_pads_init); * Graph traversal */ -static struct media_entity * -media_entity_other(struct media_entity *entity, struct media_link *link) +static struct media_pad * +media_pad_other(struct media_pad *pad, struct media_link *link) { - if (link->source->entity == entity) - return link->sink->entity; + if (link->source == pad) + return link->sink; else - return link->source->entity; + return link->source; } /* push an entity to traversal stack */ -static void stack_push(struct media_graph *graph, - struct media_entity *entity) +static void stack_push(struct media_graph *graph, struct media_pad *pad) { if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) { WARN_ON(1); return; } graph->top++; - graph->stack[graph->top].link = entity->links.next; - graph->stack[graph->top].entity = entity; + graph->stack[graph->top].link = pad->entity->links.next; + graph->stack[graph->top].pad = pad; } -static struct media_entity *stack_pop(struct media_graph *graph) +static struct media_pad *stack_pop(struct media_graph *graph) { - struct media_entity *entity; + struct media_pad *pad; - entity = graph->stack[graph->top].entity; + pad = graph->stack[graph->top].pad; graph->top--; - return entity; + return pad; } #define link_top(en) ((en)->stack[(en)->top].link) -#define stack_top(en) ((en)->stack[(en)->top].entity) +#define stack_top(en) ((en)->stack[(en)->top].pad) /** * media_graph_walk_init - Allocate resources for graph walk @@ -297,8 +296,8 @@ void media_graph_walk_start(struct media_graph *graph, struct media_pad *pad) media_entity_enum_set(&graph->ent_enum, pad->entity); graph->top = 0; - graph->stack[graph->top].entity = NULL; - stack_push(graph, pad->entity); + graph->stack[graph->top].pad = NULL; + stack_push(graph, pad); dev_dbg(pad->graph_obj.mdev->dev, "begin graph walk at '%s':%u\n", pad->entity->name, pad->index); } @@ -306,16 +305,16 @@ EXPORT_SYMBOL_GPL(media_graph_walk_start); static void media_graph_walk_iter(struct media_graph *graph) { - struct media_entity *entity = stack_top(graph); + struct media_pad *pad = stack_top(graph); struct media_link *link; - struct media_entity *next; + struct media_pad *next; link = list_entry(link_top(graph), typeof(*link), list); /* The link is not enabled so we do not follow. */ if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { link_top(graph) = link_top(graph)->next; - dev_dbg(entity->graph_obj.mdev->dev, + dev_dbg(pad->graph_obj.mdev->dev, "walk: skipping disabled link '%s':%u -> '%s':%u\n", link->source->entity->name, link->source->index, link->sink->entity->name, link->sink->index); @@ -323,23 +322,23 @@ static void media_graph_walk_iter(struct media_graph *graph) } /* Get the entity at the other end of the link. */ - next = media_entity_other(entity, link); + next = media_pad_other(pad, link); /* Has the entity already been visited? */ - if (media_entity_enum_test_and_set(&graph->ent_enum, next)) { + if (media_entity_enum_test_and_set(&graph->ent_enum, next->entity)) { link_top(graph) = link_top(graph)->next; - dev_dbg(entity->graph_obj.mdev->dev, + dev_dbg(pad->graph_obj.mdev->dev, "walk: skipping entity '%s' (already seen)\n", - next->name); + next->entity->name); return; } /* Push the new entity to stack and start over. */ link_top(graph) = link_top(graph)->next; stack_push(graph, next); - dev_dbg(entity->graph_obj.mdev->dev, "walk: pushing '%s' on stack\n", - next->name); - lockdep_assert_held(&entity->graph_obj.mdev->graph_mutex); + dev_dbg(next->graph_obj.mdev->dev, "walk: pushing '%s':%u on stack\n", + next->entity->name, next->index); + lockdep_assert_held(&next->graph_obj.mdev->graph_mutex); } struct media_entity *media_graph_walk_next(struct media_graph *graph) @@ -354,10 +353,10 @@ struct media_entity *media_graph_walk_next(struct media_graph *graph) * top of the stack until no more entities on the level can be * found. */ - while (link_top(graph) != &stack_top(graph)->links) + while (link_top(graph) != &stack_top(graph)->entity->links) media_graph_walk_iter(graph); - entity = stack_pop(graph); + entity = stack_pop(graph)->entity; dev_dbg(entity->graph_obj.mdev->dev, "walk: returning entity '%s'\n", entity->name); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b9bfcf34eb0a..5b55d6179e13 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -78,16 +78,16 @@ struct media_entity_enum { * struct media_graph - Media graph traversal state * * @stack: Graph traversal stack; the stack contains information - * on the path the media entities to be walked and the - * links through which they were reached. - * @stack.entity: pointer to &struct media_entity at the graph. + * on the media pads to be walked and the links through + * which they were reached. + * @stack.pad: pointer to &struct media_pad at the graph. * @stack.link: pointer to &struct list_head. * @ent_enum: Visited entities * @top: The top of the stack */ struct media_graph { struct { - struct media_entity *entity; + struct media_pad *pad; struct list_head *link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; From patchwork Mon Aug 30 11:00:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504497 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D2E4C432BE for ; Mon, 30 Aug 2021 11:02:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3444D61139 for ; Mon, 30 Aug 2021 11:02:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236464AbhH3LDY (ORCPT ); Mon, 30 Aug 2021 07:03:24 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236450AbhH3LDP (ORCPT ); Mon, 30 Aug 2021 07:03:15 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9F92F1543; Mon, 30 Aug 2021 13:02:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321339; bh=259fhmqRC52j5naHelwPcj8XLsfzyOHhUn8rPODjX2w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RtaJkeWVA2veXHwopIkJhxMN8u13g30XoVIik/HxgpjIxM6ElpF+qc1PWOjVqpPpm c6liNpTQYEkoTogdm2WBt2v4kKCj7wsLAOlP+FzPmB7wRBRZ1BHJtwK6vpfCCaF0V8 DVJvuxLR73UHERnAHYfRvL6cCFUbh2147mWBRMc0= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 10/36] media: entity: Walk the graph based on pads Date: Mon, 30 Aug 2021 14:00:50 +0300 Message-Id: <20210830110116.488338-11-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus Instead of iterating over graph entities during the walk, iterate the pads through which the entity was first reached. This is required in order to make the entity pipeline pad-based rather than entity based. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Signed-off-by: Tomi Valkeinen --- Documentation/driver-api/media/mc-core.rst | 7 ++- drivers/media/mc/mc-entity.c | 51 +++++++++++-------- drivers/media/platform/exynos4-is/media-dev.c | 20 ++++---- drivers/media/platform/omap3isp/ispvideo.c | 17 ++++--- drivers/media/platform/vsp1/vsp1_video.c | 12 ++--- drivers/media/platform/xilinx/xilinx-dma.c | 12 ++--- drivers/media/v4l2-core/v4l2-mc.c | 24 ++++----- drivers/staging/media/omap4iss/iss_video.c | 36 ++++++------- include/media/media-entity.h | 7 +-- 9 files changed, 101 insertions(+), 85 deletions(-) diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst index ba0aee982124..8a13640bed56 100644 --- a/Documentation/driver-api/media/mc-core.rst +++ b/Documentation/driver-api/media/mc-core.rst @@ -169,8 +169,11 @@ Drivers initiate a graph traversal by calling The graph structure, provided by the caller, is initialized to start graph traversal at the given pad in an entity. -Drivers can then retrieve the next entity by calling -:c:func:`media_graph_walk_next()` +Drivers can then retrieve the next pad by calling +:c:func:`media_graph_walk_next()`. Only the pad through which the entity +is first reached is returned. If the caller is interested in knowing which +further pads would be connected, the :c:func:`media_entity_has_route()` +function can be used for that. When the graph traversal is complete the function will return ``NULL``. diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index e3a932ab9abd..06147f38ce2e 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -341,9 +341,9 @@ static void media_graph_walk_iter(struct media_graph *graph) lockdep_assert_held(&next->graph_obj.mdev->graph_mutex); } -struct media_entity *media_graph_walk_next(struct media_graph *graph) +struct media_pad *media_graph_walk_next(struct media_graph *graph) { - struct media_entity *entity; + struct media_pad *pad; if (stack_top(graph) == NULL) return NULL; @@ -356,11 +356,11 @@ struct media_entity *media_graph_walk_next(struct media_graph *graph) while (link_top(graph) != &stack_top(graph)->entity->links) media_graph_walk_iter(graph); - entity = stack_pop(graph)->entity; - dev_dbg(entity->graph_obj.mdev->dev, - "walk: returning entity '%s'\n", entity->name); + pad = stack_pop(graph); + dev_dbg(pad->graph_obj.mdev->dev, + "walk: returning pad '%s':%u\n", pad->entity->name, pad->index); - return entity; + return pad; } EXPORT_SYMBOL_GPL(media_graph_walk_next); @@ -408,7 +408,8 @@ __must_check int __media_pipeline_start(struct media_entity *entity, { struct media_device *mdev = entity->graph_obj.mdev; struct media_graph *graph = &pipe->graph; - struct media_entity *entity_err = entity; + struct media_pad *pad = entity->pads; + struct media_pad *pad_err = pad; struct media_link *link; int ret; @@ -418,9 +419,11 @@ __must_check int __media_pipeline_start(struct media_entity *entity, goto error_graph_walk_start; } - media_graph_walk_start(&pipe->graph, entity->pads); + media_graph_walk_start(&pipe->graph, pad); + + while ((pad = media_graph_walk_next(graph))) { + struct media_entity *entity = pad->entity; - while ((entity = media_graph_walk_next(graph))) { DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); @@ -429,7 +432,7 @@ __must_check int __media_pipeline_start(struct media_entity *entity, if (entity->pipe && entity->pipe != pipe) { pr_err("Pipe active for %s. Can't start for %s\n", entity->name, - entity_err->name); + pad_err->entity->name); ret = -EBUSY; goto error; } @@ -447,26 +450,27 @@ __must_check int __media_pipeline_start(struct media_entity *entity, bitmap_fill(has_no_links, entity->num_pads); list_for_each_entry(link, &entity->links, list) { - struct media_pad *pad = link->sink->entity == entity - ? link->sink : link->source; + struct media_pad *other_pad = + link->sink->entity == entity ? + link->sink : link->source; /* Mark that a pad is connected by a link. */ - bitmap_clear(has_no_links, pad->index, 1); + bitmap_clear(has_no_links, other_pad->index, 1); /* * Pads that either do not need to connect or * are connected through an enabled link are * fine. */ - if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) || + if (!(other_pad->flags & MEDIA_PAD_FL_MUST_CONNECT) || link->flags & MEDIA_LNK_FL_ENABLED) - bitmap_set(active, pad->index, 1); + bitmap_set(active, other_pad->index, 1); /* * Link validation will only take place for * sink ends of the link that are enabled. */ - if (link->sink != pad || + if (link->sink != other_pad || !(link->flags & MEDIA_LNK_FL_ENABLED)) continue; @@ -502,9 +506,11 @@ __must_check int __media_pipeline_start(struct media_entity *entity, * Link validation on graph failed. We revert what we did and * return the error. */ - media_graph_walk_start(graph, entity_err->pads); + media_graph_walk_start(graph, pad_err); + + while ((pad_err = media_graph_walk_next(graph))) { + struct media_entity *entity_err = pad_err->entity; - while ((entity_err = media_graph_walk_next(graph))) { /* Sanity check for negative stream_count */ if (!WARN_ON_ONCE(entity_err->stream_count <= 0)) { entity_err->stream_count--; @@ -516,7 +522,7 @@ __must_check int __media_pipeline_start(struct media_entity *entity, * We haven't increased stream_count further than this * so we quit here. */ - if (entity_err == entity) + if (pad_err == pad) break; } @@ -543,8 +549,9 @@ EXPORT_SYMBOL_GPL(media_pipeline_start); void __media_pipeline_stop(struct media_entity *entity) { - struct media_graph *graph = &entity->pipe->graph; struct media_pipeline *pipe = entity->pipe; + struct media_graph *graph = &pipe->graph; + struct media_pad *pad; /* * If the following check fails, the driver has performed an @@ -555,7 +562,9 @@ void __media_pipeline_stop(struct media_entity *entity) media_graph_walk_start(graph, entity->pads); - while ((entity = media_graph_walk_next(graph))) { + while ((pad = media_graph_walk_next(graph))) { + struct media_entity *entity = pad->entity; + /* Sanity check for negative stream_count */ if (!WARN_ON_ONCE(entity->stream_count <= 0)) { entity->stream_count--; diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 4ec7f7a6b0f6..10429466a394 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1164,7 +1164,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable, struct media_graph *graph) { - struct media_entity *entity_err = entity; + struct media_pad *pad, *pad_err = entity->pads; int ret; /* @@ -1173,13 +1173,13 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable, * through active links. This is needed as we cannot power on/off the * subdevs in random order. */ - media_graph_walk_start(graph, entity->pads); + media_graph_walk_start(graph, pad_err); - while ((entity = media_graph_walk_next(graph))) { - if (!is_media_entity_v4l2_video_device(entity)) + while ((pad = media_graph_walk_next(graph))) { + if (!is_media_entity_v4l2_video_device(pad->entity)) continue; - ret = __fimc_md_modify_pipeline(entity, enable); + ret = __fimc_md_modify_pipeline(pad->entity, enable); if (ret < 0) goto err; @@ -1188,15 +1188,15 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable, return 0; err: - media_graph_walk_start(graph, entity_err->pads); + media_graph_walk_start(graph, pad_err); - while ((entity_err = media_graph_walk_next(graph))) { - if (!is_media_entity_v4l2_video_device(entity_err)) + while ((pad_err = media_graph_walk_next(graph))) { + if (!is_media_entity_v4l2_video_device(pad_err->entity)) continue; - __fimc_md_modify_pipeline(entity_err, !enable); + __fimc_md_modify_pipeline(pad_err->entity, !enable); - if (entity_err == entity) + if (pad_err == pad) break; } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 3c1485d59404..5c1cbb1a9003 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -222,8 +222,8 @@ static int isp_video_get_graph_data(struct isp_video *video, struct isp_pipeline *pipe) { struct media_graph graph; - struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->graph_obj.mdev; + struct media_pad *pad = video->video.entity.pads; + struct media_device *mdev = video->video.entity.graph_obj.mdev; struct isp_video *far_end = NULL; int ret; @@ -234,23 +234,24 @@ static int isp_video_get_graph_data(struct isp_video *video, return ret; } - media_graph_walk_start(&graph, entity->pads); + media_graph_walk_start(&graph, pad); - while ((entity = media_graph_walk_next(&graph))) { + while ((pad = media_graph_walk_next(&graph))) { struct isp_video *__video; - media_entity_enum_set(&pipe->ent_enum, entity); + media_entity_enum_set(&pipe->ent_enum, pad->entity); if (far_end != NULL) continue; - if (entity == &video->video.entity) + if (pad == video->video.entity.pads) continue; - if (!is_media_entity_v4l2_video_device(entity)) + if (!is_media_entity_v4l2_video_device(pad->entity)) continue; - __video = to_isp_video(media_entity_to_video_device(entity)); + __video = to_isp_video(media_entity_to_video_device( + pad->entity)); if (__video->type != video->type) far_end = __video; } diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 61e4fbaba7b7..f2c36f2fdf53 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -559,8 +559,8 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe, struct vsp1_video *video) { struct media_graph graph; - struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->graph_obj.mdev; + struct media_pad *pad = video->video.entity.pads; + struct media_device *mdev = video->video.entity.graph_obj.mdev; unsigned int i; int ret; @@ -569,17 +569,17 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe, if (ret) return ret; - media_graph_walk_start(&graph, entity->pads); + media_graph_walk_start(&graph, pad); - while ((entity = media_graph_walk_next(&graph))) { + while ((pad = media_graph_walk_next(&graph))) { struct v4l2_subdev *subdev; struct vsp1_rwpf *rwpf; struct vsp1_entity *e; - if (!is_media_entity_v4l2_subdev(entity)) + if (!is_media_entity_v4l2_subdev(pad->entity)) continue; - subdev = media_entity_to_v4l2_subdev(entity); + subdev = media_entity_to_v4l2_subdev(pad->entity); e = to_vsp1_entity(subdev); list_add_tail(&e->list_pipe, &pipe->entities); e->pipe = pipe; diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index af0d55ab6c15..d33f99c6ffa4 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -174,8 +174,8 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, struct xvip_dma *start) { struct media_graph graph; - struct media_entity *entity = &start->video.entity; - struct media_device *mdev = entity->graph_obj.mdev; + struct media_pad *pad = start->video.entity.pads; + struct media_device *mdev = pad->entity->graph_obj.mdev; unsigned int num_inputs = 0; unsigned int num_outputs = 0; int ret; @@ -189,15 +189,15 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, return ret; } - media_graph_walk_start(&graph, entity->pads); + media_graph_walk_start(&graph, pad); - while ((entity = media_graph_walk_next(&graph))) { + while ((pad = media_graph_walk_next(&graph))) { struct xvip_dma *dma; - if (entity->function != MEDIA_ENT_F_IO_V4L) + if (pad->entity->function != MEDIA_ENT_F_IO_V4L) continue; - dma = to_xvip_dma(media_entity_to_video_device(entity)); + dma = to_xvip_dma(media_entity_to_video_device(pad->entity)); if (dma->pad.flags & MEDIA_PAD_FL_SINK) { pipe->output = dma; diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index d215fe31b9a2..cbeb580c6754 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -434,13 +434,14 @@ EXPORT_SYMBOL_GPL(v4l2_create_fwnode_links); static int pipeline_pm_use_count(struct media_entity *entity, struct media_graph *graph) { + struct media_pad *pad; int use = 0; media_graph_walk_start(graph, entity->pads); - while ((entity = media_graph_walk_next(graph))) { - if (is_media_entity_v4l2_video_device(entity)) - use += entity->use_count; + while ((pad = media_graph_walk_next(graph))) { + if (is_media_entity_v4l2_video_device(pad->entity)) + use += pad->entity->use_count; } return use; @@ -493,7 +494,7 @@ static int pipeline_pm_power_one(struct media_entity *entity, int change) static int pipeline_pm_power(struct media_entity *entity, int change, struct media_graph *graph) { - struct media_entity *first = entity; + struct media_pad *tmp_pad, *pad; int ret = 0; if (!change) @@ -501,19 +502,18 @@ static int pipeline_pm_power(struct media_entity *entity, int change, media_graph_walk_start(graph, entity->pads); - while (!ret && (entity = media_graph_walk_next(graph))) - if (is_media_entity_v4l2_subdev(entity)) - ret = pipeline_pm_power_one(entity, change); + while (!ret && (pad = media_graph_walk_next(graph))) + if (is_media_entity_v4l2_subdev(pad->entity)) + ret = pipeline_pm_power_one(pad->entity, change); if (!ret) return ret; - media_graph_walk_start(graph, first->pads); + media_graph_walk_start(graph, entity->pads); - while ((first = media_graph_walk_next(graph)) - && first != entity) - if (is_media_entity_v4l2_subdev(first)) - pipeline_pm_power_one(first, -change); + while ((tmp_pad = media_graph_walk_next(graph)) && tmp_pad != pad) + if (is_media_entity_v4l2_subdev(tmp_pad->entity)) + pipeline_pm_power_one(tmp_pad->entity, -change); return ret; } diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 760cd0ab1feb..8c25ad73a81e 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -206,8 +206,8 @@ static struct iss_video * iss_video_far_end(struct iss_video *video) { struct media_graph graph; - struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->graph_obj.mdev; + struct media_pad *pad = video->video.entity.pads; + struct media_device *mdev = video->video.entity.graph_obj.mdev; struct iss_video *far_end = NULL; mutex_lock(&mdev->graph_mutex); @@ -217,16 +217,17 @@ iss_video_far_end(struct iss_video *video) return NULL; } - media_graph_walk_start(&graph, entity->pads); + media_graph_walk_start(&graph, pad); - while ((entity = media_graph_walk_next(&graph))) { - if (entity == &video->video.entity) + while ((pad = media_graph_walk_next(&graph))) { + if (pad->entity == &video->video.entity) continue; - if (!is_media_entity_v4l2_video_device(entity)) + if (!is_media_entity_v4l2_video_device(pad->entity)) continue; - far_end = to_iss_video(media_entity_to_video_device(entity)); + far_end = to_iss_video(media_entity_to_video_device( + pad->entity)); if (far_end->type != video->type) break; @@ -853,8 +854,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) struct iss_video_fh *vfh = to_iss_video_fh(fh); struct iss_video *video = video_drvdata(file); struct media_graph graph; - struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->graph_obj.mdev; + struct media_pad *pad = video->video.entity.pads; + struct media_device *mdev = video->video.entity.graph_obj.mdev; enum iss_pipeline_state state; struct iss_pipeline *pipe; struct iss_video *far_end; @@ -870,31 +871,32 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) * Start streaming on the pipeline. No link touching an entity in the * pipeline can be activated or deactivated once streaming is started. */ - pipe = entity->pipe - ? to_iss_pipeline(entity) : &video->pipe; + pipe = pad->entity->pipe + ? to_iss_pipeline(pad->entity) : &video->pipe; pipe->external = NULL; pipe->external_rate = 0; pipe->external_bpp = 0; - ret = media_entity_enum_init(&pipe->ent_enum, entity->graph_obj.mdev); + ret = media_entity_enum_init(&pipe->ent_enum, + pad->entity->graph_obj.mdev); if (ret) goto err_graph_walk_init; - ret = media_graph_walk_init(&graph, entity->graph_obj.mdev); + ret = media_graph_walk_init(&graph, pad->entity->graph_obj.mdev); if (ret) goto err_graph_walk_init; if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, true); - ret = media_pipeline_start(entity, &pipe->pipe); + ret = media_pipeline_start(pad->entity, &pipe->pipe); if (ret < 0) goto err_media_pipeline_start; mutex_lock(&mdev->graph_mutex); - media_graph_walk_start(&graph, entity->pads); - while ((entity = media_graph_walk_next(&graph))) - media_entity_enum_set(&pipe->ent_enum, entity); + media_graph_walk_start(&graph, pad); + while ((pad = media_graph_walk_next(&graph))) + media_entity_enum_set(&pipe->ent_enum, pad->entity); mutex_unlock(&mdev->graph_mutex); /* diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 5b55d6179e13..926fd201eae3 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -926,10 +926,11 @@ void media_graph_walk_start(struct media_graph *graph, struct media_pad *pad); * The graph structure must have been previously initialized with a call to * media_graph_walk_start(). * - * Return: returns the next entity in the graph or %NULL if the whole graph - * have been traversed. + * Return: returns the next entity in the graph, identified by the pad through + * which it has been reached. If the whole graph has been traversed, return + * %NULL. */ -struct media_entity *media_graph_walk_next(struct media_graph *graph); +struct media_pad *media_graph_walk_next(struct media_graph *graph); /** * media_pipeline_start - Mark a pipeline as streaming From patchwork Mon Aug 30 11:00:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504822 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D99EBC43214 for ; Mon, 30 Aug 2021 11:02:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C2C2961107 for ; Mon, 30 Aug 2021 11:02:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236466AbhH3LDZ (ORCPT ); Mon, 30 Aug 2021 07:03:25 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236459AbhH3LDW (ORCPT ); Mon, 30 Aug 2021 07:03:22 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8DB92B7E; Mon, 30 Aug 2021 13:02:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321340; bh=7fR4JzssU6ZybYXSvkIfq8QlK5WtaQGH821wAcaAfzo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q4gpbMReBGX4655NEPFC0E5DTw70IKIcjHuCKJkB1gnfb6NmkVbTU0BkaU5kO9Lyf vipdun1pnag7rdrfiSrceAf+uJgUmIG6zFbJI/rBupziGiG7YGEuPhSXektiW/OMHD Oohb5RZP3d3PKX5VsqaDVEHNN5vSsv8M1cs0f3dI= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 11/36] media: mc: Start walk from a specific pad in use count calculation Date: Mon, 30 Aug 2021 14:00:51 +0300 Message-Id: <20210830110116.488338-12-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus With the addition of the recent has_route() media entity op, the pads of a media entity are no longer all interconnected. This has to be taken into account in power management. Prepare for the addition of a helper function supporting S_ROUTING. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-mc.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c index cbeb580c6754..35d18ed89fa5 100644 --- a/drivers/media/v4l2-core/v4l2-mc.c +++ b/drivers/media/v4l2-core/v4l2-mc.c @@ -427,17 +427,16 @@ EXPORT_SYMBOL_GPL(v4l2_create_fwnode_links); /* * pipeline_pm_use_count - Count the number of users of a pipeline - * @entity: The entity + * @pad: Any pad along the pipeline * * Return the total number of users of all video device nodes in the pipeline. */ -static int pipeline_pm_use_count(struct media_entity *entity, - struct media_graph *graph) +static int pipeline_pm_use_count(struct media_pad *pad, + struct media_graph *graph) { - struct media_pad *pad; int use = 0; - media_graph_walk_start(graph, entity->pads); + media_graph_walk_start(graph, pad); while ((pad = media_graph_walk_next(graph))) { if (is_media_entity_v4l2_video_device(pad->entity)) @@ -483,7 +482,7 @@ static int pipeline_pm_power_one(struct media_entity *entity, int change) /* * pipeline_pm_power - Apply power change to all entities in a pipeline - * @entity: The entity + * @pad: Any pad along the pipeline * @change: Use count change * * Walk the pipeline to update the use count and the power state of all non-node @@ -491,16 +490,16 @@ static int pipeline_pm_power_one(struct media_entity *entity, int change) * * Return 0 on success or a negative error code on failure. */ -static int pipeline_pm_power(struct media_entity *entity, int change, - struct media_graph *graph) +static int pipeline_pm_power(struct media_pad *pad, int change, + struct media_graph *graph) { - struct media_pad *tmp_pad, *pad; + struct media_pad *tmp_pad, *first = pad; int ret = 0; if (!change) return 0; - media_graph_walk_start(graph, entity->pads); + media_graph_walk_start(graph, pad); while (!ret && (pad = media_graph_walk_next(graph))) if (is_media_entity_v4l2_subdev(pad->entity)) @@ -509,7 +508,7 @@ static int pipeline_pm_power(struct media_entity *entity, int change, if (!ret) return ret; - media_graph_walk_start(graph, entity->pads); + media_graph_walk_start(graph, first); while ((tmp_pad = media_graph_walk_next(graph)) && tmp_pad != pad) if (is_media_entity_v4l2_subdev(tmp_pad->entity)) @@ -531,7 +530,7 @@ static int v4l2_pipeline_pm_use(struct media_entity *entity, unsigned int use) WARN_ON(entity->use_count < 0); /* Apply power change to connected non-nodes. */ - ret = pipeline_pm_power(entity, change, &mdev->pm_count_walk); + ret = pipeline_pm_power(entity->pads, change, &mdev->pm_count_walk); if (ret < 0) entity->use_count -= change; @@ -557,8 +556,8 @@ int v4l2_pipeline_link_notify(struct media_link *link, u32 flags, unsigned int notification) { struct media_graph *graph = &link->graph_obj.mdev->pm_count_walk; - struct media_entity *source = link->source->entity; - struct media_entity *sink = link->sink->entity; + struct media_pad *source = link->source; + struct media_pad *sink = link->sink; int source_use; int sink_use; int ret = 0; From patchwork Mon Aug 30 11:00:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504821 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4DDDC43216 for ; Mon, 30 Aug 2021 11:02:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8F25B61107 for ; Mon, 30 Aug 2021 11:02:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236470AbhH3LDZ (ORCPT ); Mon, 30 Aug 2021 07:03:25 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236462AbhH3LDW (ORCPT ); Mon, 30 Aug 2021 07:03:22 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6E05AB9C; Mon, 30 Aug 2021 13:02:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321341; bh=61dap9zqutL5mt0qTjlPX+iadUGRqz29iP2NJxjjFAU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K5K3VZiiJs2jFcUEPE+pYekc4a0WigaY5a0WElCdmHZ3BvUKGd3jj6kJd2tYuwbH1 HS77KSgR0q5L4iHFt86sZedISLuFbB4ibAXo2QAWap5TKVBpG4KIIvplCHTnJzW13Q F2C2EUgaLzUou3DgzGrBSOfGXa0oXFbqKyIjMrvw= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 12/36] media: entity: Add iterator helper for entity pads Date: Mon, 30 Aug 2021 14:00:52 +0300 Message-Id: <20210830110116.488338-13-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Jacopo Mondi Add an iterator helper to easily cycle through all pads in an entity and use it in media-entity and media-device code where appropriate. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Signed-off-by: Tomi Valkeinen --- drivers/media/mc/mc-device.c | 13 ++++++------- drivers/media/mc/mc-entity.c | 11 ++++++----- include/media/media-entity.h | 12 ++++++++++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index cf5e459b1d96..cb569beab99e 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -581,7 +581,7 @@ static void __media_device_unregister_entity(struct media_entity *entity) struct media_device *mdev = entity->graph_obj.mdev; struct media_link *link, *tmp; struct media_interface *intf; - unsigned int i; + struct media_pad *iter; ida_free(&mdev->entity_internal_idx, entity->internal_idx); @@ -597,8 +597,8 @@ static void __media_device_unregister_entity(struct media_entity *entity) __media_entity_remove_links(entity); /* Remove all pads that belong to this entity */ - for (i = 0; i < entity->num_pads; i++) - media_gobj_destroy(&entity->pads[i].graph_obj); + media_entity_for_each_pad(entity, iter) + media_gobj_destroy(&iter->graph_obj); /* Remove the entity */ media_gobj_destroy(&entity->graph_obj); @@ -617,7 +617,7 @@ int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { struct media_entity_notify *notify, *next; - unsigned int i; + struct media_pad *iter; int ret; if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || @@ -646,9 +646,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); /* Initialize objects at the pads */ - for (i = 0; i < entity->num_pads; i++) - media_gobj_create(mdev, MEDIA_GRAPH_PAD, - &entity->pads[i].graph_obj); + media_entity_for_each_pad(entity, iter) + media_gobj_create(mdev, MEDIA_GRAPH_PAD, &iter->graph_obj); /* invoke entity_notify callbacks */ list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 06147f38ce2e..2b438c481812 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -198,7 +198,8 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads) { struct media_device *mdev = entity->graph_obj.mdev; - unsigned int i; + struct media_pad *iter; + unsigned int i = 0; if (num_pads >= MEDIA_ENTITY_MAX_PADS) return -E2BIG; @@ -209,12 +210,12 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, if (mdev) mutex_lock(&mdev->graph_mutex); - for (i = 0; i < num_pads; i++) { - pads[i].entity = entity; - pads[i].index = i; + media_entity_for_each_pad(entity, iter) { + iter->entity = entity; + iter->index = i++; if (mdev) media_gobj_create(mdev, MEDIA_GRAPH_PAD, - &entity->pads[i].graph_obj); + &iter->graph_obj); } if (mdev) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 926fd201eae3..5f6eed24e63f 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -1107,3 +1107,15 @@ void media_remove_intf_links(struct media_interface *intf); (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) #endif + +/** + * media_entity_for_each_pad - Iterate on all pads in an entity + * @entity: The entity the pads belong to + * @iter: The iterator pad + * + * Iterate on all pads in a media entity. + */ +#define media_entity_for_each_pad(entity, iter) \ + for (iter = (entity)->pads; \ + iter < &(entity)->pads[(entity)->num_pads]; \ + ++iter) From patchwork Mon Aug 30 11:00:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504496 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48C82C4320A for ; Mon, 30 Aug 2021 11:02:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 327A26113C for ; Mon, 30 Aug 2021 11:02:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236471AbhH3LD0 (ORCPT ); Mon, 30 Aug 2021 07:03:26 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236438AbhH3LDX (ORCPT ); Mon, 30 Aug 2021 07:03:23 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4C2DBBB0; Mon, 30 Aug 2021 13:02:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321342; bh=21acosLBBzJ12iVmNqt3LLlMgHX9qPkmyp3yuIQ7dNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T3cMVgrR280wcGJj6vO1VQ2//DiELtihMdHnFDBsDe1JGlnTk6NhRABOU7wwMqLAQ A9dfoPcCGB6VfH/Mzk4l9oysHnWZ9FEXluIBtPFY69ninO2sTWqa5q6/ZycpnZIQON 6bpvQ7AlDIRbLjHNT6zCxtil9S5GlJCl7YYyXNo0= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 13/36] media: entity: Move the pipeline from entity to pads Date: Mon, 30 Aug 2021 14:00:53 +0300 Message-Id: <20210830110116.488338-14-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus This moves the pipe and stream_count fields from struct media_entity to struct media_pad. Effectively streams become pad-specific rather than being entity specific, allowing several independent streams to traverse a single entity and an entity to be part of several streams. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund - Update documentation to use 'pads' - Use the media pad iterator in media_entity.c - Update rcar-dma.c to use the new per-pad stream count Signed-off-by: Jacopo Mondi - Fix cleanup in the error path of __media_pipeline_start() Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-entity.c | 68 +++++++++++-------- drivers/media/platform/exynos4-is/fimc-isp.c | 2 +- drivers/media/platform/exynos4-is/fimc-lite.c | 2 +- drivers/media/platform/omap3isp/isp.c | 2 +- drivers/media/platform/omap3isp/ispvideo.c | 2 +- drivers/media/platform/omap3isp/ispvideo.h | 2 +- drivers/media/platform/rcar-vin/rcar-core.c | 16 +++-- drivers/media/platform/rcar-vin/rcar-dma.c | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/platform/xilinx/xilinx-dma.h | 2 +- drivers/staging/media/imx/imx-media-utils.c | 2 +- drivers/staging/media/omap4iss/iss.c | 2 +- drivers/staging/media/omap4iss/iss_video.c | 2 +- drivers/staging/media/omap4iss/iss_video.h | 2 +- include/media/media-entity.h | 21 +++--- 15 files changed, 74 insertions(+), 55 deletions(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 2b438c481812..8ad4cb845f4a 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -424,24 +424,30 @@ __must_check int __media_pipeline_start(struct media_entity *entity, while ((pad = media_graph_walk_next(graph))) { struct media_entity *entity = pad->entity; + bool skip_validation = pad->pipe != NULL; + struct media_pad *iter; DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); - entity->stream_count++; + ret = 0; - if (entity->pipe && entity->pipe != pipe) { - pr_err("Pipe active for %s. Can't start for %s\n", - entity->name, - pad_err->entity->name); - ret = -EBUSY; - goto error; + media_entity_for_each_pad(entity, iter) { + if (iter->pipe && iter->pipe != pipe) { + pr_err("Pipe active for %s. Can't start for %s\n", + entity->name, iter->entity->name); + ret = -EBUSY; + } else { + iter->pipe = pipe; + } + iter->stream_count++; } - entity->pipe = pipe; + if (ret) + goto error; - /* Already streaming --- no need to check. */ - if (entity->stream_count > 1) + /* Already part of the pipeline, skip validation. */ + if (skip_validation) continue; if (!entity->ops || !entity->ops->link_validate) @@ -510,20 +516,23 @@ __must_check int __media_pipeline_start(struct media_entity *entity, media_graph_walk_start(graph, pad_err); while ((pad_err = media_graph_walk_next(graph))) { - struct media_entity *entity_err = pad_err->entity; - - /* Sanity check for negative stream_count */ - if (!WARN_ON_ONCE(entity_err->stream_count <= 0)) { - entity_err->stream_count--; - if (entity_err->stream_count == 0) - entity_err->pipe = NULL; + struct media_entity *entity = pad_err->entity; + struct media_pad *iter; + + media_entity_for_each_pad(entity, iter) { + /* Sanity check for negative stream_count */ + if (!WARN_ON_ONCE(iter->stream_count <= 0)) { + --iter->stream_count; + if (iter->stream_count == 0) + iter->pipe = NULL; + } } /* * We haven't increased stream_count further than this * so we quit here. */ - if (pad_err == pad) + if (pad_err->entity == pad->entity) break; } @@ -550,7 +559,7 @@ EXPORT_SYMBOL_GPL(media_pipeline_start); void __media_pipeline_stop(struct media_entity *entity) { - struct media_pipeline *pipe = entity->pipe; + struct media_pipeline *pipe = entity->pads->pipe; struct media_graph *graph = &pipe->graph; struct media_pad *pad; @@ -565,12 +574,15 @@ void __media_pipeline_stop(struct media_entity *entity) while ((pad = media_graph_walk_next(graph))) { struct media_entity *entity = pad->entity; - - /* Sanity check for negative stream_count */ - if (!WARN_ON_ONCE(entity->stream_count <= 0)) { - entity->stream_count--; - if (entity->stream_count == 0) - entity->pipe = NULL; + struct media_pad *iter; + + media_entity_for_each_pad(entity, iter) { + /* Sanity check for negative stream_count */ + if (!WARN_ON_ONCE(iter->stream_count <= 0)) { + iter->stream_count--; + if (iter->stream_count == 0) + iter->pipe = NULL; + } } } @@ -840,7 +852,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) { const u32 mask = MEDIA_LNK_FL_ENABLED; struct media_device *mdev; - struct media_entity *source, *sink; + struct media_pad *source, *sink; int ret = -EBUSY; if (link == NULL) @@ -856,8 +868,8 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) if (link->flags == flags) return 0; - source = link->source->entity; - sink = link->sink->entity; + source = link->source; + sink = link->sink; if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) && (source->stream_count || sink->stream_count)) diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index 855235bea46d..80274e29ccc5 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -226,7 +226,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, } } } else { - if (sd->entity.stream_count == 0) { + if (sd->entity.pads->stream_count == 0) { if (fmt->pad == FIMC_ISP_SD_PAD_SINK) { struct v4l2_subdev_format format = *fmt; diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index aaa3af0493ce..67bfb1ad2ba2 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -1073,7 +1073,7 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, mutex_lock(&fimc->lock); if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP && - sd->entity.stream_count > 0) || + sd->entity.pads->stream_count > 0) || (atomic_read(&fimc->out_path) == FIMC_IO_DMA && vb2_is_busy(&fimc->vb_queue))) { mutex_unlock(&fimc->lock); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 20f59c59ff8a..28aab16d7662 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -936,7 +936,7 @@ static int isp_pipeline_is_last(struct media_entity *me) struct isp_pipeline *pipe; struct media_pad *pad; - if (!me->pipe) + if (!me->pads->pipe) return 0; pipe = to_isp_pipeline(me); if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED) diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 5c1cbb1a9003..a8438040c4aa 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -1094,7 +1094,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) /* Start streaming on the pipeline. No link touching an entity in the * pipeline can be activated or deactivated once streaming is started. */ - pipe = video->video.entity.pipe + pipe = video->video.entity.pads->pipe ? to_isp_pipeline(&video->video.entity) : &video->pipe; ret = media_entity_enum_init(&pipe->ent_enum, &video->isp->media_dev); diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h index a0908670c0cf..4c9c5b719ec5 100644 --- a/drivers/media/platform/omap3isp/ispvideo.h +++ b/drivers/media/platform/omap3isp/ispvideo.h @@ -100,7 +100,7 @@ struct isp_pipeline { }; #define to_isp_pipeline(__e) \ - container_of((__e)->pipe, struct isp_pipeline, pipe) + container_of((__e)->pads->pipe, struct isp_pipeline, pipe) static inline int isp_pipeline_ready(struct isp_pipeline *pipe) { diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 33957cc9118c..e59453d6b7c3 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -132,13 +132,17 @@ static int rvin_group_link_notify(struct media_link *link, u32 flags, return 0; /* - * Don't allow link changes if any entity in the graph is - * streaming, modifying the CHSEL register fields can disrupt - * running streams. + * Don't allow link changes if any stream in the graph is active as + * modifying the CHSEL register fields can disrupt running streams. */ - media_device_for_each_entity(entity, &group->mdev) - if (entity->stream_count) - return -EBUSY; + media_device_for_each_entity(entity, &group->mdev) { + struct media_pad *iter; + + media_entity_for_each_pad(entity, iter) { + if (iter->stream_count) + return -EBUSY; + } + } mutex_lock(&group->lock); diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index f5f722ab1d4e..80b7ae47d165 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1231,7 +1231,7 @@ static int rvin_set_stream(struct rvin_dev *vin, int on) */ mdev = vin->vdev.entity.graph_obj.mdev; mutex_lock(&mdev->graph_mutex); - pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe; + pipe = sd->entity.pads->pipe ? sd->entity.pads->pipe : &vin->vdev.pipe; ret = __media_pipeline_start(&vin->vdev.entity, pipe); mutex_unlock(&mdev->graph_mutex); if (ret) diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index d33f99c6ffa4..03ee19d00041 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -402,7 +402,7 @@ static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count) * Use the pipeline object embedded in the first DMA object that starts * streaming. */ - pipe = dma->video.entity.pipe + pipe = dma->video.entity.pads->pipe ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe; ret = media_pipeline_start(&dma->video.entity, &pipe->pipe); diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h index 2378bdae57ae..69ced71a5696 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.h +++ b/drivers/media/platform/xilinx/xilinx-dma.h @@ -47,7 +47,7 @@ struct xvip_pipeline { static inline struct xvip_pipeline *to_xvip_pipeline(struct media_entity *e) { - return container_of(e->pipe, struct xvip_pipeline, pipe); + return container_of(e->pads->pipe, struct xvip_pipeline, pipe); } /** diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 6f90acf9c725..535da4dda3c6 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -913,7 +913,7 @@ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd, __media_pipeline_stop(entity); } else { v4l2_subdev_call(sd, video, s_stream, 0); - if (entity->pipe) + if (entity->pads->pipe) __media_pipeline_stop(entity); } diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 68588e9dab0b..4c6f25aa8b57 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -548,7 +548,7 @@ static int iss_pipeline_is_last(struct media_entity *me) struct iss_pipeline *pipe; struct media_pad *pad; - if (!me->pipe) + if (!me->pads->pipe) return 0; pipe = to_iss_pipeline(me); if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED) diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 8c25ad73a81e..b74f7891711d 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -871,7 +871,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) * Start streaming on the pipeline. No link touching an entity in the * pipeline can be activated or deactivated once streaming is started. */ - pipe = pad->entity->pipe + pipe = pad->pipe ? to_iss_pipeline(pad->entity) : &video->pipe; pipe->external = NULL; pipe->external_rate = 0; diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h index 526281bf0051..9b8ec27bf87d 100644 --- a/drivers/staging/media/omap4iss/iss_video.h +++ b/drivers/staging/media/omap4iss/iss_video.h @@ -91,7 +91,7 @@ struct iss_pipeline { }; #define to_iss_pipeline(__e) \ - container_of((__e)->pipe, struct iss_pipeline, pipe) + container_of((__e)->pads->pipe, struct iss_pipeline, pipe) static inline int iss_pipeline_ready(struct iss_pipeline *pipe) { diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 5f6eed24e63f..c9d97c902d05 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -180,15 +180,24 @@ enum media_pad_signal_type { * * @graph_obj: Embedded structure containing the media object common data * @entity: Entity this pad belongs to + * @pipe: Pipeline this pad belongs to + * @stream_count: Stream count for the pad * @index: Pad index in the entity pads array, numbered from 0 to n * @sig_type: Type of the signal inside a media pad * @flags: Pad flags, as defined in * :ref:`include/uapi/linux/media.h ` * (seek for ``MEDIA_PAD_FL_*``) + * .. note:: + * + * @stream_count reference count must never be negative, but is a signed + * integer on purpose: a simple ``WARN_ON(<0)`` check can be used to + * detect reference count bugs that would make it negative. */ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ struct media_entity *entity; + struct media_pipeline *pipe; + int stream_count; u16 index; enum media_pad_signal_type sig_type; unsigned long flags; @@ -267,9 +276,7 @@ enum media_entity_type { * @pads: Pads array with the size defined by @num_pads. * @links: List of data links. * @ops: Entity operations. - * @stream_count: Stream count for the entity. * @use_count: Use count for the entity. - * @pipe: Pipeline this entity belongs to. * @info: Union with devnode information. Kept just for backward * compatibility. * @info.dev: Contains device major and minor info. @@ -282,10 +289,9 @@ enum media_entity_type { * * .. note:: * - * @stream_count and @use_count reference counts must never be - * negative, but are signed integers on purpose: a simple ``WARN_ON(<0)`` - * check can be used to detect reference count bugs that would make them - * negative. + * @use_count reference count must never be negative, but is a signed + * integer on purpose: a simple ``WARN_ON(<0)`` check can be used to + * detect reference count bugs that would make it negative. */ struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ @@ -304,11 +310,8 @@ struct media_entity { const struct media_entity_operations *ops; - int stream_count; int use_count; - struct media_pipeline *pipe; - union { struct { u32 major; From patchwork Mon Aug 30 11:00:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504819 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05A10C4320E for ; Mon, 30 Aug 2021 11:02:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DDD6661107 for ; Mon, 30 Aug 2021 11:02:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236478AbhH3LD1 (ORCPT ); Mon, 30 Aug 2021 07:03:27 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236448AbhH3LDY (ORCPT ); Mon, 30 Aug 2021 07:03:24 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 52AC41279; Mon, 30 Aug 2021 13:02:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321343; bh=OtkiYhMX9wv8B2uWuvjDzZHZSxgct8eAzkN4lfpMidY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qFGDvwhszWSk+5ewNbhT+NFYVH371Iq3gX0WLKyHsp95NwqZL3GxmNltVOWUxlZwp 9uVfxCIFykS4xvqEFnm6N0awOmVZlBEYKvhqJqizb0JlgtmghVfyi86JVaK3Jcwcb3 cibRjMjdkA0bHSCiQFDLp9XtoSyHxFDqgJSAfgxo= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 14/36] media: entity: Use pad as the starting point for a pipeline Date: Mon, 30 Aug 2021 14:00:54 +0300 Message-Id: <20210830110116.488338-15-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus The pipeline has been moved from the entity to the pads; reflect this in the media pipeline function API. Signed-off-by: Sakari Ailus Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- Documentation/driver-api/media/mc-core.rst | 9 +++-- drivers/media/mc/mc-entity.c | 24 ++++++------- drivers/media/pci/intel/ipu3/ipu3-cio2-main.c | 6 ++-- .../media/platform/exynos4-is/fimc-capture.c | 8 ++--- .../platform/exynos4-is/fimc-isp-video.c | 8 ++--- drivers/media/platform/exynos4-is/fimc-lite.c | 8 ++--- drivers/media/platform/omap3isp/ispvideo.c | 6 ++-- .../media/platform/qcom/camss/camss-video.c | 6 ++-- drivers/media/platform/rcar-vin/rcar-dma.c | 6 ++-- .../platform/rockchip/rkisp1/rkisp1-capture.c | 6 ++-- .../media/platform/s3c-camif/camif-capture.c | 6 ++-- drivers/media/platform/stm32/stm32-dcmi.c | 6 ++-- .../platform/sunxi/sun4i-csi/sun4i_dma.c | 6 ++-- .../platform/sunxi/sun6i-csi/sun6i_video.c | 6 ++-- drivers/media/platform/ti-vpe/cal-video.c | 6 ++-- drivers/media/platform/vsp1/vsp1_video.c | 6 ++-- drivers/media/platform/xilinx/xilinx-dma.c | 6 ++-- .../media/test-drivers/vimc/vimc-capture.c | 6 ++-- drivers/media/usb/au0828/au0828-core.c | 8 ++--- drivers/staging/media/imx/imx-media-utils.c | 6 ++-- drivers/staging/media/ipu3/ipu3-v4l2.c | 6 ++-- drivers/staging/media/omap4iss/iss_video.c | 6 ++-- drivers/staging/media/tegra-video/tegra210.c | 6 ++-- include/media/media-entity.h | 34 +++++++++---------- 24 files changed, 99 insertions(+), 102 deletions(-) diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst index 8a13640bed56..136047a22744 100644 --- a/Documentation/driver-api/media/mc-core.rst +++ b/Documentation/driver-api/media/mc-core.rst @@ -213,15 +213,14 @@ When starting streaming, drivers must notify all entities in the pipeline to prevent link states from being modified during streaming by calling :c:func:`media_pipeline_start()`. -The function will mark all entities connected to the given entity through -enabled links, either directly or indirectly, as streaming. +The function will mark all the pads connected to the given pad through +enabled routes and links, either directly or indirectly, as streaming. The struct media_pipeline instance pointed to by -the pipe argument will be stored in every entity in the pipeline. +the pipe argument will be stored in every pad in the pipeline. Drivers should embed the struct media_pipeline in higher-level pipeline structures and can then access the -pipeline through the struct media_entity -pipe field. +pipeline through the struct media_pad pipe field. Calls to :c:func:`media_pipeline_start()` can be nested. The pipeline pointer must be identical for all nested calls to the function. diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 8ad4cb845f4a..b44ab423b49b 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -404,12 +404,11 @@ EXPORT_SYMBOL_GPL(media_entity_get_fwnode_pad); * Pipeline management */ -__must_check int __media_pipeline_start(struct media_entity *entity, +__must_check int __media_pipeline_start(struct media_pad *pad, struct media_pipeline *pipe) { - struct media_device *mdev = entity->graph_obj.mdev; + struct media_device *mdev = pad->graph_obj.mdev; struct media_graph *graph = &pipe->graph; - struct media_pad *pad = entity->pads; struct media_pad *pad_err = pad; struct media_link *link; int ret; @@ -544,24 +543,23 @@ __must_check int __media_pipeline_start(struct media_entity *entity, } EXPORT_SYMBOL_GPL(__media_pipeline_start); -__must_check int media_pipeline_start(struct media_entity *entity, +__must_check int media_pipeline_start(struct media_pad *pad, struct media_pipeline *pipe) { - struct media_device *mdev = entity->graph_obj.mdev; + struct media_device *mdev = pad->graph_obj.mdev; int ret; mutex_lock(&mdev->graph_mutex); - ret = __media_pipeline_start(entity, pipe); + ret = __media_pipeline_start(pad, pipe); mutex_unlock(&mdev->graph_mutex); return ret; } EXPORT_SYMBOL_GPL(media_pipeline_start); -void __media_pipeline_stop(struct media_entity *entity) +void __media_pipeline_stop(struct media_pad *pad) { - struct media_pipeline *pipe = entity->pads->pipe; + struct media_pipeline *pipe = pad->pipe; struct media_graph *graph = &pipe->graph; - struct media_pad *pad; /* * If the following check fails, the driver has performed an @@ -570,7 +568,7 @@ void __media_pipeline_stop(struct media_entity *entity) if (WARN_ON(!pipe)) return; - media_graph_walk_start(graph, entity->pads); + media_graph_walk_start(graph, pad); while ((pad = media_graph_walk_next(graph))) { struct media_entity *entity = pad->entity; @@ -592,12 +590,12 @@ void __media_pipeline_stop(struct media_entity *entity) } EXPORT_SYMBOL_GPL(__media_pipeline_stop); -void media_pipeline_stop(struct media_entity *entity) +void media_pipeline_stop(struct media_pad *pad) { - struct media_device *mdev = entity->graph_obj.mdev; + struct media_device *mdev = pad->graph_obj.mdev; mutex_lock(&mdev->graph_mutex); - __media_pipeline_stop(entity); + __media_pipeline_stop(pad); mutex_unlock(&mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_pipeline_stop); diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c index 47db0ee0fcbf..74db79b2990f 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c @@ -981,7 +981,7 @@ static int cio2_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) return r; } - r = media_pipeline_start(&q->vdev.entity, &q->pipe); + r = media_pipeline_start(q->vdev.entity.pads, &q->pipe); if (r) goto fail_pipeline; @@ -1001,7 +1001,7 @@ static int cio2_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) fail_csi2_subdev: cio2_hw_exit(cio2, q); fail_hw: - media_pipeline_stop(&q->vdev.entity); + media_pipeline_stop(q->vdev.entity.pads); fail_pipeline: dev_dbg(&cio2->pci_dev->dev, "failed to start streaming (%d)\n", r); cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_QUEUED); @@ -1022,7 +1022,7 @@ static void cio2_vb2_stop_streaming(struct vb2_queue *vq) cio2_hw_exit(cio2, q); synchronize_irq(cio2->pci_dev->irq); cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_ERROR); - media_pipeline_stop(&q->vdev.entity); + media_pipeline_stop(q->vdev.entity.pads); pm_runtime_put(&cio2->pci_dev->dev); cio2->streaming = false; } diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 7ff4024003f4..eaac0ac4e406 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -524,7 +524,7 @@ static int fimc_capture_release(struct file *file) mutex_lock(&fimc->lock); if (close && vc->streaming) { - media_pipeline_stop(&vc->ve.vdev.entity); + media_pipeline_stop(vc->ve.vdev.entity.pads); vc->streaming = false; } @@ -1184,7 +1184,7 @@ static int fimc_cap_streamon(struct file *file, void *priv, if (fimc_capture_active(fimc)) return -EBUSY; - ret = media_pipeline_start(entity, &vc->ve.pipe->mp); + ret = media_pipeline_start(entity->pads, &vc->ve.pipe->mp); if (ret < 0) return ret; @@ -1218,7 +1218,7 @@ static int fimc_cap_streamon(struct file *file, void *priv, } err_p_stop: - media_pipeline_stop(entity); + media_pipeline_stop(entity->pads); return ret; } @@ -1234,7 +1234,7 @@ static int fimc_cap_streamoff(struct file *file, void *priv, return ret; if (vc->streaming) { - media_pipeline_stop(&vc->ve.vdev.entity); + media_pipeline_stop(vc->ve.vdev.entity.pads); vc->streaming = false; } diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 83688a7982f7..e2862b3dcdfc 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -312,7 +312,7 @@ static int isp_video_release(struct file *file) is_singular_file = v4l2_fh_is_singular_file(file); if (is_singular_file && ivc->streaming) { - media_pipeline_stop(entity); + media_pipeline_stop(entity->pads); ivc->streaming = 0; } @@ -493,7 +493,7 @@ static int isp_video_streamon(struct file *file, void *priv, struct media_entity *me = &ve->vdev.entity; int ret; - ret = media_pipeline_start(me, &ve->pipe->mp); + ret = media_pipeline_start(me->pads, &ve->pipe->mp); if (ret < 0) return ret; @@ -508,7 +508,7 @@ static int isp_video_streamon(struct file *file, void *priv, isp->video_capture.streaming = 1; return 0; p_stop: - media_pipeline_stop(me); + media_pipeline_stop(me->pads); return ret; } @@ -523,7 +523,7 @@ static int isp_video_streamoff(struct file *file, void *priv, if (ret < 0) return ret; - media_pipeline_stop(&video->ve.vdev.entity); + media_pipeline_stop(video->ve.vdev.entity.pads); video->streaming = 0; return 0; } diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 67bfb1ad2ba2..a979600ff6e6 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -516,7 +516,7 @@ static int fimc_lite_release(struct file *file) if (v4l2_fh_is_singular_file(file) && atomic_read(&fimc->out_path) == FIMC_IO_DMA) { if (fimc->streaming) { - media_pipeline_stop(entity); + media_pipeline_stop(entity->pads); fimc->streaming = false; } fimc_lite_stop_capture(fimc, false); @@ -822,7 +822,7 @@ static int fimc_lite_streamon(struct file *file, void *priv, if (fimc_lite_active(fimc)) return -EBUSY; - ret = media_pipeline_start(entity, &fimc->ve.pipe->mp); + ret = media_pipeline_start(entity->pads, &fimc->ve.pipe->mp); if (ret < 0) return ret; @@ -839,7 +839,7 @@ static int fimc_lite_streamon(struct file *file, void *priv, } err_p_stop: - media_pipeline_stop(entity); + media_pipeline_stop(entity->pads); return 0; } @@ -853,7 +853,7 @@ static int fimc_lite_streamoff(struct file *file, void *priv, if (ret < 0) return ret; - media_pipeline_stop(&fimc->ve.vdev.entity); + media_pipeline_stop(fimc->ve.vdev.entity.pads); fimc->streaming = false; return 0; } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index a8438040c4aa..87334477f223 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -1105,7 +1105,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); pipe->max_rate = pipe->l3_ick; - ret = media_pipeline_start(&video->video.entity, &pipe->pipe); + ret = media_pipeline_start(video->video.entity.pads, &pipe->pipe); if (ret < 0) goto err_pipeline_start; @@ -1162,7 +1162,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) return 0; err_check_format: - media_pipeline_stop(&video->video.entity); + media_pipeline_stop(video->video.entity.pads); err_pipeline_start: /* TODO: Implement PM QoS */ /* The DMA queue must be emptied here, otherwise CCDC interrupts that @@ -1229,7 +1229,7 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) video->error = false; /* TODO: Implement PM QoS */ - media_pipeline_stop(&video->video.entity); + media_pipeline_stop(video->video.entity.pads); media_entity_enum_cleanup(&pipe->ent_enum); diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c index f282275af626..5cd494f17589 100644 --- a/drivers/media/platform/qcom/camss/camss-video.c +++ b/drivers/media/platform/qcom/camss/camss-video.c @@ -491,7 +491,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count) struct v4l2_subdev *subdev; int ret; - ret = media_pipeline_start(&vdev->entity, &video->pipe); + ret = media_pipeline_start(vdev->entity.pads, &video->pipe); if (ret < 0) return ret; @@ -520,7 +520,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count) return 0; error: - media_pipeline_stop(&vdev->entity); + media_pipeline_stop(vdev->entity.pads); video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED); @@ -551,7 +551,7 @@ static void video_stop_streaming(struct vb2_queue *q) v4l2_subdev_call(subdev, video, s_stream, 0); } - media_pipeline_stop(&vdev->entity); + media_pipeline_stop(vdev->entity.pads); video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR); } diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 80b7ae47d165..83b2f923cf98 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1215,7 +1215,7 @@ static int rvin_set_stream(struct rvin_dev *vin, int on) sd = media_entity_to_v4l2_subdev(pad->entity); if (!on) { - media_pipeline_stop(&vin->vdev.entity); + media_pipeline_stop(vin->vdev.entity.pads); return v4l2_subdev_call(sd, video, s_stream, 0); } @@ -1232,7 +1232,7 @@ static int rvin_set_stream(struct rvin_dev *vin, int on) mdev = vin->vdev.entity.graph_obj.mdev; mutex_lock(&mdev->graph_mutex); pipe = sd->entity.pads->pipe ? sd->entity.pads->pipe : &vin->vdev.pipe; - ret = __media_pipeline_start(&vin->vdev.entity, pipe); + ret = __media_pipeline_start(vin->vdev.entity.pads, pipe); mutex_unlock(&mdev->graph_mutex); if (ret) return ret; @@ -1241,7 +1241,7 @@ static int rvin_set_stream(struct rvin_dev *vin, int on) if (ret == -ENOIOCTLCMD) ret = 0; if (ret) - media_pipeline_stop(&vin->vdev.entity); + media_pipeline_stop(vin->vdev.entity.pads); return ret; } diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c index 41988eb0ec0a..2efbe181b6f1 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c @@ -988,7 +988,7 @@ static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue) rkisp1_dummy_buf_destroy(cap); - media_pipeline_stop(&node->vdev.entity); + media_pipeline_stop(node->vdev.entity.pads); mutex_unlock(&cap->rkisp1->stream_lock); } @@ -1002,7 +1002,7 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count) mutex_lock(&cap->rkisp1->stream_lock); - ret = media_pipeline_start(entity, &cap->rkisp1->pipe); + ret = media_pipeline_start(entity->pads, &cap->rkisp1->pipe); if (ret) { dev_err(cap->rkisp1->dev, "start pipeline failed %d\n", ret); goto err_ret_buffers; @@ -1038,7 +1038,7 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count) err_destroy_dummy: rkisp1_dummy_buf_destroy(cap); err_pipeline_stop: - media_pipeline_stop(entity); + media_pipeline_stop(entity->pads); err_ret_buffers: rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED); mutex_unlock(&cap->rkisp1->stream_lock); diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index 140854ab4dd8..0189b8a33032 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -848,13 +848,13 @@ static int s3c_camif_streamon(struct file *file, void *priv, if (s3c_vp_active(vp)) return 0; - ret = media_pipeline_start(sensor, camif->m_pipeline); + ret = media_pipeline_start(sensor->pads, camif->m_pipeline); if (ret < 0) return ret; ret = camif_pipeline_validate(camif); if (ret < 0) { - media_pipeline_stop(sensor); + media_pipeline_stop(sensor->pads); return ret; } @@ -878,7 +878,7 @@ static int s3c_camif_streamoff(struct file *file, void *priv, ret = vb2_streamoff(&vp->vb_queue, type); if (ret == 0) - media_pipeline_stop(&camif->sensor.sd->entity); + media_pipeline_stop(camif->sensor.sd->entity.pads); return ret; } diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index d914ccef9831..457bc838bb73 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -730,7 +730,7 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) goto err_unlocked; } - ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline); + ret = media_pipeline_start(dcmi->vdev->entity.pads, &dcmi->pipeline); if (ret < 0) { dev_err(dcmi->dev, "%s: Failed to start streaming, media pipeline start error (%d)\n", __func__, ret); @@ -844,7 +844,7 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) dcmi_pipeline_stop(dcmi); err_media_pipeline_stop: - media_pipeline_stop(&dcmi->vdev->entity); + media_pipeline_stop(dcmi->vdev->entity.pads); err_pm_put: pm_runtime_put(dcmi->dev); @@ -871,7 +871,7 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) dcmi_pipeline_stop(dcmi); - media_pipeline_stop(&dcmi->vdev->entity); + media_pipeline_stop(dcmi->vdev->entity.pads); spin_lock_irq(&dcmi->irqlock); diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c index 2c39cd7f2862..be0defdf74f1 100644 --- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c @@ -266,7 +266,7 @@ static int sun4i_csi_start_streaming(struct vb2_queue *vq, unsigned int count) goto err_clear_dma_queue; } - ret = media_pipeline_start(&csi->vdev.entity, &csi->vdev.pipe); + ret = media_pipeline_start(csi->vdev.entity.pads, &csi->vdev.pipe); if (ret < 0) goto err_free_scratch_buffer; @@ -330,7 +330,7 @@ static int sun4i_csi_start_streaming(struct vb2_queue *vq, unsigned int count) sun4i_csi_capture_stop(csi); err_disable_pipeline: - media_pipeline_stop(&csi->vdev.entity); + media_pipeline_stop(csi->vdev.entity.pads); err_free_scratch_buffer: dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr, @@ -359,7 +359,7 @@ static void sun4i_csi_stop_streaming(struct vb2_queue *vq) return_all_buffers(csi, VB2_BUF_STATE_ERROR); spin_unlock_irqrestore(&csi->qlock, flags); - media_pipeline_stop(&csi->vdev.entity); + media_pipeline_stop(csi->vdev.entity.pads); dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr, csi->scratch.paddr); diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c index 07b2161392d2..6baa597a4dad 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c @@ -141,7 +141,7 @@ static int sun6i_video_start_streaming(struct vb2_queue *vq, unsigned int count) video->sequence = 0; - ret = media_pipeline_start(&video->vdev.entity, &video->vdev.pipe); + ret = media_pipeline_start(video->vdev.entity.pads, &video->vdev.pipe); if (ret < 0) goto clear_dma_queue; @@ -207,7 +207,7 @@ static int sun6i_video_start_streaming(struct vb2_queue *vq, unsigned int count) stop_csi_stream: sun6i_csi_set_stream(video->csi, false); stop_media_pipeline: - media_pipeline_stop(&video->vdev.entity); + media_pipeline_stop(video->vdev.entity.pads); clear_dma_queue: spin_lock_irqsave(&video->dma_queue_lock, flags); list_for_each_entry(buf, &video->dma_queue, list) @@ -231,7 +231,7 @@ static void sun6i_video_stop_streaming(struct vb2_queue *vq) sun6i_csi_set_stream(video->csi, false); - media_pipeline_stop(&video->vdev.entity); + media_pipeline_stop(video->vdev.entity.pads); /* Release all active buffers */ spin_lock_irqsave(&video->dma_queue_lock, flags); diff --git a/drivers/media/platform/ti-vpe/cal-video.c b/drivers/media/platform/ti-vpe/cal-video.c index 7799da1cc261..861a20ee6885 100644 --- a/drivers/media/platform/ti-vpe/cal-video.c +++ b/drivers/media/platform/ti-vpe/cal-video.c @@ -711,7 +711,7 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count) dma_addr_t addr; int ret; - ret = media_pipeline_start(&ctx->vdev.entity, &ctx->phy->pipe); + ret = media_pipeline_start(ctx->vdev.entity.pads, &ctx->phy->pipe); if (ret < 0) { ctx_err(ctx, "Failed to start media pipeline: %d\n", ret); goto error_release_buffers; @@ -764,7 +764,7 @@ static int cal_start_streaming(struct vb2_queue *vq, unsigned int count) cal_ctx_unprepare(ctx); error_pipeline: - media_pipeline_stop(&ctx->vdev.entity); + media_pipeline_stop(ctx->vdev.entity.pads); error_release_buffers: cal_release_buffers(ctx, VB2_BUF_STATE_QUEUED); @@ -785,7 +785,7 @@ static void cal_stop_streaming(struct vb2_queue *vq) cal_release_buffers(ctx, VB2_BUF_STATE_ERROR); - media_pipeline_stop(&ctx->vdev.entity); + media_pipeline_stop(ctx->vdev.entity.pads); } static const struct vb2_ops cal_video_qops = { diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index f2c36f2fdf53..978f820b0f34 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -927,7 +927,7 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) } mutex_unlock(&pipe->lock); - media_pipeline_stop(&video->video.entity); + media_pipeline_stop(video->video.entity.pads); vsp1_video_release_buffers(video); vsp1_video_pipeline_put(pipe); } @@ -1048,7 +1048,7 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) return PTR_ERR(pipe); } - ret = __media_pipeline_start(&video->video.entity, &pipe->pipe); + ret = __media_pipeline_start(video->video.entity.pads, &pipe->pipe); if (ret < 0) { mutex_unlock(&mdev->graph_mutex); goto err_pipe; @@ -1072,7 +1072,7 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) return 0; err_stop: - media_pipeline_stop(&video->video.entity); + media_pipeline_stop(video->video.entity.pads); err_pipe: vsp1_video_pipeline_put(pipe); return ret; diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 03ee19d00041..f04b3d190562 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -405,7 +405,7 @@ static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count) pipe = dma->video.entity.pads->pipe ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe; - ret = media_pipeline_start(&dma->video.entity, &pipe->pipe); + ret = media_pipeline_start(dma->video.entity.pads, &pipe->pipe); if (ret < 0) goto error; @@ -431,7 +431,7 @@ static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count) return 0; error_stop: - media_pipeline_stop(&dma->video.entity); + media_pipeline_stop(dma->video.entity.pads); error: /* Give back all queued buffers to videobuf2. */ @@ -459,7 +459,7 @@ static void xvip_dma_stop_streaming(struct vb2_queue *vq) /* Cleanup the pipeline and mark it as being stopped. */ xvip_pipeline_cleanup(pipe); - media_pipeline_stop(&dma->video.entity); + media_pipeline_stop(dma->video.entity.pads); /* Give back all queued buffers to videobuf2. */ spin_lock_irq(&dma->queued_lock); diff --git a/drivers/media/test-drivers/vimc/vimc-capture.c b/drivers/media/test-drivers/vimc/vimc-capture.c index 5e9fd902cd37..10724b0a868c 100644 --- a/drivers/media/test-drivers/vimc/vimc-capture.c +++ b/drivers/media/test-drivers/vimc/vimc-capture.c @@ -246,7 +246,7 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count) vcap->sequence = 0; /* Start the media pipeline */ - ret = media_pipeline_start(entity, &vcap->stream.pipe); + ret = media_pipeline_start(entity->pads, &vcap->stream.pipe); if (ret) { vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED); return ret; @@ -254,7 +254,7 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count) ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1); if (ret) { - media_pipeline_stop(entity); + media_pipeline_stop(entity->pads); vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED); return ret; } @@ -273,7 +273,7 @@ static void vimc_cap_stop_streaming(struct vb2_queue *vq) vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 0); /* Stop the media pipeline */ - media_pipeline_stop(&vcap->vdev.entity); + media_pipeline_stop(vcap->vdev.entity.pads); /* Release all active buffers */ vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_ERROR); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index caefac07af92..877e85a451cb 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -410,7 +410,7 @@ static int au0828_enable_source(struct media_entity *entity, goto end; } - ret = __media_pipeline_start(entity, pipe); + ret = __media_pipeline_start(entity->pads, pipe); if (ret) { pr_err("Start Pipeline: %s->%s Error %d\n", source->name, entity->name, ret); @@ -501,12 +501,12 @@ static void au0828_disable_source(struct media_entity *entity) return; /* stop pipeline */ - __media_pipeline_stop(dev->active_link_owner); + __media_pipeline_stop(dev->active_link_owner->pads); pr_debug("Pipeline stop for %s\n", dev->active_link_owner->name); ret = __media_pipeline_start( - dev->active_link_user, + dev->active_link_user->pads, dev->active_link_user_pipe); if (ret) { pr_err("Start Pipeline: %s->%s %d\n", @@ -532,7 +532,7 @@ static void au0828_disable_source(struct media_entity *entity) return; /* stop pipeline */ - __media_pipeline_stop(dev->active_link_owner); + __media_pipeline_stop(dev->active_link_owner->pads); pr_debug("Pipeline stop for %s\n", dev->active_link_owner->name); diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index 535da4dda3c6..74218af45551 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -905,16 +905,16 @@ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd, mutex_lock(&imxmd->md.graph_mutex); if (on) { - ret = __media_pipeline_start(entity, &imxmd->pipe); + ret = __media_pipeline_start(entity->pads, &imxmd->pipe); if (ret) goto out; ret = v4l2_subdev_call(sd, video, s_stream, 1); if (ret) - __media_pipeline_stop(entity); + __media_pipeline_stop(entity->pads); } else { v4l2_subdev_call(sd, video, s_stream, 0); if (entity->pads->pipe) - __media_pipeline_stop(entity); + __media_pipeline_stop(entity->pads); } out: diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index 38a240764509..db5867da3f11 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -485,7 +485,7 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) pipe = node->pipe; imgu_pipe = &imgu->imgu_pipe[pipe]; - r = media_pipeline_start(&node->vdev.entity, &imgu_pipe->pipeline); + r = media_pipeline_start(node->vdev.entity.pads, &imgu_pipe->pipeline); if (r < 0) goto fail_return_bufs; @@ -510,7 +510,7 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) return 0; fail_stop_pipeline: - media_pipeline_stop(&node->vdev.entity); + media_pipeline_stop(node->vdev.entity.pads); fail_return_bufs: imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_QUEUED); @@ -550,7 +550,7 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq) imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); mutex_unlock(&imgu->streaming_lock); - media_pipeline_stop(&node->vdev.entity); + media_pipeline_stop(node->vdev.entity.pads); } /******************** v4l2_ioctl_ops ********************/ diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index b74f7891711d..20fac40581c6 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -889,7 +889,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, true); - ret = media_pipeline_start(pad->entity, &pipe->pipe); + ret = media_pipeline_start(pad, &pipe->pipe); if (ret < 0) goto err_media_pipeline_start; @@ -980,7 +980,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) err_omap4iss_set_stream: vb2_streamoff(&vfh->queue, type); err_iss_video_check_format: - media_pipeline_stop(&video->video.entity); + media_pipeline_stop(video->video.entity.pads); err_media_pipeline_start: if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, false); @@ -1034,7 +1034,7 @@ iss_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, false); - media_pipeline_stop(&video->video.entity); + media_pipeline_stop(video->video.entity.pads); done: mutex_unlock(&video->stream_lock); diff --git a/drivers/staging/media/tegra-video/tegra210.c b/drivers/staging/media/tegra-video/tegra210.c index f10a041e3e6c..d2d7dd0e8624 100644 --- a/drivers/staging/media/tegra-video/tegra210.c +++ b/drivers/staging/media/tegra-video/tegra210.c @@ -547,7 +547,7 @@ static int tegra210_vi_start_streaming(struct vb2_queue *vq, u32 count) VI_INCR_SYNCPT_NO_STALL); /* start the pipeline */ - ret = media_pipeline_start(&chan->video.entity, pipe); + ret = media_pipeline_start(chan->video.entity.pads, pipe); if (ret < 0) goto error_pipeline_start; @@ -595,7 +595,7 @@ static int tegra210_vi_start_streaming(struct vb2_queue *vq, u32 count) error_kthread_start: tegra_channel_set_stream(chan, false); error_set_stream: - media_pipeline_stop(&chan->video.entity); + media_pipeline_stop(chan->video.entity.pads); error_pipeline_start: tegra_channel_release_buffers(chan, VB2_BUF_STATE_QUEUED); return ret; @@ -617,7 +617,7 @@ static void tegra210_vi_stop_streaming(struct vb2_queue *vq) tegra_channel_release_buffers(chan, VB2_BUF_STATE_ERROR); tegra_channel_set_stream(chan, false); - media_pipeline_stop(&chan->video.entity); + media_pipeline_stop(chan->video.entity.pads); } /* diff --git a/include/media/media-entity.h b/include/media/media-entity.h index c9d97c902d05..516d73a2941e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -937,53 +937,53 @@ struct media_pad *media_graph_walk_next(struct media_graph *graph); /** * media_pipeline_start - Mark a pipeline as streaming - * @entity: Starting entity - * @pipe: Media pipeline to be assigned to all entities in the pipeline. + * @pad: Starting pad + * @pipe: Media pipeline to be assigned to all pads in the pipeline. * - * Mark all entities connected to a given entity through enabled links, either - * directly or indirectly, as streaming. The given pipeline object is assigned - * to every entity in the pipeline and stored in the media_entity pipe field. + * Mark all pads connected to a given pad through enabled routes or links, + * either directly or indirectly, as streaming. The given pipeline object is + * assigned to every pad in the pipeline and stored in the media_pad pipe + * field. * * Calls to this function can be nested, in which case the same number of * media_pipeline_stop() calls will be required to stop streaming. The * pipeline pointer must be identical for all nested calls to * media_pipeline_start(). */ -__must_check int media_pipeline_start(struct media_entity *entity, +__must_check int media_pipeline_start(struct media_pad *pad, struct media_pipeline *pipe); /** * __media_pipeline_start - Mark a pipeline as streaming * - * @entity: Starting entity - * @pipe: Media pipeline to be assigned to all entities in the pipeline. + * @pad: Starting pad + * @pipe: Media pipeline to be assigned to all pads in the pipeline. * * ..note:: This is the non-locking version of media_pipeline_start() */ -__must_check int __media_pipeline_start(struct media_entity *entity, +__must_check int __media_pipeline_start(struct media_pad *pad, struct media_pipeline *pipe); /** * media_pipeline_stop - Mark a pipeline as not streaming - * @entity: Starting entity + * @pad: Starting pad * - * Mark all entities connected to a given entity through enabled links, either - * directly or indirectly, as not streaming. The media_entity pipe field is - * reset to %NULL. + * Mark all pads connected to a given pad through enabled routes or links, + * either directly or indirectly, as not streaming. * * If multiple calls to media_pipeline_start() have been made, the same * number of calls to this function are required to mark the pipeline as not - * streaming. + * streaming and reset the media_pad pipe field to %NULL. */ -void media_pipeline_stop(struct media_entity *entity); +void media_pipeline_stop(struct media_pad *pad); /** * __media_pipeline_stop - Mark a pipeline as not streaming * - * @entity: Starting entity + * @pad: Starting pad * * .. note:: This is the non-locking version of media_pipeline_stop() */ -void __media_pipeline_stop(struct media_entity *entity); +void __media_pipeline_stop(struct media_pad *pad); /** * media_devnode_create() - creates and initializes a device node interface From patchwork Mon Aug 30 11:00:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504820 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DAB3C43214 for ; Mon, 30 Aug 2021 11:02:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 79CA56113A for ; Mon, 30 Aug 2021 11:02:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236485AbhH3LD1 (ORCPT ); Mon, 30 Aug 2021 07:03:27 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236449AbhH3LDY (ORCPT ); Mon, 30 Aug 2021 07:03:24 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 374A51334; Mon, 30 Aug 2021 13:02:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321343; bh=DRLJ+R0TbbvqigB5q68R6rhX+XyW5CJQPCSMtDNY2hs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CfgaRudlrtQA+teVEW11N0JBZt6BBE7WWbZdvMbNzJBxWAdMd5uLXqSsmEcQNc25y Ug4zL8o6rHFIBj98psup1Xqhu/Xy0xtoP7YNkqm0M2qiIN6msTQ1J0HJOEikv24XDj UXB+5KnmhW2gNO+gbBSi6+t2qt6JQU4X3OEz9G4k= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla , Michal Simek Subject: [PATCH v8 15/36] media: entity: Add has_route entity operation Date: Mon, 30 Aug 2021 14:00:55 +0300 Message-Id: <20210830110116.488338-16-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Laurent Pinchart The optional operation can be used by entities to report whether two pads are internally connected. While at there, fix a Sphinx compiler warning in a comment block a few lines above. Signed-off-by: Laurent Pinchart Signed-off-by: Michal Simek Signed-off-by: Sakari Ailus Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- include/media/media-entity.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 516d73a2941e..ad4020b2df65 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -187,6 +187,7 @@ enum media_pad_signal_type { * @flags: Pad flags, as defined in * :ref:`include/uapi/linux/media.h ` * (seek for ``MEDIA_PAD_FL_*``) + * * .. note:: * * @stream_count reference count must never be negative, but is a signed @@ -214,6 +215,10 @@ struct media_pad { * @link_validate: Return whether a link is valid from the entity point of * view. The media_pipeline_start() function * validates all links by calling this operation. Optional. + * @has_route: Return whether a route exists inside the entity between + * two given pads. Pads are passed to the operation ordered + * by index. Optional: If the operation isn't implemented + * all pads will be considered as connected. * * .. note:: * @@ -227,6 +232,8 @@ struct media_entity_operations { const struct media_pad *local, const struct media_pad *remote, u32 flags); int (*link_validate)(struct media_link *link); + bool (*has_route)(struct media_entity *entity, unsigned int pad0, + unsigned int pad1); }; /** From patchwork Mon Aug 30 11:00:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504495 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DC73C432BE for ; Mon, 30 Aug 2021 11:02:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EE22E6112F for ; Mon, 30 Aug 2021 11:02:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236486AbhH3LD2 (ORCPT ); Mon, 30 Aug 2021 07:03:28 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236450AbhH3LDZ (ORCPT ); Mon, 30 Aug 2021 07:03:25 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 28B99146F; Mon, 30 Aug 2021 13:02:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321344; bh=WfNNqbtlD9WLVh/jXPaVCZ6hgKEw1491aKMzPa4gO1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kUa6Q+5zQnUyASlcaKlmhJ3EUToQ0oT6/9zZEC/aLuvqbT73CWLBiy3Fbt7F97xzS 1Y6O0V2/AVVb+8aNmZYEANL+h1/uRFs4BfYyxk+VN21mOTQDhF5qWkpj029pP2YRT3 18dWLohdfQP71dhjSxXsY8nx1TXzGF8UuH77KUvE= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla , Michal Simek Subject: [PATCH v8 16/36] media: entity: Add media_entity_has_route() function Date: Mon, 30 Aug 2021 14:00:56 +0300 Message-Id: <20210830110116.488338-17-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Laurent Pinchart This is a wrapper around the media entity has_route operation. Signed-off-by: Laurent Pinchart Signed-off-by: Michal Simek Signed-off-by: Sakari Ailus Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- drivers/media/mc/mc-entity.c | 19 +++++++++++++++++++ include/media/media-entity.h | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index b44ab423b49b..a83f004efd37 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -229,6 +229,25 @@ EXPORT_SYMBOL_GPL(media_entity_pads_init); * Graph traversal */ +bool media_entity_has_route(struct media_entity *entity, unsigned int pad0, + unsigned int pad1) +{ + if (pad0 >= entity->num_pads || pad1 >= entity->num_pads) + return false; + + if (pad0 == pad1) + return true; + + if (!entity->ops || !entity->ops->has_route) + return true; + + if (entity->pads[pad1].index < entity->pads[pad0].index) + swap(pad0, pad1); + + return entity->ops->has_route(entity, pad0, pad1); +} +EXPORT_SYMBOL_GPL(media_entity_has_route); + static struct media_pad * media_pad_other(struct media_pad *pad, struct media_link *link) { diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ad4020b2df65..b3069eef7fdb 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -904,6 +904,23 @@ int media_entity_get_fwnode_pad(struct media_entity *entity, __must_check int media_graph_walk_init( struct media_graph *graph, struct media_device *mdev); +/** + * media_entity_has_route - Check if two entity pads are connected internally + * + * @entity: The entity + * @pad0: The first pad index + * @pad1: The second pad index + * + * This function can be used to check whether two pads of an entity are + * connected internally in the entity. + * + * The caller must hold entity->graph_obj.mdev->mutex. + * + * Return: true if the pads are connected internally and false otherwise. + */ +bool media_entity_has_route(struct media_entity *entity, unsigned int pad0, + unsigned int pad1); + /** * media_graph_walk_cleanup - Release resources used by graph walk. * From patchwork Mon Aug 30 11:00:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504494 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 969A4C43216 for ; Mon, 30 Aug 2021 11:02:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 872FB61102 for ; Mon, 30 Aug 2021 11:02:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236491AbhH3LD2 (ORCPT ); Mon, 30 Aug 2021 07:03:28 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236459AbhH3LDZ (ORCPT ); Mon, 30 Aug 2021 07:03:25 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 182255A7; Mon, 30 Aug 2021 13:02:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321345; bh=fBmi7rAybO8V2zMqNy7LWawcc/2RQMUQuRo2+xJ+qZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WayWSoUf11r3tYBH1q0XXk7dgTbZTi3nrNiajWDuFhnYxhdO5PGLEZkKGG0DkpDpv bZQ8XzO18A8va+2zCGCLCgAoHIih0oTCutMGYq9jEEFpGb6YSx37Wh2/O7F/KYdlc4 TtrKiwb2mUlgJ62zxEf/uc/06CWBJS5Aq08CcIdQ= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla , Michal Simek Subject: [PATCH v8 17/36] media: entity: Use routing information during graph traversal Date: Mon, 30 Aug 2021 14:00:57 +0300 Message-Id: <20210830110116.488338-18-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Laurent Pinchart Take internal routing information as reported by the entity has_route operation into account during graph traversal to avoid following unrelated links. Signed-off-by: Laurent Pinchart Signed-off-by: Michal Simek Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- drivers/media/mc/mc-entity.c | 46 ++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index a83f004efd37..58cdc9c6b342 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -248,15 +248,6 @@ bool media_entity_has_route(struct media_entity *entity, unsigned int pad0, } EXPORT_SYMBOL_GPL(media_entity_has_route); -static struct media_pad * -media_pad_other(struct media_pad *pad, struct media_link *link) -{ - if (link->source == pad) - return link->sink; - else - return link->source; -} - /* push an entity to traversal stack */ static void stack_push(struct media_graph *graph, struct media_pad *pad) { @@ -327,7 +318,8 @@ static void media_graph_walk_iter(struct media_graph *graph) { struct media_pad *pad = stack_top(graph); struct media_link *link; - struct media_pad *next; + struct media_pad *remote; + struct media_pad *local; link = list_entry(link_top(graph), typeof(*link), list); @@ -341,24 +333,42 @@ static void media_graph_walk_iter(struct media_graph *graph) return; } - /* Get the entity at the other end of the link. */ - next = media_pad_other(pad, link); + /* + * Get the local pad, the remote pad and the entity at the other + * end of the link. + */ + if (link->source->entity == pad->entity) { + remote = link->sink; + local = link->source; + } else { + remote = link->source; + local = link->sink; + } + + /* + * Are the local pad and the pad we came from connected + * internally in the entity ? + */ + if (!media_entity_has_route(pad->entity, pad->index, local->index)) { + link_top(graph) = link_top(graph)->next; + return; + } /* Has the entity already been visited? */ - if (media_entity_enum_test_and_set(&graph->ent_enum, next->entity)) { + if (media_entity_enum_test_and_set(&graph->ent_enum, remote->entity)) { link_top(graph) = link_top(graph)->next; dev_dbg(pad->graph_obj.mdev->dev, "walk: skipping entity '%s' (already seen)\n", - next->entity->name); + remote->entity->name); return; } /* Push the new entity to stack and start over. */ link_top(graph) = link_top(graph)->next; - stack_push(graph, next); - dev_dbg(next->graph_obj.mdev->dev, "walk: pushing '%s':%u on stack\n", - next->entity->name, next->index); - lockdep_assert_held(&next->graph_obj.mdev->graph_mutex); + stack_push(graph, remote); + dev_dbg(remote->graph_obj.mdev->dev, "walk: pushing '%s':%u on stack\n", + remote->entity->name, remote->index); + lockdep_assert_held(&remote->graph_obj.mdev->graph_mutex); } struct media_pad *media_graph_walk_next(struct media_graph *graph) From patchwork Mon Aug 30 11:00:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504818 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BFD7C4320A for ; Mon, 30 Aug 2021 11:02:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 89A396113A for ; Mon, 30 Aug 2021 11:02:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236494AbhH3LD3 (ORCPT ); Mon, 30 Aug 2021 07:03:29 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236469AbhH3LD0 (ORCPT ); Mon, 30 Aug 2021 07:03:26 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 161921489; Mon, 30 Aug 2021 13:02:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321346; bh=3+YgyXzsPP4KS4GsPgH+S1WSVb2QTLubXVGO6Cuekc0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sxTBKesRX/xPLvZDpKsHWQNEMxv4IkicRFfeJ46ifJMS5k+D21jxJmhXYZOCSRkNM FHUE2vrObFZu3oNVq+G8ihkavRjcHtZA+vXUI7xg8g6La8pSxjDqm9lpZYpJrjKX13 K5ntcgyctF8+5amA8ZJ5OVOxb1JehMk8kknuMgjA= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 18/36] media: entity: Skip link validation for pads to which there is no route Date: Mon, 30 Aug 2021 14:00:58 +0300 Message-Id: <20210830110116.488338-19-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus Links are validated along the pipeline which is about to start streaming. Not all the pads in entities that are traversed along that pipeline are part of the pipeline, however. Skip the link validation for such pads. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- drivers/media/mc/mc-entity.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 58cdc9c6b342..e963850b32df 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -489,6 +489,11 @@ __must_check int __media_pipeline_start(struct media_pad *pad, link->sink->entity == entity ? link->sink : link->source; + /* Ignore pads to which there is no route. */ + if (!media_entity_has_route(entity, pad->index, + other_pad->index)) + continue; + /* Mark that a pad is connected by a link. */ bitmap_clear(has_no_links, other_pad->index, 1); From patchwork Mon Aug 30 11:00:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504493 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4EB96C432BE for ; Mon, 30 Aug 2021 11:02:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3A4C961102 for ; Mon, 30 Aug 2021 11:02:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236498AbhH3LDa (ORCPT ); Mon, 30 Aug 2021 07:03:30 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236475AbhH3LD0 (ORCPT ); Mon, 30 Aug 2021 07:03:26 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ED5CD156A; Mon, 30 Aug 2021 13:02:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321347; bh=iIYIEOjyYGKMALl/dDuwMxeOh/aW9HsBxJIVF9D5BsA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GpDssssO+MlpGatoSV2U9g0AoajvyGBhe8OTSLu0slTFB0sTaS5G4/OJPEFR+Qn/1 FZALrPsghpjYU58CUZYJxQEuj1aQQDNNrjug5uNqtViKN8yq4vyX8vEoYLj/wK1dvd tJdkQEUYSyhaObi81qFVG9YgJQ6LU9nZWvU4K/1U= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 19/36] media: entity: Add an iterator helper for connected pads Date: Mon, 30 Aug 2021 14:00:59 +0300 Message-Id: <20210830110116.488338-20-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus Add a helper macro for iterating over pads that are connected through enabled routes. This can be used to find all the connected pads within an entity, for instance starting from the pad which has been obtained during the graph walk. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund - Make __media_entity_next_routed_pad() return NULL and adjust the iterator to handle that Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Signed-off-by: Tomi Valkeinen --- drivers/media/mc/mc-entity.c | 14 ++++++++++++++ include/media/media-entity.h | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index e963850b32df..072f017b399a 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -248,6 +248,20 @@ bool media_entity_has_route(struct media_entity *entity, unsigned int pad0, } EXPORT_SYMBOL_GPL(media_entity_has_route); +struct media_pad *__media_entity_next_routed_pad(struct media_pad *root, + struct media_pad *iter) +{ + struct media_entity *entity = root->entity; + + for (; iter < &entity->pads[entity->num_pads]; iter++) { + if (media_entity_has_route(entity, root->index, iter->index)) + return iter; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(__media_entity_next_routed_pad); + /* push an entity to traversal stack */ static void stack_push(struct media_graph *graph, struct media_pad *pad) { diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b3069eef7fdb..cd1750e495df 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -921,6 +921,32 @@ __must_check int media_graph_walk_init( bool media_entity_has_route(struct media_entity *entity, unsigned int pad0, unsigned int pad1); +/** + * __media_entity_next_routed_pad - Get next pad connected to @root + * + * @root: The root pad to which the iterated pads have a route + * @iter: The iterator pad + * + * Get next pad which has a route to @root. + */ +struct media_pad *__media_entity_next_routed_pad(struct media_pad *root, + struct media_pad *iter); + +/** + * media_entity_for_each_routed_pad - Iterate over entity pads connected by routes + * + * @root: The root pad to which the iterated pads have a route + * @iter: The iterator pad + * + * Iterate over all pads of an entity which have an internal route to @root pad. + * The iteration will include the @root pad itself. + */ +#define media_entity_for_each_routed_pad(root, iter) \ + for (iter = __media_entity_next_routed_pad(root, \ + (root)->entity->pads); \ + iter != NULL; \ + iter = __media_entity_next_routed_pad(root, iter + 1)) + /** * media_graph_walk_cleanup - Release resources used by graph walk. * From patchwork Mon Aug 30 11:01:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504817 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 284ABC43214 for ; Mon, 30 Aug 2021 11:02:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1202861139 for ; Mon, 30 Aug 2021 11:02:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236503AbhH3LDb (ORCPT ); Mon, 30 Aug 2021 07:03:31 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236477AbhH3LD1 (ORCPT ); Mon, 30 Aug 2021 07:03:27 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D187F1924; Mon, 30 Aug 2021 13:02:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321348; bh=YHZvmeGd5HTtm5USFRz0/NGI/WH25omht+wndPg3R+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R8+LZh3iKn7Xg8bN8qQMLFpRaHCPgdhks06nKERghpsI6bwjMPrgbXOyVvP0eDOdy xiBb0iJPGQvpg3qxnumWxzY9pKHLaZU5jmWFqJmUqDI5mVgfCKlECiyObyrBqX/5FJ 4KJpmLFgeeJUV9PULGJb9NiwW347zyIfdTcjYjyA= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 20/36] media: entity: Add only connected pads to the pipeline Date: Mon, 30 Aug 2021 14:01:00 +0300 Message-Id: <20210830110116.488338-21-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus A single entity may contain multiple pipelines. Only add pads that were connected to the pad through which the entity was reached to the pipeline. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- drivers/media/mc/mc-entity.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 072f017b399a..4eb4b94c09e2 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -474,7 +474,7 @@ __must_check int __media_pipeline_start(struct media_pad *pad, ret = 0; - media_entity_for_each_pad(entity, iter) { + media_entity_for_each_routed_pad(pad, iter) { if (iter->pipe && iter->pipe != pipe) { pr_err("Pipe active for %s. Can't start for %s\n", entity->name, iter->entity->name); @@ -563,10 +563,9 @@ __must_check int __media_pipeline_start(struct media_pad *pad, media_graph_walk_start(graph, pad_err); while ((pad_err = media_graph_walk_next(graph))) { - struct media_entity *entity = pad_err->entity; struct media_pad *iter; - media_entity_for_each_pad(entity, iter) { + media_entity_for_each_routed_pad(pad_err, iter) { /* Sanity check for negative stream_count */ if (!WARN_ON_ONCE(iter->stream_count <= 0)) { --iter->stream_count; @@ -619,10 +618,9 @@ void __media_pipeline_stop(struct media_pad *pad) media_graph_walk_start(graph, pad); while ((pad = media_graph_walk_next(graph))) { - struct media_entity *entity = pad->entity; struct media_pad *iter; - media_entity_for_each_pad(entity, iter) { + media_entity_for_each_routed_pad(pad, iter) { /* Sanity check for negative stream_count */ if (!WARN_ON_ONCE(iter->stream_count <= 0)) { iter->stream_count--; From patchwork Mon Aug 30 11:01:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504492 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94ACAC432BE for ; Mon, 30 Aug 2021 11:02:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7D8C161131 for ; Mon, 30 Aug 2021 11:02:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236509AbhH3LDc (ORCPT ); Mon, 30 Aug 2021 07:03:32 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236448AbhH3LD1 (ORCPT ); Mon, 30 Aug 2021 07:03:27 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B3FE18AD; Mon, 30 Aug 2021 13:02:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321349; bh=k4dtSi5T81HriB88LQzoRIe3W/ODgFiOtzTeyiQAslA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qJQ4i9rXyIiNNnKY7BaqBIifh7kZlIgBj9SWGbn03qKkkVqn39798Do2ix6FnTj0F 7v+j1gjaqUeZCCCABFY959193H5BIX2sBuvm3rPjYgv4IE60+1cPcTLKw3fPoILbUn 7+urq/t65Oto9Yci2wNnLUkG5zIJjW3dSLT4SEUg= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 21/36] media: entity: Add debug information in graph walk route check Date: Mon, 30 Aug 2021 14:01:01 +0300 Message-Id: <20210830110116.488338-22-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus Add debug printout in graph walk route check. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- drivers/media/mc/mc-entity.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 4eb4b94c09e2..663773f6bb2f 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -365,6 +365,9 @@ static void media_graph_walk_iter(struct media_graph *graph) */ if (!media_entity_has_route(pad->entity, pad->index, local->index)) { link_top(graph) = link_top(graph)->next; + dev_dbg(pad->graph_obj.mdev->dev, + "walk: skipping \"%s\":%u -> %u (no route)\n", + pad->entity->name, pad->index, local->index); return; } From patchwork Mon Aug 30 11:01:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504816 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8304FC4320A for ; Mon, 30 Aug 2021 11:02:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6F0276113D for ; Mon, 30 Aug 2021 11:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236517AbhH3LDd (ORCPT ); Mon, 30 Aug 2021 07:03:33 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236480AbhH3LD1 (ORCPT ); Mon, 30 Aug 2021 07:03:27 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9328A1543; Mon, 30 Aug 2021 13:02:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321350; bh=uAejeEnF4wLo8/PXKQHvt/Yl7pOuK99aODYQikJB0tI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=thg4wqZhu7FXLR3DpqDhShnY7UmkZUaNZq4dkDhZaEQLSa3G9DJtGEJuUZxUANYic 9twVr9e1p8fpiT9wORJsjqVs1axIjOcA9iAqz2kiKcBgl/oBCyjPbfnN1HHP4GZfGO O2tbbLjnNeUks4MzKQXkKdywkNKaXK86uadTi6P8= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 22/36] media: Add bus type to frame descriptors Date: Mon, 30 Aug 2021 14:01:02 +0300 Message-Id: <20210830110116.488338-23-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus Add the media bus type to the frame descriptor. CSI-2 specific information will be added in next patch to the frame descriptor. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund - Make the bus type a named enum Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- include/media/v4l2-subdev.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 2290b5025fc0..65471e579815 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -344,12 +344,32 @@ struct v4l2_mbus_frame_desc_entry { #define V4L2_FRAME_DESC_ENTRY_MAX 4 +/** + * enum v4l2_mbus_frame_desc_type - media bus frame description type + * + * @V4L2_MBUS_FRAME_DESC_TYPE_UNDEFINED: + * Undefined frame desc type. Drivers should not use this, it is + * for backwards compatibility. + * @V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL: + * Parallel media bus. + * @V4L2_MBUS_FRAME_DESC_TYPE_CSI2: + * CSI-2 media bus. Frame desc parameters must be set in + * &struct v4l2_mbus_frame_desc_entry->csi2. + */ +enum v4l2_mbus_frame_desc_type { + V4L2_MBUS_FRAME_DESC_TYPE_UNDEFINED = 0, + V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL, + V4L2_MBUS_FRAME_DESC_TYPE_CSI2, +}; + /** * struct v4l2_mbus_frame_desc - media bus data frame description + * @type: type of the bus (enum v4l2_mbus_frame_desc_type) * @entry: frame descriptors array * @num_entries: number of entries in @entry array */ struct v4l2_mbus_frame_desc { + enum v4l2_mbus_frame_desc_type type; struct v4l2_mbus_frame_desc_entry entry[V4L2_FRAME_DESC_ENTRY_MAX]; unsigned short num_entries; }; From patchwork Mon Aug 30 11:01:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504490 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 17202C4320E for ; Mon, 30 Aug 2021 11:02:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 010DB61131 for ; Mon, 30 Aug 2021 11:02:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236384AbhH3LDe (ORCPT ); Mon, 30 Aug 2021 07:03:34 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236488AbhH3LD3 (ORCPT ); Mon, 30 Aug 2021 07:03:29 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 77389B7E; Mon, 30 Aug 2021 13:02:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321351; bh=Q3RxadSLrXHtHkV0AyktOCF7iAfAYimZgccI7frbwRo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aH+hh5lymuFlEsWlw7aNrznOsnS7SpXAOkh0TQjtKnMQknf3ZiqNEWAOuSTod36ds zIXGhpfMjaLR7lxerQZY2TDS8dPHBxJOUAIHrEiQuDHYIkbojq8GQJf2eCYRngs5ba ftS/1XOVq2nhgm+dU6xS9NUo6VJ7Yx404sKCgZ3E= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 23/36] media: Add CSI-2 bus configuration to frame descriptors Date: Mon, 30 Aug 2021 14:01:03 +0300 Message-Id: <20210830110116.488338-24-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus Add CSI-2 bus specific configuration to the frame descriptors. This allows obtaining the virtual channel and data type information for each stream the transmitter is sending. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- include/media/v4l2-subdev.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 65471e579815..3071d202597d 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -312,6 +312,17 @@ struct v4l2_subdev_audio_ops { int (*s_stream)(struct v4l2_subdev *sd, int enable); }; +/** + * struct v4l2_mbus_frame_desc_entry_csi2 + * + * @vc: CSI-2 virtual channel + * @dt: CSI-2 data type ID + */ +struct v4l2_mbus_frame_desc_entry_csi2 { + u8 vc; + u8 dt; +}; + /** * enum v4l2_mbus_frame_desc_flags - media bus frame description flags * @@ -335,11 +346,16 @@ enum v4l2_mbus_frame_desc_flags { * %FRAME_DESC_FL_BLOB is not set. * @length: number of octets per frame, valid if @flags * %V4L2_MBUS_FRAME_DESC_FL_LEN_MAX is set. + * @bus: Bus-specific frame descriptor parameters + * @bus.csi2: CSI-2-specific bus configuration */ struct v4l2_mbus_frame_desc_entry { enum v4l2_mbus_frame_desc_flags flags; u32 pixelcode; u32 length; + union { + struct v4l2_mbus_frame_desc_entry_csi2 csi2; + } bus; }; #define V4L2_FRAME_DESC_ENTRY_MAX 4 From patchwork Mon Aug 30 11:01:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504814 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4DED3C43216 for ; Mon, 30 Aug 2021 11:02:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D1C56113C for ; Mon, 30 Aug 2021 11:02:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236529AbhH3LDf (ORCPT ); Mon, 30 Aug 2021 07:03:35 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236490AbhH3LD3 (ORCPT ); Mon, 30 Aug 2021 07:03:29 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 540DBB9C; Mon, 30 Aug 2021 13:02:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321352; bh=0pUu/xAEYHpYQ2OvcfMdz+cb/psSCmdkXZAphq5k2vc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZPtyRn4FliniOHjxm1VB4ai5sDm6ORH0ETWAIX582i+80/34vgHdLGIDDi45EgfjV zmr25pqn6R8BxjIHw4FUUlckgzCmHngLVHJGlEsb7wDw59MkoLHTV46V3WvG13WeiF Gm9O2mqJpfZ+IKt1DglVRnqg4yGqDbtS/eoT1un8= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 24/36] media: Add stream to frame descriptor Date: Mon, 30 Aug 2021 14:01:04 +0300 Message-Id: <20210830110116.488338-25-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sakari Ailus The stream field identifies the stream this frame descriptor applies to in routing configuration across a multiplexed link. Signed-off-by: Sakari Ailus Reviewed-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- include/media/v4l2-subdev.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 3071d202597d..f232b9f52817 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -342,6 +342,7 @@ enum v4l2_mbus_frame_desc_flags { * struct v4l2_mbus_frame_desc_entry - media bus frame description structure * * @flags: bitmask flags, as defined by &enum v4l2_mbus_frame_desc_flags. + * @stream: stream in routing configuration * @pixelcode: media bus pixel code, valid if @flags * %FRAME_DESC_FL_BLOB is not set. * @length: number of octets per frame, valid if @flags @@ -351,6 +352,7 @@ enum v4l2_mbus_frame_desc_flags { */ struct v4l2_mbus_frame_desc_entry { enum v4l2_mbus_frame_desc_flags flags; + u32 stream; u32 pixelcode; u32 length; union { From patchwork Mon Aug 30 11:01:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504491 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CC5ECC19F35 for ; Mon, 30 Aug 2021 11:02:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B3E3661102 for ; Mon, 30 Aug 2021 11:02:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236531AbhH3LDg (ORCPT ); Mon, 30 Aug 2021 07:03:36 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236492AbhH3LDa (ORCPT ); Mon, 30 Aug 2021 07:03:30 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3948D185F; Mon, 30 Aug 2021 13:02:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321352; bh=acRzB5SPAWNb2gdeyhPnUB06+MeXvCcwNvdN+zTW814=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V1UGpF6kLWOUTyAvWWdGnv5lic59THJu1M+yVuoTs+ywQL4GtysTBvew/zuxNPNGI jhdjV5QsLZ+pUg/YrBRS5G3Uv2fXXGYUG4b471YTrCYSIC1gJmT/Tnv3NM+P6Po20u uRbI2OoGej3MLMofKosIPbt7Bz6nPTkDkRjuYLyU= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 25/36] media: subdev: increase V4L2_FRAME_DESC_ENTRY_MAX to 8 Date: Mon, 30 Aug 2021 14:01:05 +0300 Message-Id: <20210830110116.488338-26-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org V4L2_FRAME_DESC_ENTRY_MAX is currently set to 4. In theory it's possible to have an arbitrary amount of streams in a single pad, so preferably there should be no hardcoded maximum number. However, I believe a reasonable max is 8, which would cover a CSI-2 pad with 4 streams of pixel data and 4 streams of metadata. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- include/media/v4l2-subdev.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index f232b9f52817..1c022d1a6896 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -360,7 +360,11 @@ struct v4l2_mbus_frame_desc_entry { } bus; }; -#define V4L2_FRAME_DESC_ENTRY_MAX 4 + /* + * FIXME: If this number is too small, it should be dropped altogether and the + * API switched to a dynamic number of frame descriptor entries. + */ +#define V4L2_FRAME_DESC_ENTRY_MAX 8 /** * enum v4l2_mbus_frame_desc_type - media bus frame description type From patchwork Mon Aug 30 11:01:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504815 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FC69C19F38 for ; Mon, 30 Aug 2021 11:02:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 091EE61139 for ; Mon, 30 Aug 2021 11:02:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236532AbhH3LDg (ORCPT ); Mon, 30 Aug 2021 07:03:36 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236493AbhH3LDa (ORCPT ); Mon, 30 Aug 2021 07:03:30 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 16BEE220E; Mon, 30 Aug 2021 13:02:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321353; bh=3xTblfq00yXar8gawda0KjUrZ6yQgX3YMAn7J39H5rE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QoTzlQDsM8qCFpe+K8y3Me8p/+yLPJQ0YzHcjB9vEX1jY6+RaabB1VkVq2VACKifY eKf8t+fdU4TjpSm77cikWS/LfknOvsrXOYv9Su7LHcaDVAOgXlCvhnupRd4NuqPBCi 2magLQ7eBIrOkcuu67Kcuu+sPEDLiI7/qXktP63Y= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 26/36] media: add V4L2_SUBDEV_FL_MULTIPLEXED Date: Mon, 30 Aug 2021 14:01:06 +0300 Message-Id: <20210830110116.488338-27-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add subdev flag V4L2_SUBDEV_FL_MULTIPLEXED. It is used to indicate that the subdev supports the new API with multiplexed streams (routing, stream configs). TODO: describe better what the flag does. Signed-off-by: Tomi Valkeinen --- include/media/v4l2-subdev.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 1c022d1a6896..356901d8a948 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -890,6 +890,12 @@ struct v4l2_subdev_internal_ops { * should set this flag. */ #define V4L2_SUBDEV_FL_HAS_EVENTS (1U << 3) +/* + * Set this flag if this subdev supports multiplexed streams. This means + * that the driver supports routing and handles the stream parameter in its + * v4l2_subdev_pad_ops handlers. + */ +#define V4L2_SUBDEV_FL_MULTIPLEXED (1U << 4) struct regulator_bulk_data; From patchwork Mon Aug 30 11:01:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504489 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC77AC432BE for ; Mon, 30 Aug 2021 11:02:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C46306113A for ; Mon, 30 Aug 2021 11:02:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236524AbhH3LDi (ORCPT ); Mon, 30 Aug 2021 07:03:38 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236475AbhH3LDb (ORCPT ); Mon, 30 Aug 2021 07:03:31 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EE74C1279; Mon, 30 Aug 2021 13:02:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321354; bh=QttCyilsiZwzZ7mjxXKBD0+RCLxpBaUEnNR0LESgvAs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TAThtMlWCNJBz43mBWajrMmxVMuzYU+R0FyoKn2TkSdRF9R2O3QBoq6Ytxi5Ky8ko vUpiPcaV4zzxFwf9kX1vT3Wm1dUn37viZ1qgz0X5wv26y957UPWw+1jp3mlSDhVaNL vBAxtsUFvLc3MCZqfOhg42m3oZWNOr5wbSd8EveI= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 27/36] media: Documentation: Add GS_ROUTING documentation Date: Mon, 30 Aug 2021 14:01:07 +0300 Message-Id: <20210830110116.488338-28-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Jacopo Mondi Add documentation for VIDIOC_SUBDEV_G/S_ROUTING ioctl and add description of multiplexed media pads and internal routing to the V4L2-subdev documentation section. Signed-off-by: Jacopo Mondi Signed-off-by: Tomi Valkeinen --- .../userspace-api/media/v4l/dev-subdev.rst | 2 + .../userspace-api/media/v4l/user-func.rst | 1 + .../media/v4l/vidioc-subdev-g-routing.rst | 146 ++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst diff --git a/Documentation/userspace-api/media/v4l/dev-subdev.rst b/Documentation/userspace-api/media/v4l/dev-subdev.rst index fd1de0a73a9f..a67c2749089a 100644 --- a/Documentation/userspace-api/media/v4l/dev-subdev.rst +++ b/Documentation/userspace-api/media/v4l/dev-subdev.rst @@ -29,6 +29,8 @@ will feature a character device node on which ioctls can be called to - negotiate image formats on individual pads +- inspect and modify internal data routing between pads of the same entity + Sub-device character device nodes, conventionally named ``/dev/v4l-subdev*``, use major number 81. diff --git a/Documentation/userspace-api/media/v4l/user-func.rst b/Documentation/userspace-api/media/v4l/user-func.rst index 53e604bd7d60..228c1521f190 100644 --- a/Documentation/userspace-api/media/v4l/user-func.rst +++ b/Documentation/userspace-api/media/v4l/user-func.rst @@ -70,6 +70,7 @@ Function Reference vidioc-subdev-g-crop vidioc-subdev-g-fmt vidioc-subdev-g-frame-interval + vidioc-subdev-g-routing vidioc-subdev-g-selection vidioc-subdev-querycap vidioc-subscribe-event diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst new file mode 100644 index 000000000000..41f4873c49f7 --- /dev/null +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-routing.rst @@ -0,0 +1,146 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: V4L + +.. _VIDIOC_SUBDEV_G_ROUTING: + +****************************************************** +ioctl VIDIOC_SUBDEV_G_ROUTING, VIDIOC_SUBDEV_S_ROUTING +****************************************************** + +Name +==== + +VIDIOC_SUBDEV_G_ROUTING - VIDIOC_SUBDEV_S_ROUTING - Get or set routing between streams of media pads in a media entity. + + +Synopsis +======== + +.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_G_ROUTING, struct v4l2_subdev_routing *argp ) + :name: VIDIOC_SUBDEV_G_ROUTING + +.. c:function:: int ioctl( int fd, VIDIOC_SUBDEV_S_ROUTING, struct v4l2_subdev_routing *argp ) + :name: VIDIOC_SUBDEV_S_ROUTING + + +Arguments +========= + +``fd`` + File descriptor returned by :ref:`open() `. + +``argp`` + Pointer to struct :c:type:`v4l2_subdev_routing`. + + +Description +=========== + +These ioctls are used to get and set the routing in a media entity. +The routing configuration determines the flows of data inside an entity. + +Drivers report their current routing tables using the +``VIDIOC_SUBDEV_G_ROUTING`` ioctl and application may enable or disable routes +with the VIDIOC_SUBDEV_S_ROUTING ioctl, by adding or removing routes and setting +or clearing the ``V4L2_SUBDEV_ROUTE_FL_ACTIVE`` flag of the ``flags`` field of +a struct :c:type:`v4l2_subdev_route`. + +A special case for routing are routes marked with +``V4L2_SUBDEV_ROUTE_FL_SOURCE`` flag. These routes are used to describe +source endpoints on sensors and the sink fields are unused. + +When inspecting routes through VIDIOC_SUBDEV_G_ROUTING and the application +provided ``num_routes`` is not big enough to contain all the available routes +the subdevice exposes, drivers return the ENOSPC error code and adjust the +value of the ``num_routes`` field. Application should then reserve enough memory +for all the route entries and call VIDIOC_SUBDEV_G_ROUTING again. + +.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| + +.. c:type:: v4l2_subdev_routing + +.. flat-table:: struct v4l2_subdev_routing + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u32 + - ``which`` + - Format to modified, from enum + :ref:`v4l2_subdev_format_whence `. + * - struct :c:type:`v4l2_subdev_route` + - ``routes[]`` + - Array of struct :c:type:`v4l2_subdev_route` entries + * - __u32 + - ``num_routes`` + - Number of entries of the routes array + * - __u32 + - ``reserved``\ [5] + - Reserved for future extensions. Applications and drivers must set + the array to zero. + +.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| + +.. c:type:: v4l2_subdev_route + +.. flat-table:: struct v4l2_subdev_route + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u32 + - ``sink_pad`` + - Sink pad number. + * - __u32 + - ``sink_stream`` + - Sink pad stream number. + * - __u32 + - ``source_pad`` + - Source pad number. + * - __u32 + - ``source_stream`` + - Source pad stream number. + * - __u32 + - ``flags`` + - Route enable/disable flags + :ref:`v4l2_subdev_routing_flags `. + * - __u32 + - ``reserved``\ [5] + - Reserved for future extensions. Applications and drivers must set + the array to zero. + +.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| + +.. _v4l2-subdev-routing-flags: + +.. flat-table:: enum v4l2_subdev_routing_flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * - V4L2_SUBDEV_ROUTE_FL_ACTIVE + - 0 + - The route is enabled. Set by applications. + * - V4L2_SUBDEV_ROUTE_FL_IMMUTABLE + - 1 + - The route is immutable. Set by the driver. + * - V4L2_SUBDEV_ROUTE_FL_SOURCE + - 2 + - The route is a source route, and the ``sink_pad`` and ``sink_stream`` + fields are unused. Set by the driver. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + +ENOSPC + The number of provided route entries is less than the available ones. + +EINVAL + The sink or source pad identifiers reference a non-existing pad, or reference + pads of different types (ie. the sink_pad identifiers refers to a source pad) + or the sink or source stream identifiers reference a non-existing stream on + the sink or source pad. From patchwork Mon Aug 30 11:01:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504813 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7E812C4320A for ; Mon, 30 Aug 2021 11:02:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 67C1861107 for ; Mon, 30 Aug 2021 11:02:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236526AbhH3LDi (ORCPT ); Mon, 30 Aug 2021 07:03:38 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236499AbhH3LDb (ORCPT ); Mon, 30 Aug 2021 07:03:31 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CBC951334; Mon, 30 Aug 2021 13:02:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321355; bh=EbsfLns6mOud+vDirT94ApJHWYd+qNYRLndY/cgzwos=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iNbyqYNrk+IIeqb1D3sACyTvqZeSSV+8viyqdI0s6np3Nx8QU3fQySJoGvpJAVvEu BOHIT9399kIFGUvp6fp+mHaEbH7NwyVgTvl3SMPl5STQP3cfOaqsiQM0l/NJWkXVe3 eZvkWmUaPcgNcaGyKNs8jEhhqc2jq+3BvPLa5CFY= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla , Michal Simek Subject: [PATCH v8 28/36] media: subdev: Add [GS]_ROUTING subdev ioctls and operations Date: Mon, 30 Aug 2021 14:01:08 +0300 Message-Id: <20210830110116.488338-29-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Laurent Pinchart Add support for subdev internal routing. A route is defined as a single stream from a sink pad to a source pad. The userspace can configure the routing via two new ioctls, VIDIOC_SUBDEV_G_ROUTING and VIDIOC_SUBDEV_S_ROUTING, and subdevs can implement the functionality with v4l2_subdev_pad_ops.set_routing(). Signed-off-by: Laurent Pinchart Signed-off-by: Michal Simek - Add sink and source streams for multiplexed links - Copy the argument back in case of an error. This is needed to let the caller know the number of routes. Signed-off-by: Sakari Ailus - Expand and refine documentation. - Make the 'routes' pointer a __u64 __user pointer so that a compat32 version of the ioctl is not required. - Add struct v4l2_subdev_krouting to be used for subdevice operations. Signed-off-by: Jacopo Mondi - Fix typecasing warnings - Check sink & source pad types - Add 'which' field - Add V4L2_SUBDEV_ROUTE_FL_SOURCE - Routing to subdev state - Dropped get_routing subdev op Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-ioctl.c | 25 ++++++++- drivers/media/v4l2-core/v4l2-subdev.c | 75 +++++++++++++++++++++++++++ include/media/v4l2-subdev.h | 24 +++++++++ include/uapi/linux/v4l2-subdev.h | 57 ++++++++++++++++++++ 4 files changed, 180 insertions(+), 1 deletion(-) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 05d5db3d85e5..8e9315ffcb99 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -3065,6 +3066,21 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, ret = 1; break; } + + case VIDIOC_SUBDEV_G_ROUTING: + case VIDIOC_SUBDEV_S_ROUTING: { + struct v4l2_subdev_routing *routing = parg; + + if (routing->num_routes > 256) + return -EINVAL; + + *user_ptr = u64_to_user_ptr(routing->routes); + *kernel_ptr = (void **)&routing->routes; + *array_size = sizeof(struct v4l2_subdev_route) + * routing->num_routes; + ret = 1; + break; + } } return ret; @@ -3328,8 +3344,15 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg, /* * Some ioctls can return an error, but still have valid * results that must be returned. + * + * FIXME: subdev IOCTLS are partially handled here and partially in + * v4l2-subdev.c and the 'always_copy' flag can only be set for IOCTLS + * defined here as part of the 'v4l2_ioctls' array. As + * VIDIOC_SUBDEV_G_ROUTING needs to return results to applications even + * in case of failure, but it is not defined here as part of the + * 'v4l2_ioctls' array, insert an ad-hoc check to address that. */ - if (err < 0 && !always_copy) + if (err < 0 && !always_copy && cmd != VIDIOC_SUBDEV_G_ROUTING) goto out; out_array_args: diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b1e65488210d..0e1f325b3159 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -395,6 +395,12 @@ subdev_ioctl_get_state(struct v4l2_subdev *sd, struct v4l2_subdev_fh *subdev_fh, which = ((struct v4l2_subdev_selection *)arg)->which; break; } + + case VIDIOC_SUBDEV_G_ROUTING: + case VIDIOC_SUBDEV_S_ROUTING: { + which = ((struct v4l2_subdev_routing *)arg)->which; + break; + } } return which == V4L2_SUBDEV_FORMAT_TRY ? @@ -711,6 +717,74 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_SUBDEV_QUERYSTD: return v4l2_subdev_call(sd, video, querystd, arg); + case VIDIOC_SUBDEV_G_ROUTING: { + struct v4l2_subdev_routing *routing = arg; + struct v4l2_subdev_krouting *krouting; + + if (!(sd->flags & V4L2_SUBDEV_FL_MULTIPLEXED)) + return -ENOIOCTLCMD; + + memset(routing->reserved, 0, sizeof(routing->reserved)); + + krouting = &state->routing; + + if (routing->num_routes < krouting->num_routes) { + routing->num_routes = krouting->num_routes; + return -ENOSPC; + } + + memcpy((struct v4l2_subdev_route *)(uintptr_t)routing->routes, + krouting->routes, + krouting->num_routes * sizeof(*krouting->routes)); + routing->num_routes = krouting->num_routes; + + return 0; + } + + case VIDIOC_SUBDEV_S_ROUTING: { + struct v4l2_subdev_routing *routing = arg; + struct v4l2_subdev_route *routes = + (struct v4l2_subdev_route *)(uintptr_t)routing->routes; + struct v4l2_subdev_krouting krouting = {}; + unsigned int i; + + if (!(sd->flags & V4L2_SUBDEV_FL_MULTIPLEXED)) + return -ENOIOCTLCMD; + + if (routing->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev) + return -EPERM; + + memset(routing->reserved, 0, sizeof(routing->reserved)); + + for (i = 0; i < routing->num_routes; ++i) { + const struct v4l2_subdev_route *route = &routes[i]; + const struct media_pad *pads = sd->entity.pads; + + /* Do not check sink pad for source routes */ + if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_SOURCE)) { + if (route->sink_pad >= sd->entity.num_pads) + return -EINVAL; + + if (!(pads[route->sink_pad].flags & + MEDIA_PAD_FL_SINK)) + return -EINVAL; + } + + if (route->source_pad >= sd->entity.num_pads) + return -EINVAL; + + if (!(pads[route->source_pad].flags & + MEDIA_PAD_FL_SOURCE)) + return -EINVAL; + } + + krouting.which = routing->which; + krouting.num_routes = routing->num_routes; + krouting.routes = routes; + + return v4l2_subdev_call(sd, pad, set_routing, state, &krouting); + } + default: return v4l2_subdev_call(sd, core, ioctl, cmd, arg); } @@ -975,6 +1049,7 @@ void v4l2_free_subdev_state(struct v4l2_subdev_state *state) mutex_destroy(&state->lock); + kvfree(state->routing.routes); kvfree(state->pads); kfree(state); } diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 356901d8a948..cd6aad21ae0c 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -694,12 +694,29 @@ struct v4l2_subdev_pad_config { struct v4l2_rect try_compose; }; +/** + * struct v4l2_subdev_krouting - subdev routing table + * + * @which: format type (from enum v4l2_subdev_format_whence) + * @routes: &struct v4l2_subdev_route + * @num_routes: number of routes + * + * This structure is used to translate arguments received from + * VIDIOC_SUBDEV_G/S_ROUTING() ioctl to subdev device drivers operations. + */ +struct v4l2_subdev_krouting { + u32 which; + struct v4l2_subdev_route *routes; + unsigned int num_routes; +}; + /** * struct v4l2_subdev_state - Used for storing subdev state information. * * @lock: mutex for the state * @which: state type (from enum v4l2_subdev_format_whence) * @pads: &struct v4l2_subdev_pad_config array + * @routing: routing table for the subdev * * This structure only needs to be passed to the pad op if the 'which' field * of the main argument is set to %V4L2_SUBDEV_FORMAT_TRY. For @@ -709,6 +726,7 @@ struct v4l2_subdev_state { struct mutex lock; u32 which; struct v4l2_subdev_pad_config *pads; + struct v4l2_subdev_krouting routing; }; /** @@ -772,6 +790,9 @@ struct v4l2_subdev_state { * applied to the hardware. The operation shall fail if the * pad index it has been called on is not valid or in case of * unrecoverable failures. + * + * @set_routing: enable or disable data connection routes described in the + * subdevice routing table. */ struct v4l2_subdev_pad_ops { int (*init_cfg)(struct v4l2_subdev *sd, @@ -816,6 +837,9 @@ struct v4l2_subdev_pad_ops { struct v4l2_mbus_config *config); int (*set_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_config *config); + int (*set_routing)(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *route); }; /** diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index 658106f5b5dc..3aa623e0e5f9 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h @@ -188,6 +188,61 @@ struct v4l2_subdev_capability { /* The v4l2 sub-device video device node is registered in read-only mode. */ #define V4L2_SUBDEV_CAP_RO_SUBDEV 0x00000001 +/* + * Is the route active? An active route will start when streaming is enabled + * on a video node. + */ +#define V4L2_SUBDEV_ROUTE_FL_ACTIVE BIT(0) + +/* + * Is the route immutable, i.e. can it be activated and inactivated? + * Set by the driver. + */ +#define V4L2_SUBDEV_ROUTE_FL_IMMUTABLE BIT(1) + +/* + * Is the route a source endpoint? A source endpoint route refers to a stream + * generated internally by the subdevice (usually a sensor), and thus there + * is no sink-side endpoint for the route. The sink_pad and sink_stream + * fields are unused. + * Set by the driver. + */ +#define V4L2_SUBDEV_ROUTE_FL_SOURCE BIT(2) + +/** + * struct v4l2_subdev_route - A route inside a subdev + * + * @sink_pad: the sink pad index + * @sink_stream: the sink stream identifier + * @source_pad: the source pad index + * @source_stream: the source stream identifier + * @flags: route flags V4L2_SUBDEV_ROUTE_FL_* + * @reserved: drivers and applications must zero this array + */ +struct v4l2_subdev_route { + __u32 sink_pad; + __u32 sink_stream; + __u32 source_pad; + __u32 source_stream; + __u32 flags; + __u32 reserved[5]; +}; + +/** + * struct v4l2_subdev_routing - Subdev routing information + * + * @which: configuration type (from enum v4l2_subdev_format_whence) + * @routes: pointer to the routes array + * @num_routes: the total number of routes in the routes array + * @reserved: drivers and applications must zero this array + */ +struct v4l2_subdev_routing { + __u32 which; + __u64 routes; + __u32 num_routes; + __u32 reserved[5]; +}; + /* Backwards compatibility define --- to be removed */ #define v4l2_subdev_edid v4l2_edid @@ -203,6 +258,8 @@ struct v4l2_subdev_capability { #define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) #define VIDIOC_SUBDEV_G_SELECTION _IOWR('V', 61, struct v4l2_subdev_selection) #define VIDIOC_SUBDEV_S_SELECTION _IOWR('V', 62, struct v4l2_subdev_selection) +#define VIDIOC_SUBDEV_G_ROUTING _IOWR('V', 38, struct v4l2_subdev_routing) +#define VIDIOC_SUBDEV_S_ROUTING _IOWR('V', 39, struct v4l2_subdev_routing) /* The following ioctls are identical to the ioctls in videodev2.h */ #define VIDIOC_SUBDEV_G_STD _IOR('V', 23, v4l2_std_id) #define VIDIOC_SUBDEV_S_STD _IOW('V', 24, v4l2_std_id) From patchwork Mon Aug 30 11:01:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504488 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8EC2C19F3A for ; Mon, 30 Aug 2021 11:02:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D4A386113A for ; Mon, 30 Aug 2021 11:02:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236534AbhH3LDj (ORCPT ); Mon, 30 Aug 2021 07:03:39 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236505AbhH3LDc (ORCPT ); Mon, 30 Aug 2021 07:03:32 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B3A63237E; Mon, 30 Aug 2021 13:02:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321356; bh=zJ6zupZ20SJEAwDDZfm9lvG5CMwc9AYBmK3WeT9+rIs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j7pVswcq6KB0NidE67XJRXgovb+zM3783/ZXu+LaPnxgBwS0OU0ZkGbkhjSmGJdEw Oh/5V7b/KcKVnhk6xbn8vEIVMpglCOV5Q+n9Z2MTelrFFIDW/vyoFPZZb8W2RbyypK MfTCjeJZdeYr4BAWiyV901ojwSvh69mG/FPAOd5I= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 29/36] media: subdev: add v4l2_subdev_has_route() Date: Mon, 30 Aug 2021 14:01:09 +0300 Message-Id: <20210830110116.488338-30-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add a v4l2_subdev_has_route() helper function which can be used for media_entity_operations.has_route op. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 30 +++++++++++++++++++++++++++ include/media/v4l2-subdev.h | 16 ++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 0e1f325b3159..7497ad0f6024 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -999,6 +999,36 @@ int v4l2_subdev_link_validate(struct media_link *link) } EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); +bool v4l2_subdev_has_route(struct media_entity *entity, unsigned int pad0, unsigned int pad1) +{ + struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); + struct v4l2_subdev_krouting *routing; + unsigned int i; + struct v4l2_subdev_state *state; + + state = v4l2_subdev_lock_active_state(sd); + + routing = &state->routing; + + for (i = 0; i < routing->num_routes; ++i) { + struct v4l2_subdev_route *route = &routing->routes[i]; + + if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) + continue; + + if ((route->sink_pad == pad0 && route->source_pad == pad1) || + (route->source_pad == pad0 && route->sink_pad == pad1)) { + v4l2_subdev_unlock_state(state); + return true; + } + } + + v4l2_subdev_unlock_state(state); + + return false; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_has_route); + struct v4l2_subdev_state * __v4l2_alloc_subdev_state(struct v4l2_subdev *sd, enum v4l2_subdev_format_whence which, diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index cd6aad21ae0c..858e18aa5b20 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1213,6 +1213,22 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, */ int v4l2_subdev_link_validate(struct media_link *link); +/** + * v4l2_subdev_has_route - MC has_route implementation for subdevs + * + * @entity: pointer to &struct media_entity + * @pad0: pad number for the first pad + * @pad1: pad number for the second pad + * + * This function looks at the routing in subdev's active state and returns if + * there is a route connecting pad0 and pad1. + * + * This function can be used as implementation for + * media_entity_operations.has_route. + */ +bool v4l2_subdev_has_route(struct media_entity *entity, unsigned int pad0, + unsigned int pad1); + /** * v4l2_alloc_subdev_state - allocate v4l2_subdev_state * From patchwork Mon Aug 30 11:01:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504812 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70E1FC43214 for ; Mon, 30 Aug 2021 11:02:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 574B96112F for ; Mon, 30 Aug 2021 11:02:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236537AbhH3LDj (ORCPT ); Mon, 30 Aug 2021 07:03:39 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236507AbhH3LDc (ORCPT ); Mon, 30 Aug 2021 07:03:32 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 92086146F; Mon, 30 Aug 2021 13:02:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321357; bh=Kdf3da2fMbLmRAXhbg5z4fZfZo36UQWwd8a84GIbNZg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XTPRy+gxM/zYz+xLqIJEmWY+5eyjvKgsijcDrR6FnAZbFawCsBqT0r8WnevdMMG7T 59G27uflua3o2lASIXaNRlqjbR7sZ5IpJ+u7c0YUkMDB29JNgGnpGa6KIxSH8VMlWE NlxqnEew5y3P0vytfW478uhrcM24Ii/gigM5bXmQ= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 30/36] media: subdev: add v4l2_subdev_set_routing helper() Date: Mon, 30 Aug 2021 14:01:10 +0300 Message-Id: <20210830110116.488338-31-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add a helper function to set the subdev routing. The helper can be used from subdev driver's set_routing op to store the routing table. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 31 +++++++++++++++++++++++++++ include/media/v4l2-subdev.h | 16 ++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 7497ad0f6024..eb1103afbfbc 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -1155,3 +1155,34 @@ void v4l2_subdev_unlock_state(struct v4l2_subdev_state *state) mutex_unlock(&state->lock); } EXPORT_SYMBOL_GPL(v4l2_subdev_unlock_state); + +int v4l2_subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *routing) +{ + struct v4l2_subdev_krouting *dst = &state->routing; + const struct v4l2_subdev_krouting *src = routing; + + lockdep_assert_held(&state->lock); + + kvfree(dst->routes); + dst->routes = NULL; + dst->num_routes = 0; + + if (src->num_routes == 0) { + dst->which = src->which; + } else { + dst->routes = kvmalloc_array(src->num_routes, sizeof(*src->routes), + GFP_KERNEL); + if (!dst->routes) + return -ENOMEM; + + memcpy(dst->routes, src->routes, + src->num_routes * sizeof(*src->routes)); + dst->num_routes = src->num_routes; + dst->which = src->which; + } + + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 858e18aa5b20..90e9fda6babb 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1436,4 +1436,20 @@ v4l2_subdev_validate_and_lock_state(struct v4l2_subdev *sd, return state; } +/** + * v4l2_subdev_set_routing() - Set given routing to subdev state + * @sd: The subdevice + * @state: The subdevice state + * @routing: Routing that will be copied to subdev state + * + * This will release old routing table (if any) from the state, allocate + * enough space for the given routing, and copy the routing. + * + * This can be used from the subdev driver's set_routing op, after validating + * the routing. + */ +int v4l2_subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *routing); + #endif From patchwork Mon Aug 30 11:01:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504487 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EDAD3C432BE for ; Mon, 30 Aug 2021 11:02:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D977C61102 for ; Mon, 30 Aug 2021 11:02:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236527AbhH3LDk (ORCPT ); Mon, 30 Aug 2021 07:03:40 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236511AbhH3LDd (ORCPT ); Mon, 30 Aug 2021 07:03:33 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6FFAB5A7; Mon, 30 Aug 2021 13:02:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321358; bh=QWFi3+Z4ec8n5lrgrBbbwQ/922FMwz8BNjA5XAjtoCU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YQMJ3EiPiOlYuWQpBok5YtoH34cwZZ2lQf0ZNNJ9piflmeCDYqvQCke/EaZDDTS3M nPWRr9Eh45whiYbOo92RMXpJrELHvAtuXJAsFoyCatigiDo1ExAj/A0uQMDR3B+bUG fIrYLA09Hyd5S1OJCb7QCZNWiVbt4zvZ3GFYgPRo= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 31/36] media: subdev: add stream based configuration Date: Mon, 30 Aug 2021 14:01:11 +0300 Message-Id: <20210830110116.488338-32-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add support to manage configurations (format, crop, compose) per stream, instead of per pad. This is accomplished with data structures that hold an array of all subdev's stream configurations. The number of streams can vary at runtime based on routing. Every time the routing is changed, the stream configurations need to be re-initialized. Signed-off-by: Tomi Valkeinen --- .../v4l/vidioc-subdev-enum-frame-interval.rst | 5 +- .../v4l/vidioc-subdev-enum-frame-size.rst | 5 +- .../v4l/vidioc-subdev-enum-mbus-code.rst | 5 +- .../media/v4l/vidioc-subdev-g-crop.rst | 5 +- .../media/v4l/vidioc-subdev-g-fmt.rst | 5 +- .../v4l/vidioc-subdev-g-frame-interval.rst | 5 +- .../media/v4l/vidioc-subdev-g-selection.rst | 5 +- drivers/media/v4l2-core/v4l2-subdev.c | 136 ++++++++++++++++-- include/media/v4l2-subdev.h | 48 +++++++ include/uapi/linux/v4l2-subdev.h | 28 +++- 10 files changed, 225 insertions(+), 22 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-interval.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-interval.rst index 3703943b412f..8def4c05d3da 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-interval.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-interval.rst @@ -92,7 +92,10 @@ multiple pads of the same sub-device is not defined. - Frame intervals to be enumerated, from enum :ref:`v4l2_subdev_format_whence `. * - __u32 - - ``reserved``\ [8] + - ``stream`` + - Stream identifier. + * - __u32 + - ``reserved``\ [7] - Reserved for future extensions. Applications and drivers must set the array to zero. diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst index c25a9896df0e..3ef361c0dca7 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-frame-size.rst @@ -97,7 +97,10 @@ information about try formats. - Frame sizes to be enumerated, from enum :ref:`v4l2_subdev_format_whence `. * - __u32 - - ``reserved``\ [8] + - ``stream`` + - Stream identifier. + * - __u32 + - ``reserved``\ [7] - Reserved for future extensions. Applications and drivers must set the array to zero. diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst index 417f1a19bcc4..248f6f9ee7c5 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst @@ -73,7 +73,10 @@ information about the try formats. - ``flags`` - See :ref:`v4l2-subdev-mbus-code-flags` * - __u32 - - ``reserved``\ [7] + - ``stream`` + - Stream identifier. + * - __u32 + - ``reserved``\ [6] - Reserved for future extensions. Applications and drivers must set the array to zero. diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-crop.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-crop.rst index bd15c0a5a66b..1d267f7e7991 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-crop.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-crop.rst @@ -96,7 +96,10 @@ modified format should be as close as possible to the original request. - ``rect`` - Crop rectangle boundaries, in pixels. * - __u32 - - ``reserved``\ [8] + - ``stream`` + - Stream identifier. + * - __u32 + - ``reserved``\ [7] - Reserved for future extensions. Applications and drivers must set the array to zero. diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-fmt.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-fmt.rst index 7acdbb939d89..ed253a1e44b7 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-fmt.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-fmt.rst @@ -102,7 +102,10 @@ should be as close as possible to the original request. - Definition of an image format, see :c:type:`v4l2_mbus_framefmt` for details. * - __u32 - - ``reserved``\ [8] + - ``stream`` + - Stream identifier. + * - __u32 + - ``reserved``\ [7] - Reserved for future extensions. Applications and drivers must set the array to zero. diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-frame-interval.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-frame-interval.rst index d7fe7543c506..842f962d2aea 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-frame-interval.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-frame-interval.rst @@ -90,7 +90,10 @@ the same sub-device is not defined. - ``interval`` - Period, in seconds, between consecutive video frames. * - __u32 - - ``reserved``\ [9] + - ``stream`` + - Stream identifier. + * - __u32 + - ``reserved``\ [8] - Reserved for future extensions. Applications and drivers must set the array to zero. diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-selection.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-selection.rst index f9172a42f036..6b629c19168c 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-g-selection.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-g-selection.rst @@ -94,7 +94,10 @@ Selection targets and flags are documented in - ``r`` - Selection rectangle, in pixels. * - __u32 - - ``reserved``\ [8] + - ``stream`` + - Stream identifier. + * - __u32 + - ``reserved``\ [7] - Reserved for future extensions. Applications and drivers must set the array to zero. diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index eb1103afbfbc..3df30e7e0fef 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -150,14 +150,45 @@ static inline int check_pad(struct v4l2_subdev *sd, u32 pad) return 0; } -static int check_state_pads(u32 which, struct v4l2_subdev_state *state) +static int check_state_pads(struct v4l2_subdev *sd, u32 which, + struct v4l2_subdev_state *state) { + if (sd->flags & V4L2_SUBDEV_FL_MULTIPLEXED) + return 0; + if (which == V4L2_SUBDEV_FORMAT_TRY && (!state || !state->pads)) return -EINVAL; return 0; } +static int check_state_pad_stream(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, u32 pad, + u32 stream) +{ + struct v4l2_mbus_framefmt *fmt; + + if (!(sd->flags & V4L2_SUBDEV_FL_MULTIPLEXED)) + return 0; + + /* + * We need to take the state lock to access the format, but as we then + * have to unlock, nothing prevents someone changing the state before + * this call thread enters the driver's op and the driver has the + * change to lock the state. + */ + v4l2_subdev_lock_state(state); + + fmt = v4l2_state_get_stream_format(state, pad, stream); + + v4l2_subdev_unlock_state(state); + + if (!fmt) + return -EINVAL; + + return 0; +} + static inline int check_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) @@ -166,7 +197,8 @@ static inline int check_format(struct v4l2_subdev *sd, return -EINVAL; return check_which(format->which) ? : check_pad(sd, format->pad) ? : - check_state_pads(format->which, state); + check_state_pads(sd, format->which, state) ? : + check_state_pad_stream(sd, state, format->pad, format->stream); } static int call_get_fmt(struct v4l2_subdev *sd, @@ -193,7 +225,8 @@ static int call_enum_mbus_code(struct v4l2_subdev *sd, return -EINVAL; return check_which(code->which) ? : check_pad(sd, code->pad) ? : - check_state_pads(code->which, state) ? : + check_state_pads(sd, code->which, state) ? : + check_state_pad_stream(sd, state, code->pad, code->stream) ? : sd->ops->pad->enum_mbus_code(sd, state, code); } @@ -205,7 +238,8 @@ static int call_enum_frame_size(struct v4l2_subdev *sd, return -EINVAL; return check_which(fse->which) ? : check_pad(sd, fse->pad) ? : - check_state_pads(fse->which, state) ? : + check_state_pads(sd, fse->which, state) ? : + check_state_pad_stream(sd, state, fse->pad, fse->stream) ? : sd->ops->pad->enum_frame_size(sd, state, fse); } @@ -240,7 +274,8 @@ static int call_enum_frame_interval(struct v4l2_subdev *sd, return -EINVAL; return check_which(fie->which) ? : check_pad(sd, fie->pad) ? : - check_state_pads(fie->which, state) ? : + check_state_pads(sd, fie->which, state) ? : + check_state_pad_stream(sd, state, fie->pad, fie->stream) ? : sd->ops->pad->enum_frame_interval(sd, state, fie); } @@ -252,7 +287,8 @@ static inline int check_selection(struct v4l2_subdev *sd, return -EINVAL; return check_which(sel->which) ? : check_pad(sd, sel->pad) ? : - check_state_pads(sel->which, state); + check_state_pads(sd, sel->which, state) ? : + check_state_pad_stream(sd, state, sel->pad, sel->stream); } static int call_get_selection(struct v4l2_subdev *sd, @@ -868,6 +904,67 @@ const struct v4l2_file_operations v4l2_subdev_fops = { .poll = subdev_poll, }; +static int +v4l2_init_stream_configs(struct v4l2_subdev_stream_configs *stream_configs, + const struct v4l2_subdev_krouting *routing) +{ + u32 num_configs = 0; + unsigned int i; + u32 format_idx = 0; + + kvfree(stream_configs->configs); + stream_configs->configs = NULL; + stream_configs->num_configs = 0; + + /* Count number of formats needed */ + for (i = 0; i < routing->num_routes; ++i) { + struct v4l2_subdev_route *route = &routing->routes[i]; + + if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) + continue; + + /* + * Each route needs a format on both ends of the route, except for + * source streams which only need one format. + */ + num_configs += (route->flags & V4L2_SUBDEV_ROUTE_FL_SOURCE) ? 1 : 2; + } + + if (num_configs) { + stream_configs->configs = + kvcalloc(num_configs, sizeof(*stream_configs->configs), + GFP_KERNEL); + + if (!stream_configs->configs) + return -ENOMEM; + + stream_configs->num_configs = num_configs; + } + + /* Fill in the 'pad' and stream' value for each item in the array from the routing table */ + for (i = 0; i < routing->num_routes; ++i) { + struct v4l2_subdev_route *route = &routing->routes[i]; + u32 idx; + + if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) + continue; + + if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_SOURCE)) { + idx = format_idx++; + + stream_configs->configs[idx].pad = route->sink_pad; + stream_configs->configs[idx].stream = route->sink_stream; + } + + idx = format_idx++; + + stream_configs->configs[idx].pad = route->source_pad; + stream_configs->configs[idx].stream = route->source_stream; + } + + return 0; +} + #ifdef CONFIG_MEDIA_CONTROLLER int v4l2_subdev_get_fwnode_pad_1_to_1(struct media_entity *entity, @@ -1046,7 +1143,8 @@ __v4l2_alloc_subdev_state(struct v4l2_subdev *sd, state->which = which; - if (sd->entity.num_pads) { + /* Drivers that support streams do not need the legacy pad config */ + if (!(sd->flags & V4L2_SUBDEV_FL_MULTIPLEXED) && sd->entity.num_pads) { state->pads = kvmalloc_array(sd->entity.num_pads, sizeof(*state->pads), GFP_KERNEL | __GFP_ZERO); @@ -1080,6 +1178,7 @@ void v4l2_free_subdev_state(struct v4l2_subdev_state *state) mutex_destroy(&state->lock); kvfree(state->routing.routes); + kvfree(state->stream_configs.configs); kvfree(state->pads); kfree(state); } @@ -1183,6 +1282,27 @@ int v4l2_subdev_set_routing(struct v4l2_subdev *sd, dst->which = src->which; } - return 0; + return v4l2_init_stream_configs(&state->stream_configs, dst); } EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing); + +struct v4l2_mbus_framefmt * +v4l2_state_get_stream_format(struct v4l2_subdev_state *state, unsigned int pad, + u32 stream) +{ + struct v4l2_subdev_stream_configs *stream_configs; + unsigned int i; + + lockdep_assert_held(&state->lock); + + stream_configs = &state->stream_configs; + + for (i = 0; i < stream_configs->num_configs; ++i) { + if (stream_configs->configs[i].pad == pad && + stream_configs->configs[i].stream == stream) + return &stream_configs->configs[i].fmt; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(v4l2_state_get_stream_format); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 90e9fda6babb..5a2c7e2cb561 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -694,6 +694,37 @@ struct v4l2_subdev_pad_config { struct v4l2_rect try_compose; }; +/** + * struct v4l2_subdev_stream_config - Used for storing stream configuration. + * + * @pad: pad number + * @stream: stream number + * @fmt: &struct v4l2_mbus_framefmt + * @crop: &struct v4l2_rect to be used for crop + * @compose: &struct v4l2_rect to be used for compose + * + * This structure stores configuration for a stream. + */ +struct v4l2_subdev_stream_config { + u32 pad; + u32 stream; + + struct v4l2_mbus_framefmt fmt; + struct v4l2_rect crop; + struct v4l2_rect compose; +}; + +/** + * struct v4l2_subdev_stream_configs - A collection of stream configs. + * + * @num_configs: number of entries in @config. + * @configs: an array of &struct v4l2_subdev_stream_configs. + */ +struct v4l2_subdev_stream_configs { + u32 num_configs; + struct v4l2_subdev_stream_config *configs; +}; + /** * struct v4l2_subdev_krouting - subdev routing table * @@ -717,6 +748,7 @@ struct v4l2_subdev_krouting { * @which: state type (from enum v4l2_subdev_format_whence) * @pads: &struct v4l2_subdev_pad_config array * @routing: routing table for the subdev + * @stream_configs: stream configurations (only for V4L2_SUBDEV_FL_MULTIPLEXED) * * This structure only needs to be passed to the pad op if the 'which' field * of the main argument is set to %V4L2_SUBDEV_FORMAT_TRY. For @@ -727,6 +759,7 @@ struct v4l2_subdev_state { u32 which; struct v4l2_subdev_pad_config *pads; struct v4l2_subdev_krouting routing; + struct v4l2_subdev_stream_configs stream_configs; }; /** @@ -1452,4 +1485,19 @@ int v4l2_subdev_set_routing(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_krouting *routing); +/** + * v4l2_state_get_stream_format() - Get pointer to a stream format + * @state: subdevice state + * @pad: pad id + * @stream: stream id + * + * This returns a pointer to &struct v4l2_mbus_framefmt for the given pad + + * stream in the subdev state. + * + * If the state does not contain the given pad + stream, NULL is returned. + */ +struct v4l2_mbus_framefmt * +v4l2_state_get_stream_format(struct v4l2_subdev_state *state, unsigned int pad, + u32 stream); + #endif diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index 3aa623e0e5f9..d00ef85db1c7 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h @@ -44,13 +44,15 @@ enum v4l2_subdev_format_whence { * @which: format type (from enum v4l2_subdev_format_whence) * @pad: pad number, as reported by the media API * @format: media bus format (format code and frame size) + * @stream: stream number, defined in subdev routing * @reserved: drivers and applications must zero this array */ struct v4l2_subdev_format { __u32 which; __u32 pad; struct v4l2_mbus_framefmt format; - __u32 reserved[8]; + __u32 stream; + __u32 reserved[7]; }; /** @@ -58,13 +60,15 @@ struct v4l2_subdev_format { * @which: format type (from enum v4l2_subdev_format_whence) * @pad: pad number, as reported by the media API * @rect: pad crop rectangle boundaries + * @stream: stream number, defined in subdev routing * @reserved: drivers and applications must zero this array */ struct v4l2_subdev_crop { __u32 which; __u32 pad; struct v4l2_rect rect; - __u32 reserved[8]; + __u32 stream; + __u32 reserved[7]; }; #define V4L2_SUBDEV_MBUS_CODE_CSC_COLORSPACE 0x00000001 @@ -80,6 +84,7 @@ struct v4l2_subdev_crop { * @code: format code (MEDIA_BUS_FMT_ definitions) * @which: format type (from enum v4l2_subdev_format_whence) * @flags: flags set by the driver, (V4L2_SUBDEV_MBUS_CODE_*) + * @stream: stream number, defined in subdev routing * @reserved: drivers and applications must zero this array */ struct v4l2_subdev_mbus_code_enum { @@ -88,7 +93,8 @@ struct v4l2_subdev_mbus_code_enum { __u32 code; __u32 which; __u32 flags; - __u32 reserved[7]; + __u32 stream; + __u32 reserved[6]; }; /** @@ -101,6 +107,7 @@ struct v4l2_subdev_mbus_code_enum { * @min_height: minimum frame height, in pixels * @max_height: maximum frame height, in pixels * @which: format type (from enum v4l2_subdev_format_whence) + * @stream: stream number, defined in subdev routing * @reserved: drivers and applications must zero this array */ struct v4l2_subdev_frame_size_enum { @@ -112,19 +119,22 @@ struct v4l2_subdev_frame_size_enum { __u32 min_height; __u32 max_height; __u32 which; - __u32 reserved[8]; + __u32 stream; + __u32 reserved[7]; }; /** * struct v4l2_subdev_frame_interval - Pad-level frame rate * @pad: pad number, as reported by the media API * @interval: frame interval in seconds + * @stream: stream number, defined in subdev routing * @reserved: drivers and applications must zero this array */ struct v4l2_subdev_frame_interval { __u32 pad; struct v4l2_fract interval; - __u32 reserved[9]; + __u32 stream; + __u32 reserved[8]; }; /** @@ -136,6 +146,7 @@ struct v4l2_subdev_frame_interval { * @height: frame height in pixels * @interval: frame interval in seconds * @which: format type (from enum v4l2_subdev_format_whence) + * @stream: stream number, defined in subdev routing * @reserved: drivers and applications must zero this array */ struct v4l2_subdev_frame_interval_enum { @@ -146,7 +157,8 @@ struct v4l2_subdev_frame_interval_enum { __u32 height; struct v4l2_fract interval; __u32 which; - __u32 reserved[8]; + __u32 stream; + __u32 reserved[7]; }; /** @@ -158,6 +170,7 @@ struct v4l2_subdev_frame_interval_enum { * defined in v4l2-common.h; V4L2_SEL_TGT_* . * @flags: constraint flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*. * @r: coordinates of the selection window + * @stream: stream number, defined in subdev routing * @reserved: for future use, set to zero for now * * Hardware may use multiple helper windows to process a video stream. @@ -170,7 +183,8 @@ struct v4l2_subdev_selection { __u32 target; __u32 flags; struct v4l2_rect r; - __u32 reserved[8]; + __u32 stream; + __u32 reserved[7]; }; /** From patchwork Mon Aug 30 11:01:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504811 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6762C4320E for ; Mon, 30 Aug 2021 11:02:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B087361107 for ; Mon, 30 Aug 2021 11:02:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236540AbhH3LDm (ORCPT ); Mon, 30 Aug 2021 07:03:42 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236515AbhH3LDd (ORCPT ); Mon, 30 Aug 2021 07:03:33 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 525DA1489; Mon, 30 Aug 2021 13:02:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321359; bh=yWSraz2WWFSZNzAIH7wjvIl9XbdkuefMjpUviILceAU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UGFYdsKoj/eb+Gi14P88UnZ+YRTwVI2kKmxGN7u/1Jlq101IG/A8rP0tan7XPIXH+ GB/0PcJDB3jY9HWjfTZ1OXSSdcBWGZXEza7o0wy2VfNLfg+9Ux0gOtbREVQ+7DYrlH Ls9ta+a+9pUacfg/KdDlWSlYohuuwLVUZYa+I6eY= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 32/36] media: subdev: use streams in v4l2_subdev_link_validate() Date: Mon, 30 Aug 2021 14:01:12 +0300 Message-Id: <20210830110116.488338-33-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Update v4l2_subdev_link_validate() to use routing and streams for validation. Instead of just looking at the format on the pad on both ends of the link, the routing tables are used to collect all the streams going from the source to the sink over the link, and the streams' formats on both ends of the link are verified. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 217 +++++++++++++++++++++++--- 1 file changed, 199 insertions(+), 18 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 3df30e7e0fef..e8bfca595e11 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -1047,6 +1048,7 @@ EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default); static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, + u32 stream, struct v4l2_subdev_format *fmt) { if (is_media_entity_v4l2_subdev(pad->entity)) { @@ -1058,6 +1060,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad, fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; fmt->pad = pad->index; + fmt->stream = stream; return v4l2_subdev_call(sd, pad, get_fmt, state, fmt); } @@ -1068,31 +1071,209 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad, return -EINVAL; } -int v4l2_subdev_link_validate(struct media_link *link) +static int cmp_u32(const void *a, const void *b) { - struct v4l2_subdev *sink; - struct v4l2_subdev_format sink_fmt, source_fmt; - int rval; + u32 a32 = *(u32 *)a; + u32 b32 = *(u32 *)b; - rval = v4l2_subdev_link_validate_get_format( - link->source, &source_fmt); - if (rval < 0) - return 0; + return a32 > b32 ? 1 : (a32 < b32 ? -1 : 0); +} + +static int v4l2_link_validate_get_streams(struct media_link *link, + bool is_source, u32 *out_num_streams, + const u32 **out_streams, + bool *allocated) +{ + static const u32 default_streams[] = { 0 }; + struct v4l2_subdev_krouting *routing; + struct v4l2_subdev *subdev; + u32 num_streams; + u32 *streams; + unsigned int i; + struct v4l2_subdev_state *state; + + if (is_source) + subdev = media_entity_to_v4l2_subdev(link->source->entity); + else + subdev = media_entity_to_v4l2_subdev(link->sink->entity); - rval = v4l2_subdev_link_validate_get_format( - link->sink, &sink_fmt); - if (rval < 0) + if (!(subdev->flags & V4L2_SUBDEV_FL_MULTIPLEXED)) { + *out_num_streams = 1; + *out_streams = default_streams; + *allocated = false; return 0; + } - sink = media_entity_to_v4l2_subdev(link->sink->entity); + state = v4l2_subdev_lock_active_state(subdev); - rval = v4l2_subdev_call(sink, pad, link_validate, link, - &source_fmt, &sink_fmt); - if (rval != -ENOIOCTLCMD) - return rval; + routing = &state->routing; + + streams = kmalloc_array(routing->num_routes, sizeof(u32), GFP_KERNEL); + + if (!streams) { + v4l2_subdev_unlock_state(state); + return -ENOMEM; + } + + num_streams = 0; + + for (i = 0; i < routing->num_routes; ++i) { + struct v4l2_subdev_route *route = &routing->routes[i]; + int j; + u32 route_pad; + u32 route_stream; + u32 link_pad; + + if (is_source) { + route_pad = route->source_pad; + route_stream = route->source_stream; + link_pad = link->source->index; + } else { + route_pad = route->sink_pad; + route_stream = route->sink_stream; + link_pad = link->sink->index; + } + + if (!(route->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)) + continue; + + if (route_pad != link_pad) + continue; + + /* look for duplicates... */ + for (j = 0; j < num_streams; ++j) { + if (streams[j] == route_stream) + break; + } + + /* ...and drop the stream if we already have it */ + if (j != num_streams) + continue; + + streams[num_streams++] = route_stream; + } + + v4l2_subdev_unlock_state(state); + + sort(streams, num_streams, sizeof(u32), &cmp_u32, NULL); + + *out_num_streams = num_streams; + *out_streams = streams; + *allocated = true; - return v4l2_subdev_link_validate_default( - sink, link, &source_fmt, &sink_fmt); + return 0; +} + +int v4l2_subdev_link_validate(struct media_link *link) +{ + struct v4l2_subdev *sink_subdev = + media_entity_to_v4l2_subdev(link->sink->entity); + struct device *dev = sink_subdev->entity.graph_obj.mdev->dev; + u32 num_source_streams; + const u32 *source_streams; + bool source_allocated; + u32 num_sink_streams; + const u32 *sink_streams; + bool sink_allocated; + unsigned int sink_idx; + unsigned int source_idx; + int ret; + + dev_dbg(dev, "validating link \"%s\":%u -> \"%s\":%u\n", + link->source->entity->name, link->source->index, + link->sink->entity->name, link->sink->index); + + ret = v4l2_link_validate_get_streams(link, true, &num_source_streams, + &source_streams, + &source_allocated); + if (ret) + return ret; + + ret = v4l2_link_validate_get_streams(link, false, &num_sink_streams, + &sink_streams, &sink_allocated); + if (ret) + goto free_source; + + /* It is ok to have more source streams than sink streams */ + if (num_source_streams < num_sink_streams) { + dev_err(dev, + "Not enough source streams: %d < %d\n", + num_source_streams, num_sink_streams); + ret = -EINVAL; + goto out; + } + + /* Validate source and sink stream formats */ + + source_idx = 0; + + for (sink_idx = 0; sink_idx < num_sink_streams; ++sink_idx) { + struct v4l2_subdev_format sink_fmt, source_fmt; + u32 stream; + + stream = sink_streams[sink_idx]; + + for (; source_idx < num_source_streams; ++source_idx) { + if (source_streams[source_idx] == stream) + break; + } + + if (source_idx == num_source_streams) { + dev_err(dev, "No source stream for sink stream %u\n", + stream); + ret = -EINVAL; + goto out; + } + + dev_dbg(dev, "validating stream \"%s\":%u:%u -> \"%s\":%u:%u\n", + link->source->entity->name, link->source->index, stream, + link->sink->entity->name, link->sink->index, stream); + + ret = v4l2_subdev_link_validate_get_format(link->source, stream, + &source_fmt); + if (ret < 0) { + dev_dbg(dev, "Failed to get format for \"%s\":%u:%u (but that's ok)\n", + link->source->entity->name, link->source->index, + stream); + ret = 0; + continue; + } + + ret = v4l2_subdev_link_validate_get_format(link->sink, stream, + &sink_fmt); + if (ret < 0) { + dev_dbg(dev, "Failed to get format for \"%s\":%u:%u (but that's ok)\n", + link->sink->entity->name, link->sink->index, + stream); + ret = 0; + continue; + } + + /* TODO: add stream number to link_validate() */ + ret = v4l2_subdev_call(sink_subdev, pad, link_validate, link, + &source_fmt, &sink_fmt); + if (!ret) + continue; + + if (ret != -ENOIOCTLCMD) + goto out; + + ret = v4l2_subdev_link_validate_default(sink_subdev, link, + &source_fmt, &sink_fmt); + + if (ret) + goto out; + } + +out: + if (sink_allocated) + kfree(sink_streams); + +free_source: + if (source_allocated) + kfree(source_streams); + + return ret; } EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); From patchwork Mon Aug 30 11:01:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504810 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80CF8C4320A for ; Mon, 30 Aug 2021 11:02:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6AEC36112F for ; Mon, 30 Aug 2021 11:02:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236539AbhH3LDm (ORCPT ); Mon, 30 Aug 2021 07:03:42 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236520AbhH3LDe (ORCPT ); Mon, 30 Aug 2021 07:03:34 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2C87C156A; Mon, 30 Aug 2021 13:02:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321359; bh=AABiepMnXHGBVzO9AXWI5PWachgJarGqTETuT78lxGA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iRXz85GtcZA8sShq+2iv0xIYs6igQhcZlYiF/s4EZRYTGzz5jPB2Pli0fsjsYJpbR P0INQ6yNHnfBup5+0iTGFT+Nr7MsAS4iYE03FJ8FAL7/xXBE9DX7v9MQ/jrCTozuH5 XgP8V0u/3xoNov38xCYxYVAT1yadDEAr8Gj9PDvI= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 33/36] media: subdev: add "opposite" stream helper funcs Date: Mon, 30 Aug 2021 14:01:13 +0300 Message-Id: <20210830110116.488338-34-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add two helper functions to make dealing with streams easier: v4l2_state_find_opposite_end - given a routing table and a pad + stream, return the pad + stream on the opposite side of the subdev. v4l2_state_get_opposite_stream_format - return a pointer to the format on the pad + stream on the opposite side from the given pad + stream. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 42 +++++++++++++++++++++++++++ include/media/v4l2-subdev.h | 31 ++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index e8bfca595e11..68db3f23c256 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -1487,3 +1487,45 @@ v4l2_state_get_stream_format(struct v4l2_subdev_state *state, unsigned int pad, return NULL; } EXPORT_SYMBOL_GPL(v4l2_state_get_stream_format); + +int v4l2_state_find_opposite_end(struct v4l2_subdev_krouting *routing, u32 pad, + u32 stream, u32 *other_pad, u32 *other_stream) +{ + unsigned int i; + + for (i = 0; i < routing->num_routes; ++i) { + struct v4l2_subdev_route *route = &routing->routes[i]; + + if (route->source_pad == pad && + route->source_stream == stream) { + *other_pad = route->sink_pad; + *other_stream = route->sink_stream; + return 0; + } + + if (route->sink_pad == pad && route->sink_stream == stream) { + *other_pad = route->source_pad; + *other_stream = route->source_stream; + return 0; + } + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(v4l2_state_find_opposite_end); + +struct v4l2_mbus_framefmt * +v4l2_state_get_opposite_stream_format(struct v4l2_subdev_state *state, u32 pad, + u32 stream) +{ + u32 other_pad, other_stream; + int ret; + + ret = v4l2_state_find_opposite_end(&state->routing, pad, stream, + &other_pad, &other_stream); + if (ret) + return NULL; + + return v4l2_state_get_stream_format(state, other_pad, other_stream); +} +EXPORT_SYMBOL_GPL(v4l2_state_get_opposite_stream_format); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 5a2c7e2cb561..bc69123f71cb 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1500,4 +1500,35 @@ struct v4l2_mbus_framefmt * v4l2_state_get_stream_format(struct v4l2_subdev_state *state, unsigned int pad, u32 stream); +/** + * v4l2_state_find_opposite_end() - Find the opposite stream + * @routing: routing used to find the opposite side + * @pad: pad id + * @stream: stream id + * @other_pad: pointer used to return the opposite pad + * @other_stream: pointer used to return the opposite stream + * + * This function uses the routing table to find the pad + stream which is + * opposite the given pad + stream. + * + * Returns 0 on success, or -EINVAL if no matching route is found. + */ +int v4l2_state_find_opposite_end(struct v4l2_subdev_krouting *routing, u32 pad, + u32 stream, u32 *other_pad, u32 *other_stream); + +/** + * v4l2_state_get_opposite_stream_format() - Get pointer to opposite stream format + * @state: subdevice state + * @pad: pad id + * @stream: stream id + * + * This returns a pointer to &struct v4l2_mbus_framefmt for the pad + stream + * that is opposite the given pad + stream in the subdev state. + * + * If the state does not contain the given pad + stream, NULL is returned. + */ +struct v4l2_mbus_framefmt * +v4l2_state_get_opposite_stream_format(struct v4l2_subdev_state *state, u32 pad, + u32 stream); + #endif From patchwork Mon Aug 30 11:01:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504486 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BCC1C43216 for ; Mon, 30 Aug 2021 11:02:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 45A6561102 for ; Mon, 30 Aug 2021 11:02:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236538AbhH3LDn (ORCPT ); Mon, 30 Aug 2021 07:03:43 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236523AbhH3LDe (ORCPT ); Mon, 30 Aug 2021 07:03:34 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 060192461; Mon, 30 Aug 2021 13:02:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321360; bh=aUvCtcu2NZ4hs6j01pjqnkMqos5HeUeCNC8yv+lkiao=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pdNcRpwWBbBLduYFnFcDNYt+jX+fcE5gRpPjh1HBv3ULUUyIv6oxx5GCi1x4NMkqT ppFKyBUTJO+tUgaDjFvb3VsDV+A2t4EDts4oeRoPg2wkHMR2nzaMH52X7Diy9ov5GY 5mLfw0niBah5j19B92cmgjPQWTvwEjUEGSVLnYEw= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 34/36] media: subdev: add v4l2_subdev_get_fmt() helper function Date: Mon, 30 Aug 2021 14:01:14 +0300 Message-Id: <20210830110116.488338-35-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add v4l2_subdev_get_fmt() helper function which implements v4l2_subdev_pad_ops.get_fmt using streams. Subdev drivers that do not need to do anything special in their get_fmt op can use this helper directly for v4l2_subdev_pad_ops.get_fmt. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 21 +++++++++++++++++++++ include/media/v4l2-subdev.h | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 68db3f23c256..df3e376e439c 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -1529,3 +1529,24 @@ v4l2_state_get_opposite_stream_format(struct v4l2_subdev_state *state, u32 pad, return v4l2_state_get_stream_format(state, other_pad, other_stream); } EXPORT_SYMBOL_GPL(v4l2_state_get_opposite_stream_format); + +int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *fmt; + + v4l2_subdev_lock_state(state); + + fmt = v4l2_state_get_stream_format(state, format->pad, format->stream); + if (!fmt) { + v4l2_subdev_unlock_state(state); + return -EINVAL; + } + + format->format = *fmt; + + v4l2_subdev_unlock_state(state); + + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_get_fmt); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index bc69123f71cb..c3e859077557 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1530,5 +1530,21 @@ int v4l2_state_find_opposite_end(struct v4l2_subdev_krouting *routing, u32 pad, struct v4l2_mbus_framefmt * v4l2_state_get_opposite_stream_format(struct v4l2_subdev_state *state, u32 pad, u32 stream); +/** + * v4l2_subdev_get_fmt() - Fill format based on state + * @sd: subdevice + * @state: subdevice state + * @format: pointer to &struct v4l2_subdev_format + * + * Fill @format based on the pad and stream given in the @format struct. + * + * This function can be used by the subdev drivers to implement + * v4l2_subdev_pad_ops.get_fmt if the subdev driver does not need to do + * anything special in their get_fmt op. + * + * Returns 0 on success, error value otherwise. + */ +int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, + struct v4l2_subdev_format *format); #endif From patchwork Mon Aug 30 11:01:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504485 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04A64C432BE for ; Mon, 30 Aug 2021 11:02:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E4CDA61107 for ; Mon, 30 Aug 2021 11:02:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236520AbhH3LDo (ORCPT ); Mon, 30 Aug 2021 07:03:44 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43936 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236528AbhH3LDf (ORCPT ); Mon, 30 Aug 2021 07:03:35 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E869D247A; Mon, 30 Aug 2021 13:02:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321361; bh=eTbgt48ZKsQVDu9dp3vDLrw482Oirbwsxmw2HvheeUg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gTaMG0JQcIpO5LVl8rN8iEqxgJ3iKcnXO/t4dXKt50oE+hPE2Ufn02ejYqaM+JH+E L5UixDx5uy7K3uVUcn5KfIQCsslM0hwqDxnAvnsotR6tET2f+GXABhvKhFoFRCFmpD oc47Wv/ycJabVAhbNRJjssTM+VnbvXzWyHPOqWnk= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 35/36] media: subdev: add v4l2_subdev_set_routing_with_fmt() helper Date: Mon, 30 Aug 2021 14:01:15 +0300 Message-Id: <20210830110116.488338-36-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org v4l2_subdev_set_routing_with_fmt() is the same as v4l2_subdev_set_routing(), but additionally initializes all the streams with the given format. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 22 ++++++++++++++++++++++ include/media/v4l2-subdev.h | 15 +++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index df3e376e439c..83fa87e88bce 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -1467,6 +1467,28 @@ int v4l2_subdev_set_routing(struct v4l2_subdev *sd, } EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing); +int v4l2_subdev_set_routing_with_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *routing, + const struct v4l2_mbus_framefmt *fmt) +{ + struct v4l2_subdev_stream_configs *stream_configs; + unsigned int i; + int ret; + + ret = v4l2_subdev_set_routing(sd, state, routing); + if (ret) + return ret; + + stream_configs = &state->stream_configs; + + for (i = 0; i < stream_configs->num_configs; ++i) + stream_configs->configs[i].fmt = *fmt; + + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_subdev_set_routing_with_fmt); + struct v4l2_mbus_framefmt * v4l2_state_get_stream_format(struct v4l2_subdev_state *state, unsigned int pad, u32 stream) diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index c3e859077557..3f72c500ff6e 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1485,6 +1485,21 @@ int v4l2_subdev_set_routing(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_krouting *routing); +/** + * v4l2_subdev_set_routing_with_fmt() - Set given routing and format to subdev state + * @sd: The subdevice + * @state: The subdevice state + * @routing: Routing that will be copied to subdev state + * @fmt: Format used to initialize all the streams + * + * This is the same as v4l2_subdev_set_routing, but additionally initializes + * all the streams using the given format. + */ +int v4l2_subdev_set_routing_with_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_krouting *routing, + const struct v4l2_mbus_framefmt *fmt); + /** * v4l2_state_get_stream_format() - Get pointer to a stream format * @state: subdevice state From patchwork Mon Aug 30 11:01:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 504809 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 82B05C4320E for ; Mon, 30 Aug 2021 11:02:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7022761102 for ; Mon, 30 Aug 2021 11:02:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236542AbhH3LDo (ORCPT ); Mon, 30 Aug 2021 07:03:44 -0400 Received: from perceval.ideasonboard.com ([213.167.242.64]:43892 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236530AbhH3LDg (ORCPT ); Mon, 30 Aug 2021 07:03:36 -0400 Received: from deskari.lan (91-158-153-130.elisa-laajakaista.fi [91.158.153.130]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D088D1924; Mon, 30 Aug 2021 13:02:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1630321362; bh=pXHztcgMvIT5+m/DmHgFSB8IHvRQ4N3y2ytWJ/20IXw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DjSslXd5CIDhg29utY3asR86EkmRdlCuorNZAoNtCPBoaYUhG40DuqUHgFUwFneF0 FYJ/eqB9EGK36HGOspw7pjSYlZSYk0CxAPzFglEKlaciHkA7ZilNsJmqCJ7fNWduda zSj6ut8JcOC3IVPpAx+FPT9q+5537Z8t8I+o4kuQ= From: Tomi Valkeinen To: linux-media@vger.kernel.org, sakari.ailus@linux.intel.com, Jacopo Mondi , Laurent Pinchart , niklas.soderlund+renesas@ragnatech.se Cc: Mauro Carvalho Chehab , Hans Verkuil , Tomi Valkeinen , Pratyush Yadav , Lokesh Vutla Subject: [PATCH v8 36/36] media: subdev: add v4l2_routing_simple_verify() helper Date: Mon, 30 Aug 2021 14:01:16 +0300 Message-Id: <20210830110116.488338-37-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> References: <20210830110116.488338-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add a helper for verifying routing for the common case of non-overlapping 1-to-1 streams. Signed-off-by: Tomi Valkeinen --- drivers/media/v4l2-core/v4l2-subdev.c | 24 ++++++++++++++++++++++++ include/media/v4l2-subdev.h | 14 ++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 83fa87e88bce..e3a7793157db 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -1572,3 +1572,27 @@ int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, return 0; } EXPORT_SYMBOL_GPL(v4l2_subdev_get_fmt); + +int v4l2_routing_simple_verify(const struct v4l2_subdev_krouting *routing) +{ + unsigned int i, j; + + for (i = 0; i < routing->num_routes; ++i) { + const struct v4l2_subdev_route *route = &routing->routes[i]; + + for (j = i + 1; j < routing->num_routes; ++j) { + const struct v4l2_subdev_route *r = &routing->routes[j]; + + if (route->sink_pad == r->sink_pad && + route->sink_stream == r->sink_stream) + return -EINVAL; + + if (route->source_pad == r->source_pad && + route->source_stream == r->source_stream) + return -EINVAL; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_routing_simple_verify); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 3f72c500ff6e..476d797ecc68 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -1562,4 +1562,18 @@ v4l2_state_get_opposite_stream_format(struct v4l2_subdev_state *state, u32 pad, int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format); +/** + * v4l2_routing_simple_verify() - Verify that all streams are non-overlapping + * 1-to-1 streams + * @routing: routing to verify + * + * This verifies that the given routing contains only non-overlapping 1-to-1 + * streams. In other words, no two streams have the same source or sink + * stream ID on a single pad. This is the most common case of routing + * supported by devices. + * + * Returns 0 on success, error value otherwise. + */ +int v4l2_routing_simple_verify(const struct v4l2_subdev_krouting *routing); + #endif