From patchwork Wed Mar 23 08:45:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 8647931 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 10D1F9F36E for ; Wed, 23 Mar 2016 08:46:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E915F20396 for ; Wed, 23 Mar 2016 08:46:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 03930203A9 for ; Wed, 23 Mar 2016 08:46:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754398AbcCWIqI (ORCPT ); Wed, 23 Mar 2016 04:46:08 -0400 Received: from galahad.ideasonboard.com ([185.26.127.97]:38558 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754078AbcCWIqF (ORCPT ); Wed, 23 Mar 2016 04:46:05 -0400 Received: from avalon.bb.dnainternet.fi (85-23-193-79.bb.dnainternet.fi [85.23.193.79]) by galahad.ideasonboard.com (Postfix) with ESMTPSA id 724D02005E; Wed, 23 Mar 2016 09:45:25 +0100 (CET) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Hans Verkuil , Mauro Carvalho Chehab Subject: [PATCH v5 1/2] media: Add obj_type field to struct media_entity Date: Wed, 23 Mar 2016 10:45:55 +0200 Message-Id: <1458722756-7269-2-git-send-email-laurent.pinchart+renesas@ideasonboard.com> X-Mailer: git-send-email 2.7.3 In-Reply-To: <1458722756-7269-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> References: <1458722756-7269-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Code that processes media entities can require knowledge of the structure type that embeds a particular media entity instance in order to cast the entity to the proper object type. This needs is shown by the presence of the is_media_entity_v4l2_io and is_media_entity_v4l2_subdev functions. The implementation of those two functions relies on the entity function field, which is both a wrong and an inefficient design, without even mentioning the maintenance issue involved in updating the functions every time a new entity function is added. Fix this by adding add an obj_type field to the media entity structure to carry the information. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Sakari Ailus --- drivers/media/media-device.c | 2 + drivers/media/v4l2-core/v4l2-dev.c | 1 + drivers/media/v4l2-core/v4l2-subdev.c | 1 + include/media/media-entity.h | 79 +++++++++++++++++++---------------- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 4a97d92a7e7d..88d8de3b7a4f 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -580,6 +580,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, "Entity type for entity %s was not initialized!\n", entity->name); + WARN_ON(entity->obj_type == MEDIA_ENTITY_TYPE_INVALID); + /* Warn if we apparently re-register an entity */ WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev; diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index d8e5994cccf1..70b559d7ca80 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -735,6 +735,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0; + vdev->entity.obj_type = MEDIA_ENTITY_TYPE_VIDEO_DEVICE; vdev->entity.function = MEDIA_ENT_F_UNKNOWN; switch (type) { diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index d63083803144..0fa60801a428 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -584,6 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; + sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV; sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; #endif } diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 6dc9e4e8cbd4..5cea57955a3a 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -188,10 +188,41 @@ struct media_entity_operations { }; /** + * enum media_entity_type - Media entity type + * + * @MEDIA_ENTITY_TYPE_INVALID: + * Invalid type, used to catch uninitialized fields. + * @MEDIA_ENTITY_TYPE_VIDEO_DEVICE: + * The entity is embedded in a struct video_device instance. + * @MEDIA_ENTITY_TYPE_V4L2_SUBDEV: + * The entity is embedded in a struct v4l2_subdev instance. + * + * Media entity objects are not instantiated directly, but the media entity + * structure is inherited by (through embedding) other subsystem-specific + * structures. The media entity type identifies the type of the subclass + * structure that implements a media entity instance. + * + * This allows runtime type identification of media entities and safe casting to + * the correct object type. For instance, a media entity structure instance + * embedded in a v4l2_subdev structure instance will have the type + * MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a v4l2_subdev + * structure using the container_of() macro. + * + * The MEDIA_ENTITY_TYPE_INVALID type should never be set as an entity type, it + * only serves to catch uninitialized fields when registering entities. + */ +enum media_entity_type { + MEDIA_ENTITY_TYPE_INVALID, + MEDIA_ENTITY_TYPE_VIDEO_DEVICE, + MEDIA_ENTITY_TYPE_V4L2_SUBDEV, +}; + +/** * struct media_entity - A media entity graph object. * * @graph_obj: Embedded structure containing the media object common data. * @name: Entity name. + * @obj_type: Type of the object that implements the media_entity. * @function: Entity main function, as defined in uapi/media.h * (MEDIA_ENT_F_*) * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) @@ -220,6 +251,7 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; + enum media_entity_type obj_type; u32 function; unsigned long flags; @@ -329,56 +361,29 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) } /** - * is_media_entity_v4l2_io() - identify if the entity main function - * is a V4L2 I/O - * + * is_media_entity_v4l2_io() - Check if the entity is a video_device * @entity: pointer to entity * - * Return: true if the entity main function is one of the V4L2 I/O types - * (video, VBI or SDR radio); false otherwise. + * Return: true if the entity is an instance of a video_device object and can + * safely be cast to a struct video_device using the container_of() macro, or + * false otherwise. */ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) { - if (!entity) - return false; - - switch (entity->function) { - case MEDIA_ENT_F_IO_V4L: - case MEDIA_ENT_F_IO_VBI: - case MEDIA_ENT_F_IO_SWRADIO: - return true; - default: - return false; - } + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE; } /** - * is_media_entity_v4l2_subdev - return true if the entity main function is - * associated with the V4L2 API subdev usage - * + * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev * @entity: pointer to entity * - * This is an ancillary function used by subdev-based V4L2 drivers. - * It checks if the entity function is one of functions used by a V4L2 subdev, - * e. g. camera-relatef functions, analog TV decoder, TV tuner, V4L2 DSPs. + * Return: true if the entity is an instance of a v4l2_subdev object and can + * safely be cast to a struct v4l2_subdev using the container_of() macro, or + * false otherwise. */ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) { - if (!entity) - return false; - - switch (entity->function) { - case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN: - case MEDIA_ENT_F_CAM_SENSOR: - case MEDIA_ENT_F_FLASH: - case MEDIA_ENT_F_LENS: - case MEDIA_ENT_F_ATV_DECODER: - case MEDIA_ENT_F_TUNER: - return true; - - default: - return false; - } + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_V4L2_SUBDEV; } /**