From patchwork Thu Dec 13 13:41:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 10728749 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D7F3A13AF for ; Thu, 13 Dec 2018 13:41:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5DA52C1F1 for ; Thu, 13 Dec 2018 13:41:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BA4892C194; Thu, 13 Dec 2018 13:41:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9C69D2C250 for ; Thu, 13 Dec 2018 13:41:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729667AbeLMNlT (ORCPT ); Thu, 13 Dec 2018 08:41:19 -0500 Received: from lb1-smtp-cloud7.xs4all.net ([194.109.24.24]:59410 "EHLO lb1-smtp-cloud7.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729524AbeLMNlS (ORCPT ); Thu, 13 Dec 2018 08:41:18 -0500 Received: from test-nl.fritz.box ([80.101.105.217]) by smtp-cloud7.xs4all.net with ESMTPA id XREngf3iadllcXREpgEECJ; Thu, 13 Dec 2018 14:41:15 +0100 From: hverkuil-cisco@xs4all.nl To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFCv5 PATCH 1/4] uapi/linux/media.h: add property support Date: Thu, 13 Dec 2018 14:41:10 +0100 Message-Id: <20181213134113.15247-2-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> References: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfHOaWAa9T0hX0cy0lvLPmonAa9fBNHICWnMmB+u3IVCGCsJHEggH9FjzVoprc6YFyE5n8/zTY61pZmuyKsRoUVYHLbEAvZBVXmnG4CxVUyorrptV0uC2 B1EIofqPJQdckMVnBOI5VBLMa0dcYn2QTxUXCUg8JFPEtmEng+fdpBOuzMAx7qePBdRu9/BLE3rFnTattHBcHkXqpAQfESrkQL5CkhWiJ1/Qk96CQmvjy8RJ Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Verkuil Extend the topology struct with a properties array. Add a new media_v2_prop structure to store property information. Signed-off-by: Hans Verkuil --- include/uapi/linux/media.h | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index e5d0c5c611b5..12982327381e 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -342,6 +342,58 @@ struct media_v2_link { __u32 reserved[6]; } __attribute__ ((packed)); +#define MEDIA_PROP_TYPE_GROUP 1 +#define MEDIA_PROP_TYPE_U64 2 +#define MEDIA_PROP_TYPE_S64 3 +#define MEDIA_PROP_TYPE_STRING 4 + +#define MEDIA_OWNER_TYPE_ENTITY 0 +#define MEDIA_OWNER_TYPE_PAD 1 +#define MEDIA_OWNER_TYPE_LINK 2 +#define MEDIA_OWNER_TYPE_INTF 3 +#define MEDIA_OWNER_TYPE_PROP 4 + +/** + * struct media_v2_prop - A media property + * + * @id: The unique non-zero ID of this property + * @type: Property type + * @owner_id: The ID of the object this property belongs to + * @owner_type: The type of the object this property belongs to + * @flags: Property flags + * @name: Property name + * @payload_size: Property payload size, 0 for U64/S64 + * @payload_offset: Property payload starts at this offset from &prop.id. + * This is 0 for U64/S64. + * @reserved: Property reserved field, will be zeroed. + */ +struct media_v2_prop { + __u32 id; + __u32 type; + __u32 owner_id; + __u32 owner_type; + __u32 flags; + char name[32]; + __u32 payload_size; + __u32 payload_offset; + __u32 reserved[18]; +} __attribute__ ((packed)); + +static inline const char *media_prop2string(const struct media_v2_prop *prop) +{ + return (const char *)prop + prop->payload_offset; +} + +static inline __u64 media_prop2u64(const struct media_v2_prop *prop) +{ + return *(const __u64 *)((const char *)prop + prop->payload_offset); +} + +static inline __s64 media_prop2s64(const struct media_v2_prop *prop) +{ + return *(const __s64 *)((const char *)prop + prop->payload_offset); +} + struct media_v2_topology { __u64 topology_version; @@ -360,6 +412,10 @@ struct media_v2_topology { __u32 num_links; __u32 reserved4; __u64 ptr_links; + + __u32 num_props; + __u32 props_payload_size; + __u64 ptr_props; } __attribute__ ((packed)); /* ioctls */ From patchwork Thu Dec 13 13:41:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 10728755 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 76A85112E for ; Thu, 13 Dec 2018 13:41:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6167F2C228 for ; Thu, 13 Dec 2018 13:41:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5F4532C138; Thu, 13 Dec 2018 13:41:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DF5612C24B for ; Thu, 13 Dec 2018 13:41:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729669AbeLMNlV (ORCPT ); Thu, 13 Dec 2018 08:41:21 -0500 Received: from lb3-smtp-cloud7.xs4all.net ([194.109.24.31]:49447 "EHLO lb3-smtp-cloud7.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729664AbeLMNlU (ORCPT ); Thu, 13 Dec 2018 08:41:20 -0500 Received: from test-nl.fritz.box ([80.101.105.217]) by smtp-cloud7.xs4all.net with ESMTPA id XREngf3iadllcXREpgEECR; Thu, 13 Dec 2018 14:41:15 +0100 From: hverkuil-cisco@xs4all.nl To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFCv5 PATCH 2/4] media controller: add properties support Date: Thu, 13 Dec 2018 14:41:11 +0100 Message-Id: <20181213134113.15247-3-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> References: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfHOaWAa9T0hX0cy0lvLPmonAa9fBNHICWnMmB+u3IVCGCsJHEggH9FjzVoprc6YFyE5n8/zTY61pZmuyKsRoUVYHLbEAvZBVXmnG4CxVUyorrptV0uC2 B1EIofqPJQdckMVnBOI5VBLMa0dcYn2QTxUXCUg8JFPEtmEng+fdpBOuzMAx7qePBdRu9/BLE3rFnWL0amksxRQpudWZ0XZI77EfkHeWYpniDKlAV7c9ZvW/ Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Verkuil Add support for properties. In this initial implementation properties can be added to entities and pads. In addition, properties can be nested. Most of the changes are straightforward, but I had to make some changes to the way entities are initialized, since the struct has to be initialized either when media_entity_pads_init() is called or when media_device_register_entity() is called, whichever comes first. The properties list in the entity has to be initialized in both cases, otherwise you can't add properties to it. The entity struct is now initialized in media_entity_init and called from both functions if ent->inited is 0. Signed-off-by: Hans Verkuil --- drivers/media/media-device.c | 129 ++++++++++++++++++++++++++++++++--- drivers/media/media-entity.c | 26 +++++-- include/media/media-device.h | 6 ++ include/media/media-entity.h | 58 ++++++++++++++++ 4 files changed, 205 insertions(+), 14 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index bed24372e61f..a932e6848d47 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -242,10 +242,14 @@ static long media_device_get_topology(struct media_device *mdev, void *arg) struct media_interface *intf; struct media_pad *pad; struct media_link *link; + struct media_prop *prop; struct media_v2_entity kentity, __user *uentity; struct media_v2_interface kintf, __user *uintf; struct media_v2_pad kpad, __user *upad; struct media_v2_link klink, __user *ulink; + struct media_v2_prop kprop, __user *uprop; + unsigned int props_payload_size = 0; + unsigned int prop_payload_offset; unsigned int i; int ret = 0; @@ -375,6 +379,48 @@ static long media_device_get_topology(struct media_device *mdev, void *arg) topo->num_links = i; topo->reserved4 = 0; + /* Get properties and number of properties */ + i = 0; + uprop = media_get_uptr(topo->ptr_props); + media_device_for_each_prop(prop, mdev) { + i++; + props_payload_size += ALIGN(prop->payload_size, sizeof(u64)); + } + if (i > topo->num_props || + props_payload_size > topo->props_payload_size) + ret = ret ? : -ENOSPC; + topo->props_payload_size = props_payload_size; + topo->num_props = i; + topo->reserved4 = 0; + + if (ret || !uprop) + return ret; + + prop_payload_offset = topo->num_props * sizeof(*uprop); + media_device_for_each_prop(prop, mdev) { + memset(&kprop, 0, sizeof(kprop)); + + /* Copy prop fields to userspace struct */ + kprop.id = prop->graph_obj.id; + kprop.type = prop->type; + kprop.owner_id = prop->owner->id; + kprop.owner_type = media_type(prop->owner); + kprop.payload_size = prop->payload_size; + if (prop->payload_size) { + kprop.payload_offset = prop_payload_offset; + if (copy_to_user((u8 __user *)uprop + prop_payload_offset, + prop->payload, prop->payload_size)) + return -EFAULT; + prop_payload_offset += ALIGN(prop->payload_size, sizeof(u64)); + } + memcpy(kprop.name, prop->name, sizeof(kprop.name)); + + if (copy_to_user(uprop, &kprop, sizeof(kprop))) + return -EFAULT; + uprop++; + prop_payload_offset -= sizeof(*uprop); + } + return ret; } @@ -408,9 +454,10 @@ static long copy_arg_to_user(void __user *uarg, void *karg, unsigned int cmd) /* Do acquire the graph mutex */ #define MEDIA_IOC_FL_GRAPH_MUTEX BIT(0) -#define MEDIA_IOC_ARG(__cmd, func, fl, from_user, to_user) \ +#define MEDIA_IOC_ARG(__cmd, alts, func, fl, from_user, to_user) \ [_IOC_NR(MEDIA_IOC_##__cmd)] = { \ .cmd = MEDIA_IOC_##__cmd, \ + .alternatives = (alts), \ .fn = (long (*)(struct media_device *, void *))func, \ .flags = fl, \ .arg_from_user = from_user, \ @@ -418,23 +465,39 @@ static long copy_arg_to_user(void __user *uarg, void *karg, unsigned int cmd) } #define MEDIA_IOC(__cmd, func, fl) \ - MEDIA_IOC_ARG(__cmd, func, fl, copy_arg_from_user, copy_arg_to_user) + MEDIA_IOC_ARG(__cmd, NULL, func, fl, copy_arg_from_user, copy_arg_to_user) +#define MEDIA_IOC_ALTS(__cmd, alts, func, fl) \ + MEDIA_IOC_ARG(__cmd, alts, func, fl, copy_arg_from_user, copy_arg_to_user) /* the table is indexed by _IOC_NR(cmd) */ struct media_ioctl_info { unsigned int cmd; + const unsigned int *alternatives; unsigned short flags; long (*fn)(struct media_device *dev, void *arg); long (*arg_from_user)(void *karg, void __user *uarg, unsigned int cmd); long (*arg_to_user)(void __user *uarg, void *karg, unsigned int cmd); }; +#define _IOWR_COMPAT(type, nr, size) \ + _IOC(_IOC_READ | _IOC_WRITE, (type), (nr), (size)) + +/* Old MEDIA_IOC_G_TOPOLOGY ioctl without props support */ +#define MEDIA_IOC_G_TOPOLOGY_V1 _IOWR_COMPAT('|', 0x04, offsetof(struct media_v2_topology, num_props)) + +static const unsigned int topo_alts[] = { + /* Old MEDIA_IOC_G_TOPOLOGY without props support */ + MEDIA_IOC_G_TOPOLOGY_V1, + 0 +}; + static const struct media_ioctl_info ioctl_info[] = { MEDIA_IOC(DEVICE_INFO, media_device_get_info, MEDIA_IOC_FL_GRAPH_MUTEX), MEDIA_IOC(ENUM_ENTITIES, media_device_enum_entities, MEDIA_IOC_FL_GRAPH_MUTEX), MEDIA_IOC(ENUM_LINKS, media_device_enum_links, MEDIA_IOC_FL_GRAPH_MUTEX), MEDIA_IOC(SETUP_LINK, media_device_setup_link, MEDIA_IOC_FL_GRAPH_MUTEX), MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX), + MEDIA_IOC_ALTS(G_TOPOLOGY, topo_alts, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX), MEDIA_IOC(REQUEST_ALLOC, media_device_request_alloc, 0), }; @@ -448,17 +511,29 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, char __karg[256], *karg = __karg; long ret; - if (_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_info) - || ioctl_info[_IOC_NR(cmd)].cmd != cmd) + if (_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_info)) return -ENOIOCTLCMD; info = &ioctl_info[_IOC_NR(cmd)]; + if (info->cmd != cmd) { + const unsigned int *p; + + for (p = info->alternatives; p && *p; p++) + if (*p == cmd) + break; + if (!p || !*p) + return -ENOIOCTLCMD; + } + if (_IOC_SIZE(info->cmd) > sizeof(__karg)) { karg = kmalloc(_IOC_SIZE(info->cmd), GFP_KERNEL); if (!karg) return -ENOMEM; } + if (_IOC_SIZE(info->cmd) > _IOC_SIZE(cmd)) + memset(karg + _IOC_SIZE(cmd), 0, + _IOC_SIZE(info->cmd) - _IOC_SIZE(cmd)); if (info->arg_from_user) { ret = info->arg_from_user(karg, arg, cmd); @@ -571,6 +646,16 @@ static void media_device_release(struct media_devnode *devnode) dev_dbg(devnode->parent, "Media device released\n"); } +static void init_prop_list(struct media_device *mdev, struct list_head *list) +{ + struct media_prop *prop; + + list_for_each_entry(prop, list, list) { + media_gobj_create(mdev, MEDIA_GRAPH_PROP, &prop->graph_obj); + init_prop_list(mdev, &prop->props); + } +} + /** * media_device_register_entity - Register an entity with a media device * @mdev: The media device @@ -592,9 +677,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, /* Warn if we apparently re-register an entity */ WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev; - INIT_LIST_HEAD(&entity->links); - entity->num_links = 0; - entity->num_backlinks = 0; + if (!entity->inited) + media_entity_init(entity); ret = ida_alloc_min(&mdev->entity_internal_idx, 1, GFP_KERNEL); if (ret < 0) @@ -608,10 +692,17 @@ int __must_check media_device_register_entity(struct media_device *mdev, /* Initialize media_gobj embedded at the entity */ media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); + /* Initialize objects at the props */ + init_prop_list(mdev, &entity->props); + /* Initialize objects at the pads */ - for (i = 0; i < entity->num_pads; i++) + for (i = 0; i < entity->num_pads; i++) { media_gobj_create(mdev, MEDIA_GRAPH_PAD, - &entity->pads[i].graph_obj); + &entity->pads[i].graph_obj); + + /* Initialize objects at the pad props */ + init_prop_list(mdev, &entity->pads[i].props); + } /* invoke entity_notify callbacks */ list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) @@ -640,6 +731,18 @@ int __must_check media_device_register_entity(struct media_device *mdev, } EXPORT_SYMBOL_GPL(media_device_register_entity); +static void media_device_free_props(struct list_head *list) +{ + while (!list_empty(list)) { + struct media_prop *prop; + + prop = list_first_entry(list, struct media_prop, list); + list_del(&prop->list); + media_gobj_destroy(&prop->graph_obj); + kfree(prop); + } +} + static void __media_device_unregister_entity(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; @@ -661,8 +764,13 @@ 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++) + for (i = 0; i < entity->num_pads; i++) { + media_device_free_props(&entity->pads[i].props); media_gobj_destroy(&entity->pads[i].graph_obj); + } + + /* Remove all props that belong to this entity */ + media_device_free_props(&entity->props); /* Remove the entity */ media_gobj_destroy(&entity->graph_obj); @@ -701,6 +809,7 @@ void media_device_init(struct media_device *mdev) INIT_LIST_HEAD(&mdev->interfaces); INIT_LIST_HEAD(&mdev->pads); INIT_LIST_HEAD(&mdev->links); + INIT_LIST_HEAD(&mdev->props); INIT_LIST_HEAD(&mdev->entity_notify); mutex_init(&mdev->req_queue_mutex); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0b1cb3559140..62c4d5b4d33f 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -34,6 +34,8 @@ static inline const char *gobj_type(enum media_gobj_type type) return "link"; case MEDIA_GRAPH_INTF_DEVNODE: return "intf-devnode"; + case MEDIA_GRAPH_PROP: + return "prop"; default: return "unknown"; } @@ -106,7 +108,7 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) switch (media_type(gobj)) { case MEDIA_GRAPH_ENTITY: dev_dbg(gobj->mdev->dev, - "%s id %u: entity '%s'\n", + "%s id 0x%08x: entity '%s'\n", event_name, media_id(gobj), gobj_to_entity(gobj)->name); break; @@ -115,7 +117,7 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_link *link = gobj_to_link(gobj); dev_dbg(gobj->mdev->dev, - "%s id %u: %s link id %u ==> id %u\n", + "%s id 0x%08x: %s link id 0x%08x ==> id 0x%08x\n", event_name, media_id(gobj), media_type(link->gobj0) == MEDIA_GRAPH_PAD ? "data" : "interface", @@ -128,7 +130,7 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_pad *pad = gobj_to_pad(gobj); dev_dbg(gobj->mdev->dev, - "%s id %u: %s%spad '%s':%d\n", + "%s id 0x%08x: %s%spad '%s':%d\n", event_name, media_id(gobj), pad->flags & MEDIA_PAD_FL_SINK ? "sink " : "", pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "", @@ -141,12 +143,22 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_intf_devnode *devnode = intf_to_devnode(intf); dev_dbg(gobj->mdev->dev, - "%s id %u: intf_devnode %s - major: %d, minor: %d\n", + "%s id 0x%08x: intf_devnode %s - major: %d, minor: %d\n", event_name, media_id(gobj), intf_type(intf), devnode->major, devnode->minor); break; } + case MEDIA_GRAPH_PROP: + { + struct media_prop *prop = gobj_to_prop(gobj); + + dev_dbg(gobj->mdev->dev, + "%s id 0x%08x: prop '%s':0x%08x\n", + event_name, media_id(gobj), + prop->name, media_id(prop->owner)); + break; + } } #endif } @@ -175,6 +187,9 @@ void media_gobj_create(struct media_device *mdev, case MEDIA_GRAPH_INTF_DEVNODE: list_add_tail(&gobj->list, &mdev->interfaces); break; + case MEDIA_GRAPH_PROP: + list_add_tail(&gobj->list, &mdev->props); + break; } mdev->topology_version++; @@ -212,6 +227,8 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, if (num_pads >= MEDIA_ENTITY_MAX_PADS) return -E2BIG; + if (!entity->inited) + media_entity_init(entity); entity->num_pads = num_pads; entity->pads = pads; @@ -221,6 +238,7 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, for (i = 0; i < num_pads; i++) { pads[i].entity = entity; pads[i].index = i; + INIT_LIST_HEAD(&pads[i].props); if (mdev) media_gobj_create(mdev, MEDIA_GRAPH_PAD, &entity->pads[i].graph_obj); diff --git a/include/media/media-device.h b/include/media/media-device.h index c8ddbfe8b74c..d422a1e1c367 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -101,6 +101,7 @@ struct media_device_ops { * @interfaces: List of registered interfaces * @pads: List of registered pads * @links: List of registered links + * @props: List of registered properties * @entity_notify: List of registered entity_notify callbacks * @graph_mutex: Protects access to struct media_device data * @pm_count_walk: Graph walk for power state walk. Access serialised using @@ -170,6 +171,7 @@ struct media_device { struct list_head interfaces; struct list_head pads; struct list_head links; + struct list_head props; /* notify callback list invoked when a new entity is registered */ struct list_head entity_notify; @@ -411,6 +413,10 @@ void media_device_unregister_entity_notify(struct media_device *mdev, #define media_device_for_each_link(link, mdev) \ list_for_each_entry(link, &(mdev)->links, graph_obj.list) +/* Iterate over all props. */ +#define media_device_for_each_prop(prop, mdev) \ + list_for_each_entry(prop, &(mdev)->props, graph_obj.list) + /** * media_device_pci_init() - create and initialize a * struct &media_device from a PCI device. diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e5f6960d92f6..5d05ebf712d0 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -36,12 +37,14 @@ * @MEDIA_GRAPH_LINK: Identify a media link * @MEDIA_GRAPH_INTF_DEVNODE: Identify a media Kernel API interface via * a device node + * @MEDIA_GRAPH_PROP: Identify a media property */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, MEDIA_GRAPH_PAD, MEDIA_GRAPH_LINK, MEDIA_GRAPH_INTF_DEVNODE, + MEDIA_GRAPH_PROP, }; #define MEDIA_BITS_PER_TYPE 8 @@ -193,6 +196,7 @@ enum media_pad_signal_type { * @flags: Pad flags, as defined in * :ref:`include/uapi/linux/media.h ` * (seek for ``MEDIA_PAD_FL_*``) + * @props: The list pad properties */ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ @@ -200,6 +204,33 @@ struct media_pad { u16 index; enum media_pad_signal_type sig_type; unsigned long flags; + struct list_head props; +}; + +/** + * struct media_prop - A media property graph object. + * + * @graph_obj: Embedded structure containing the media object common data + * @list: Linked list associated with the object that owns the link. + * @owner: Graph object this property belongs to + * @index: Property index for the owner property array, numbered + * from 0 to n + * @type: Property type + * @payload_size: Property payload size (i.e. additional bytes beyond this + * struct) + * @props: The list of sub-properties + * @name: Property name + * @payload: Property payload starts here + */ +struct media_prop { + struct media_gobj graph_obj; /* must be first field in struct */ + struct list_head list; + struct media_gobj *owner; + u32 type; + u32 payload_size; + struct list_head props; + char name[32]; + u8 payload[]; }; /** @@ -266,6 +297,7 @@ enum media_entity_type { * @flags: Entity flags, as defined in * :ref:`include/uapi/linux/media.h ` * (seek for ``MEDIA_ENT_FL_*``) + * @inited: Non-zero if this struct was initialized. * @num_pads: Number of sink and source pads. * @num_links: Total number of links, forward and back, enabled and disabled. * @num_backlinks: Number of backlinks @@ -273,6 +305,7 @@ enum media_entity_type { * re-used if entities are unregistered or registered again. * @pads: Pads array with the size defined by @num_pads. * @links: List of data links. + * @props: List of entity properties. * @ops: Entity operations. * @stream_count: Stream count for the entity. * @use_count: Use count for the entity. @@ -300,6 +333,7 @@ struct media_entity { enum media_entity_type obj_type; u32 function; unsigned long flags; + unsigned int inited; u16 num_pads; u16 num_links; @@ -308,6 +342,7 @@ struct media_entity { struct media_pad *pads; struct list_head links; + struct list_head props; const struct media_entity_operations *ops; @@ -362,6 +397,20 @@ struct media_intf_devnode { u32 minor; }; +/** + * media_entity_init() - initialize the media entity struct + * + * @entity: pointer to &media_entity + */ +static inline void media_entity_init(struct media_entity *entity) +{ + INIT_LIST_HEAD(&entity->links); + INIT_LIST_HEAD(&entity->props); + entity->num_links = 0; + entity->num_backlinks = 0; + entity->inited = true; +} + /** * media_entity_id() - return the media entity graph object id * @@ -595,6 +644,15 @@ static inline bool media_entity_enum_intersects( #define gobj_to_intf(gobj) \ container_of(gobj, struct media_interface, graph_obj) +/** + * gobj_to_prop - returns the struct &media_prop pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ +#define gobj_to_prop(gobj) \ + container_of(gobj, struct media_prop, graph_obj) + /** * intf_to_devnode - returns the struct media_intf_devnode pointer from the * @intf contained on it. From patchwork Thu Dec 13 13:41:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 10728753 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 097C413AF for ; Thu, 13 Dec 2018 13:41:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF6522C20A for ; Thu, 13 Dec 2018 13:41:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EDBE92C234; Thu, 13 Dec 2018 13:41:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D715F2C20A for ; Thu, 13 Dec 2018 13:41:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729668AbeLMNlT (ORCPT ); Thu, 13 Dec 2018 08:41:19 -0500 Received: from lb2-smtp-cloud7.xs4all.net ([194.109.24.28]:39997 "EHLO lb2-smtp-cloud7.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729467AbeLMNlT (ORCPT ); Thu, 13 Dec 2018 08:41:19 -0500 Received: from test-nl.fritz.box ([80.101.105.217]) by smtp-cloud7.xs4all.net with ESMTPA id XREngf3iadllcXREpgEECW; Thu, 13 Dec 2018 14:41:15 +0100 From: hverkuil-cisco@xs4all.nl To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFCv5 PATCH 3/4] media: add functions to add properties to objects Date: Thu, 13 Dec 2018 14:41:12 +0100 Message-Id: <20181213134113.15247-4-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> References: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfHOaWAa9T0hX0cy0lvLPmonAa9fBNHICWnMmB+u3IVCGCsJHEggH9FjzVoprc6YFyE5n8/zTY61pZmuyKsRoUVYHLbEAvZBVXmnG4CxVUyorrptV0uC2 B1EIofqPJQdckMVnBOI5VBLMa0dcYn2QTxUXCUg8JFPEtmEng+fdpBOuzMAx7qePBdRu9/BLE3rFnWL0amksxRQpudWZ0XZI77EfkHeWYpniDKlAV7c9ZvW/ Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Verkuil Add functions to add properties to entities, pads and other properties. This can be extended to include interfaces and links in the future when needed. Signed-off-by: Hans Verkuil --- drivers/media/media-entity.c | 64 +++++++++ include/media/media-entity.h | 264 +++++++++++++++++++++++++++++++++++ 2 files changed, 328 insertions(+) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 62c4d5b4d33f..cdb35bc8e9a0 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -251,6 +251,70 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, } EXPORT_SYMBOL_GPL(media_entity_pads_init); +static struct media_prop *media_create_prop(struct media_gobj *owner, u32 type, + const char *name, const void *ptr, + u32 payload_size) +{ + struct media_prop *prop = kzalloc(sizeof(*prop) + payload_size, + GFP_KERNEL); + + if (!prop) + return ERR_PTR(-ENOMEM); + prop->type = type; + strscpy(prop->name, name, sizeof(prop->name)); + if (owner->mdev) + media_gobj_create(owner->mdev, MEDIA_GRAPH_PROP, + &prop->graph_obj); + prop->owner = owner; + prop->payload_size = payload_size; + if (payload_size && ptr) + memcpy(prop->payload, ptr, payload_size); + INIT_LIST_HEAD(&prop->props); + return prop; +} + +struct media_prop *media_entity_add_prop(struct media_entity *ent, u32 type, + const char *name, const void *ptr, + u32 payload_size) +{ + struct media_prop *prop; + + if (!ent->inited) + media_entity_init(ent); + prop = media_create_prop(&ent->graph_obj, type, + name, ptr, payload_size); + if (!IS_ERR(prop)) + list_add_tail(&prop->list, &ent->props); + return prop; +} +EXPORT_SYMBOL_GPL(media_entity_add_prop); + +struct media_prop *media_pad_add_prop(struct media_pad *pad, u32 type, + const char *name, const void *ptr, + u32 payload_size) +{ + struct media_prop *prop = media_create_prop(&pad->graph_obj, type, + name, ptr, payload_size); + + if (!IS_ERR(prop)) + list_add_tail(&prop->list, &pad->props); + return prop; +} +EXPORT_SYMBOL_GPL(media_pad_add_prop); + +struct media_prop *media_prop_add_prop(struct media_prop *prop, u32 type, + const char *name, const void *ptr, + u32 payload_size) +{ + struct media_prop *subprop = media_create_prop(&prop->graph_obj, type, + name, ptr, payload_size); + + if (!IS_ERR(subprop)) + list_add_tail(&subprop->list, &prop->props); + return subprop; +} +EXPORT_SYMBOL_GPL(media_prop_add_prop); + /* ----------------------------------------------------------------------------- * Graph traversal */ diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 5d05ebf712d0..695acfd3fe9c 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -833,6 +833,270 @@ int media_create_pad_links(const struct media_device *mdev, void __media_entity_remove_links(struct media_entity *entity); +/** + * media_entity_add_prop() - Add property to entity + * + * @entity: entity where to add the property + * @type: property type + * @name: property name + * @ptr: property pointer to payload + * @payload_size: property payload size + * + * Returns the new property on success, or an error pointer on failure. + */ +struct media_prop *media_entity_add_prop(struct media_entity *ent, u32 type, + const char *name, const void *ptr, + u32 payload_size); + +/** + * media_pad_add_prop() - Add property to pad + * + * @pad: pad where to add the property + * @type: property type + * @name: property name + * @ptr: property pointer to payload + * @payload_size: property payload size + * + * Returns the new property on success, or an error pointer on failure. + */ +struct media_prop *media_pad_add_prop(struct media_pad *pad, u32 type, + const char *name, const void *ptr, + u32 payload_size); + +/** + * media_prop() - Add sub-property to property + * + * @prop: property where to add the sub-property + * @type: sub-property type + * @name: sub-property name + * @ptr: sub-property pointer to payload + * @payload_size: sub-property payload size + * + * Returns the new property on success, or an error pointer on failure. + */ +struct media_prop *media_prop_add_prop(struct media_prop *prop, u32 type, + const char *name, const void *ptr, + u32 payload_size); + +/** + * media_entity_add_prop_group() - Add group property to entity + * + * @entity: entity where to add the property + * @name: property name + * + * Returns the new property on success, or an error pointer on failure. + */ +static inline struct media_prop * +media_entity_add_prop_group(struct media_entity *entity, const char *name) +{ + return media_entity_add_prop(entity, MEDIA_PROP_TYPE_GROUP, + name, NULL, 0); +} + +/** + * media_entity_add_prop_u64() - Add u64 property to entity + * + * @entity: entity where to add the property + * @name: property name + * @val: property value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_entity_add_prop_u64(struct media_entity *entity, + const char *name, u64 val) +{ + struct media_prop *prop = + media_entity_add_prop(entity, MEDIA_PROP_TYPE_U64, + name, &val, sizeof(val)); + + return PTR_ERR_OR_ZERO(prop); +} + +/** + * media_entity_add_prop_s64() - Add s64 property to entity + * + * @entity: entity where to add the property + * @name: property name + * @val: property value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_entity_add_prop_s64(struct media_entity *entity, + const char *name, s64 val) +{ + struct media_prop *prop = + media_entity_add_prop(entity, MEDIA_PROP_TYPE_S64, + name, &val, sizeof(val)); + + return PTR_ERR_OR_ZERO(prop); +} + +/** + * media_entity_add_prop_string() - Add string property to entity + * + * @entity: entity where to add the property + * @name: property name + * @string: property string value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_entity_add_prop_string(struct media_entity *entity, + const char *name, + const char *string) +{ + struct media_prop *prop = + media_entity_add_prop(entity, MEDIA_PROP_TYPE_STRING, + name, string, strlen(string) + 1); + + return PTR_ERR_OR_ZERO(prop); +} + +/** + * media_pad_add_prop_group() - Add group property to pad + * + * @pad: pad where to add the property + * @name: property name + * + * Returns the new property on success, or an error pointer on failure. + */ +static inline struct media_prop *media_pad_add_prop_group(struct media_pad *pad, + const char *name) +{ + return media_pad_add_prop(pad, MEDIA_PROP_TYPE_GROUP, + name, NULL, 0); +} + +/** + * media_pad_add_prop_u64() - Add u64 property to pad + * + * @pad: pad where to add the property + * @name: property name + * @val: property value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_pad_add_prop_u64(struct media_pad *pad, + const char *name, u64 val) +{ + struct media_prop *prop = + media_pad_add_prop(pad, MEDIA_PROP_TYPE_U64, + name, &val, sizeof(val)); + + return PTR_ERR_OR_ZERO(prop); +} + +/** + * media_pad_add_prop_s64() - Add s64 property to pad + * + * @pad: pad where to add the property + * @name: property name + * @val: property value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_pad_add_prop_s64(struct media_pad *pad, + const char *name, s64 val) +{ + struct media_prop *prop = + media_pad_add_prop(pad, MEDIA_PROP_TYPE_S64, + name, &val, sizeof(val)); + + return PTR_ERR_OR_ZERO(prop); +} + +/** + * media_pad_add_prop_string() - Add string property to pad + * + * @pad: pad where to add the property + * @name: property name + * @string: property string value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_pad_add_prop_string(struct media_pad *pad, + const char *name, + const char *string) +{ + struct media_prop *prop = + media_pad_add_prop(pad, MEDIA_PROP_TYPE_STRING, + name, string, strlen(string) + 1); + + return PTR_ERR_OR_ZERO(prop); +} + +/** + * media_prop_add_prop_group() - Add group sub-property to property + * + * @prop: property where to add the sub-property + * @name: sub-property name + * + * Returns the new property on success, or an error pointer on failure. + */ +static inline struct media_prop * +media_prop_add_prop_group(struct media_prop *prop, const char *name) +{ + return media_prop_add_prop(prop, MEDIA_PROP_TYPE_GROUP, + name, NULL, 0); +} + +/** + * media_prop_add_prop_u64() - Add u64 property to property + * + * @prop: property where to add the sub-property + * @name: sub-property name + * @val: sub-property value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_prop_add_prop_u64(struct media_prop *prop, + const char *name, u64 val) +{ + struct media_prop *subprop = + media_prop_add_prop(prop, MEDIA_PROP_TYPE_U64, + name, &val, sizeof(val)); + + return PTR_ERR_OR_ZERO(subprop); +} + +/** + * media_prop_add_prop_s64() - Add s64 property to property + * + * @prop: property where to add the sub-property + * @name: sub-property name + * @val: sub-property value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_prop_add_prop_s64(struct media_prop *prop, + const char *name, s64 val) +{ + struct media_prop *subprop = + media_prop_add_prop(prop, MEDIA_PROP_TYPE_S64, + name, &val, sizeof(val)); + + return PTR_ERR_OR_ZERO(subprop); +} + +/** + * media_prop_add_prop_string() - Add string property to property + * + * @prop: property where to add the sub-property + * @name: sub-property name + * @string: sub-property string value + * + * Returns 0 on success, or an error on failure. + */ +static inline int media_prop_add_prop_string(struct media_prop *prop, + const char *name, + const char *string) +{ + struct media_prop *subprop = + media_prop_add_prop(prop, MEDIA_PROP_TYPE_STRING, + name, string, strlen(string) + 1); + + return PTR_ERR_OR_ZERO(subprop); +} + /** * media_entity_remove_links() - remove all links associated with an entity * From patchwork Thu Dec 13 13:41:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 10728757 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CE65715A6 for ; Thu, 13 Dec 2018 13:41:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C096C2C1EB for ; Thu, 13 Dec 2018 13:41:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BF8182C23F; Thu, 13 Dec 2018 13:41:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 399862C23E for ; Thu, 13 Dec 2018 13:41:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729518AbeLMNlX (ORCPT ); Thu, 13 Dec 2018 08:41:23 -0500 Received: from lb2-smtp-cloud7.xs4all.net ([194.109.24.28]:51642 "EHLO lb2-smtp-cloud7.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729663AbeLMNlS (ORCPT ); Thu, 13 Dec 2018 08:41:18 -0500 Received: from test-nl.fritz.box ([80.101.105.217]) by smtp-cloud7.xs4all.net with ESMTPA id XREngf3iadllcXREpgEECY; Thu, 13 Dec 2018 14:41:15 +0100 From: hverkuil-cisco@xs4all.nl To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFCv5 PATCH 4/4] vimc: add property test code Date: Thu, 13 Dec 2018 14:41:13 +0100 Message-Id: <20181213134113.15247-5-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> References: <20181213134113.15247-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 X-CMAE-Envelope: MS4wfHOaWAa9T0hX0cy0lvLPmonAa9fBNHICWnMmB+u3IVCGCsJHEggH9FjzVoprc6YFyE5n8/zTY61pZmuyKsRoUVYHLbEAvZBVXmnG4CxVUyorrptV0uC2 B1EIofqPJQdckMVnBOI5VBLMa0dcYn2QTxUXCUg8JFPEtmEng+fdpBOuzMAx7qePBdRu9/BLE3rFnTattHBcHkXqpAQfESrkQL5CkhWiJ1/Qk96CQmvjy8RJ Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hans Verkuil Add properties to entities and pads to be able to test the properties API. Signed-off-by: Hans Verkuil --- drivers/media/platform/vimc/vimc-common.c | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index 867e24dbd6b5..e3d5d4b3b44d 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c @@ -417,6 +417,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, const unsigned long *pads_flag, const struct v4l2_subdev_ops *sd_ops) { + struct media_prop *prop = NULL; int ret; /* Allocate the pads */ @@ -454,6 +455,55 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, goto err_clean_m_ent; } + ret = media_entity_add_prop_u64(&sd->entity, "u64", ~1); + if (!ret) + ret = media_entity_add_prop_s64(&sd->entity, "s64", -5); + if (!ret) + ret = media_entity_add_prop_string(&sd->entity, "string", + sd->name); + if (!ret) { + prop = media_entity_add_prop_group(&sd->entity, "empty-group"); + ret = PTR_ERR_OR_ZERO(prop); + } + if (!ret) { + prop = media_entity_add_prop_group(&sd->entity, "group"); + ret = PTR_ERR_OR_ZERO(prop); + } + if (!ret) + ret = media_prop_add_prop_u64(prop, "u64", 42); + if (!ret) + ret = media_prop_add_prop_s64(prop, "s64", -42); + if (!ret) + ret = media_prop_add_prop_string(prop, "string", "42"); + if (!ret) + ret = media_pad_add_prop_u64(&sd->entity.pads[num_pads - 1], + "u64", ~1); + if (!ret) + ret = media_pad_add_prop_s64(&sd->entity.pads[num_pads - 1], + "s64", -5); + if (!ret) { + prop = media_pad_add_prop_group(&sd->entity.pads[num_pads - 1], + "group"); + ret = PTR_ERR_OR_ZERO(prop); + } + if (!ret) + ret = media_prop_add_prop_u64(prop, "u64", 24); + if (!ret) + ret = media_prop_add_prop_s64(prop, "s64", -24); + if (!ret) + ret = media_pad_add_prop_string(&sd->entity.pads[0], + "string", sd->name); + if (!ret) + ret = media_prop_add_prop_string(prop, "string", "24"); + if (!ret) { + prop = media_prop_add_prop_group(prop, "subgroup"); + ret = PTR_ERR_OR_ZERO(prop); + } + if (!ret) + ret = media_prop_add_prop_string(prop, "string", "substring"); + if (ret) + goto err_clean_m_ent; + return 0; err_clean_m_ent: