MC next generation patches
Subsystems (15)
Re: [PATCH v8 55/55] [media] media-entity.h: document all the structs
In reply to Laurent PinchartEm Mon, 23 Nov 2015 22:19:19 +0200
Laurent Pinchart <[email protected]> escreveu:
Quoted 151 lines
Hi Mauro,
Thank you for the patch.
Quoted 6 lines · On Sunday 06 September 2015 09:03:14 Mauro Carvalho Chehab wrote:
Only a few structs are documented on kernel-doc-nano format (the ones added by the MC next gen patches).
Add a documentation for all structs, and ensure that they'll be producing the documentation at the Kernel's device driver DocBook.
Very good idea ! Please see below for some spelling mistakes or other corrections in addition to the ones pointed out by Hans.
Quoted 7 lines
Signed-off-by Mauro Carvalho Chehab <[email protected]>include/media/media-entity.h +0
-0include/media/media-entity.h enum media_gobj_type { · line 64
Quoted 10 lines
include/media/media-entity.h +2
-0@@ -55,11 +55,13 @@ enum media_gobj_type {/** * struct media_gobj - Define a graph object. * +* @mdev: Pointer to the struct media_device that owns the object * @id: Non-zero object ID identifier. The ID should be unique * inside a media_device, as it is composed by * MEDIA_BITS_PER_TYPE to store the type plus * MEDIA_BITS_PER_LOCAL_ID to store a per-type ID * (called as "local ID"). +* @list: Linked list associated to one of the per-type mdev object lists I'd say "List entry stored in one of the ..." (or "List head" if you prefer).
include/media/media-entity.h struct media_gobj { · line 79
Quoted 9 lines
include/media/media-entity.h +2
-0* * All objects on the media graph should have this struct embedded */ @@ -73,6 +75,28 @@ struct media_gobj {struct media_pipeline { }; +/** +* struct media_link - Define a media link graph object. I think you can drop the "Define" and just say "A media link graph object". Or, rather, "A media graph link object" to mean "a link object part of a media graph".
Same comment for the other structures.
include/media/media-entity.h struct media_gobj { · line 92
Quoted 13 lines
include/media/media-entity.h +13
-0+* +* @graph_obj: Embedded structure containing the media object common data +* @list: Linked list associated with an entity or an interface that +* owns the link. +* @gobj0: Part of an union. Used to get the pointer for the first +* graph_object of the link. +* @source: Part of an union. Used only if the first object (gobj0) is +* a pad. On such case, it represents the source pad. +* @intf: Part of an union. Used only if the first object (gobj0) is +* an interface. +* @gobj1: Part of an union. Used to get the pointer for the second +* graph_object of the link. +* @source: Part of an union. Used only if the second object (gobj0) is s/gobj0/gobj1/
include/media/media-entity.h struct media_gobj { · line 94
Quoted 2 lines
include/media/media-entity.h +2
-0+* a pad. On such case, it represents the sink pad. +* @entity: Part of an union. Used only if the second object (gobj0) is Ditto.
include/media/media-entity.h struct media_gobj { · line 96
Quoted 2 lines
include/media/media-entity.h +2
-0+* an entity. +* @reverse: Pointer to the link for the reverse direction of a pad to pad
Quoted 11 lines
include/media/media-entity.h +3
-1+* link. +* @flags: Link flags, as defined at uapi/media.h (MEDIA_LNK_FL_*) +*/ struct media_link {struct media_gobj graph_obj;struct list_head list;@@ -86,15 +110,23 @@ struct media_link {struct media_pad *sink;struct media_entity *entity; }; -struct media_link *reverse;/* Link in the reverse direction */ include/media/media-entity.h struct media_link { · line 121
Quoted 10 lines
include/media/media-entity.h +7
-1-unsigned long flags;/* Link flags (MEDIA_LNK_FL_*) */ +struct media_link *reverse; +unsigned long flags; }; +/** +* struct media_pad - Define a media pad graph object. +* +* @graph_obj: Embedded structure containing the media object common data +* @entity: Entity where this object belongs "Entity this pad belongs to"
Quoted 19 lines
include/media/media-entity.h +7
-3+* @index: Pad index in the entity pads array, numbered from 0 to n +* @flags: Pad flags, as defined at uapi/media.h (MEDIA_PAD_FL_*) +*/ struct media_pad {struct media_gobj graph_obj;/* must be first field in struct */ -struct media_entity *entity;/* Entity this pad belongs to */ -u16 index;/* Pad index in the entity pads array */ -unsigned long flags;/* Pad flags (MEDIA_PAD_FL_*) */ +struct media_entity *entity; +u16 index; +unsigned long flags; };/** @@ -113,51 +145,73 @@ struct media_entity_operations {int (*link_validate)(struct media_link *link); }; +/** include/media/media-entity.h struct media_entity_operations { · line 158
Quoted 10 lines
include/media/media-entity.h +10
-0+* struct media_entity - Define a media entity graph object. +* +* @graph_obj: Embedded structure containing the media object common data. +* @name: Entity name. +* @type: Entity type, as defined at uapi/media.h (MEDIA_ENT_T_*) +* @revision: Entity revision - OBSOLETE - should be removed soon. +* @flags: Entity flags, as defined at uapi/media.h (MEDIA_ENT_FL_*) +* @group_id: Entity group ID - OBSOLETE - should be removed soon. +* @num_pads: Number of sink and source pads. +* @num_links: Number of existing links, both enabled and disabled. I'd mention there that it includes the backlinks too as it's always clearly apparent.
"Total number of links, forward and back, enabled and disabled"
include/media/media-entity.h struct media_entity_operations { · line 161
Quoted 3 lines
include/media/media-entity.h +3
-0+* @num_backlinks: Number of backlinks +* @pads: Pads array with the size defined by @num_pads. +* @links: Linked list for the data links. "List of data links" or "Linked list of data links" if you want to make it explicit that struct
list_headis a linked list, but I think that should be known to the reader (and have the word link twice in the description for two different purpose can be slightly confusing).include/media/media-entity.h struct media_entity_operations { · line 168
Quoted 7 lines
include/media/media-entity.h +7
-0+* @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. +* @major: Devnode major number (zero if not applicable). Kept just
Quoted 1 line
Maybe s/@major/@dev.major/ (and the same for minor) ?
I don't think it works. The kernel-doc script is not smart enough to handle this kind of things.
Quoted 8 lines
include/media/media-entity.h struct media_entity_operations { · line 171
Quoted 4 lines
include/media/media-entity.h +3
-0+* for backward compatibility. +* @minor: Devnode minor number (zero if not applicable). Kept just +* for backward compatibility. As this is an internal structure I think we should clean code up sooner than later and remove the major and minor fields. It will be confusing for driver authors otherwise. Same for the revision and
group_idfields.
Yes, but we could delay such change for Kernel 4.6. There are already too much changes for 4.5.
Quoted 59 lines
Quoted 59 lines
include/media/media-entity.h +3
-0+* 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.
+ */
structmedia_entity{include/media/media-entity.h +14
-19struct media_gobj graph_obj;/* must be first field in struct */ -const char *name;/* Entity name */ -u32 type;/* Entity type (MEDIA_ENT_T_*) */ -u32 revision;/* Entity revision, driver specific */ -unsigned long flags;/* Entity flags (MEDIA_ENT_FL_*) */ -u32 group_id;/* Entity group ID */ +const char *name; +u32 type; +u32 revision; +unsigned long flags; +u32 group_id; -u16 num_pads;/* Number of sink and source pads */ -u16 num_links;/* Number of existing links, both -* enabled and disabled */ -u16 num_backlinks;/* Number of backlinks */ +u16 num_pads; +u16 num_links; +u16 num_backlinks; -struct media_pad *pads;/* Pads array (num_pads objects) */ -struct list_head links;/* Pad-to-pad links list */ +struct media_pad *pads; +struct list_head links; -const struct media_entity_operations *ops;/* Entity operations */ +const struct media_entity_operations *ops;/* 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. */ -int stream_count;/* Stream count for the entity. */ -int use_count;/* Use count for the entity. */ +int stream_count; +int use_count; -struct media_pipeline *pipe;/* Pipeline this entity belongs to. */ +struct media_pipeline *pipe;union { -/* Node specifications */ struct {u32 major;u32 minor; } dev; - -/* Sub-device specifications */ -/* Nothing needed yet */ } info; };
Quoted 13 lines
Quoted 7 lines
/**
- * structmedia_interface- Define a Kernel API interface
+ * structmedia_interface- Define a media interface graph object *
* @graph_obj: embedded graph object
- * @list: Linked list used to find other interfaces that belong
- * to the same media controllerUsual pet peeve of mine, this should be squashed with the patch that introduces struct
media_interface. Same for the next chunk. I would actually move this patch before any patch that introduces a new structure, just to document the existing structures, and then add documentation for new structures in the patches that introduce them. That would be easier to review.
Too late for doing that. It this patch were reviewed earlier...
Quoted 7 lines
Quoted 7 lines
* @links: List of links pointing to graph entities
* @type: Type of the interface as defined at the
*uapi/media/media.hheader, e. g.include/media/media-entity.h +0
-0@@ -177,7 +231,7 @@ struct media_interface { };
Quoted 7 lines
Quoted 6 lines
include/media/media-entity.h +0
-1/** -* struct media_intf_devnode - Define a Kernel API interface via a device node
+ * structmedia_intf_devnode- Define a media interface via a device node
* @intf: embedded interface object
* @major: Major number of a device node
Fixed the remaining issues.
Regards,
Mauro
Re: [PATCH v8 51/55] [media] remove interface links at media_entity_unregister()
In reply to Mauro Carvalho ChehabInterface links connected to an entity should be removed before being able of removing the entity.
drivers/media/media-device.c +16 -0
@@ -638,14 +638,30 @@ void media_device_unregister_entity(struct media_entity *entity)return ;spin_lock (&mdev->lock); + +/* Remove interface links with this entity on it */ +list_for_each_entry_safe (link, tmp, &mdev->links, graph_obj.list) { +if (media_type (link->gobj1) ==MEDIA_GRAPH_ENTITY + && link->entity == entity) { +media_gobj_remove (&link->graph_obj); +kfree (link); + } + } + +/* Remove all data links that belong to this entity */ list_for_each_entry_safe (link, tmp, &entity->links, list) {media_gobj_remove (&link->graph_obj);list_del (&link->list);kfree (link); } + +/* Remove all pads that belong to this entity */ for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj); + +/* Remove the entity */ media_gobj_remove (&entity->graph_obj); +spin_unlock (&mdev->lock); entity->graph_obj.mdev =NULL ; }
Signature · 1 line
2.4.3
Hans Verkuil
Acked-byRe: [PATCH v8 51/55] [media] remove interface links at media_entity_unregister()
Quoted 2 lines · Mauro Carvalho Chehab
Interface links connected to an entity should be removed before being able of removing the entity.
I'd replace that with:
...before the entity itself can be removed.
Quoted 2 lines
Signed-off-by Mauro Carvalho Chehab <[email protected]>
drivers/media/media-device.c void media_device_unregister_entity(struct media_entity *entity) · line 644
Quoted 13 lines
drivers/media/media-device.c +4
-0@@ -638,14 +638,30 @@ void media_device_unregister_entity(struct media_entity *entity)return ;spin_lock (&mdev->lock); + +/* Remove interface links with this entity on it */ +list_for_each_entry_safe (link, tmp, &mdev->links, graph_obj.list) { + if (media_type(link->gobj1) == MEDIA_GRAPH_ENTITY
I honestly think that the media_type() check can be removed. I think I mentioned it before. Not important enough to withhold the Ack, though.
Quoted 24 lines
drivers/media/media-device.c +12
-0+ && link->entity == entity) { +media_gobj_remove (&link->graph_obj); +kfree (link); + } + } + +/* Remove all data links that belong to this entity */ list_for_each_entry_safe (link, tmp, &entity->links, list) {media_gobj_remove (&link->graph_obj);list_del (&link->list);kfree (link); } + +/* Remove all pads that belong to this entity */ for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj); + +/* Remove the entity */ media_gobj_remove (&entity->graph_obj); +spin_unlock (&mdev->lock); entity->graph_obj.mdev =NULL ; }
Re: [PATCH v8 52/55] [media] media-device: remove interfaces and interface links
In reply to Mauro Carvalho ChehabJust like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there.
drivers/media/media-device.c +16 -1
@@ -574,6 +574,22 @@ void media_device_unregister(struct media_device *mdev) {struct media_entity *entity;struct media_entity *next; +struct media_link *link, *tmp_link; +struct media_interface *intf, *tmp_intf; + +/* Remove interface links from the media device */ +list_for_each_entry_safe (link, tmp_link, &mdev->links, + graph_obj.list) { +media_gobj_remove (&link->graph_obj); +kfree (link); + } + +/* Remove all interfaces from the media device */ +list_for_each_entry_safe (intf, tmp_intf, &mdev->interfaces, + graph_obj.list) { +media_gobj_remove (&intf->graph_obj); +kfree (intf); + }list_for_each_entry_safe (entity, next, &mdev->entities, graph_obj.list)media_device_unregister_entity (entity);
@@ -651,7 +667,6 @@ void media_device_unregister_entity(struct media_entity *entity)/* Remove all data links that belong to this entity */ list_for_each_entry_safe (link, tmp, &entity->links, list) {media_gobj_remove (&link->graph_obj); -list_del (&link->list);kfree (link); }
drivers/media/media-entity.c +4 -0
@@ -206,6 +206,10 @@ void media_gobj_remove(struct media_gobj *gobj)/* Remove the object from mdev list */ list_del (&gobj->list); + +/* Links have their own list - we need to drop them there too */ +if (media_type (gobj) ==MEDIA_GRAPH_LINK ) +list_del (&gobj_to_link (gobj)->list); }/**
include/media/media-entity.h +9 -4
@@ -153,7 +153,7 @@ struct media_entity { };/** -* struct media_intf_devnode - Define a Kernel API interface +* struct media_interface - Define a Kernel API interface * * @graph_obj: embedded graph object * @list: Linked list used to find other interfaces that belong
@@ -163,6 +163,11 @@ struct media_entity {* uapi/media/media.h header, e. g. * MEDIA_INTF_T_* * @flags: Interface flags as defined at uapi/media/media.h +* +* NOTE: As media_device_unregister() will free the address of the +* media_interface, this structure should be embedded as the first +* element of the derived functions, in order for the address to be +* the same. */ struct media_interface {struct media_gobj graph_obj;
@@ -179,11 +184,11 @@ struct media_interface {* @minor: Minor number of a device node */ struct media_intf_devnode { -struct media_interface intf; +struct media_interface intf;/* must be first field in struct */ /* Should match the fields at media_v2_intf_devnode */ -u32 major; -u32 minor; +u32 major; +u32 minor; };static inline u32 media_entity_id (struct media_entity *entity)
Signature · 1 line
2.4.3
Hans Verkuil
Acked-byRe: [PATCH v8 52/55] [media] media-device: remove interfaces and interface links
Quoted 5 lines · Mauro Carvalho Chehab
Just like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 92 lines
drivers/media/media-device.c +16
-1@@ -574,6 +574,22 @@ void media_device_unregister(struct media_device *mdev) {struct media_entity *entity;struct media_entity *next; +struct media_link *link, *tmp_link; +struct media_interface *intf, *tmp_intf; + +/* Remove interface links from the media device */ +list_for_each_entry_safe (link, tmp_link, &mdev->links, + graph_obj.list) { +media_gobj_remove (&link->graph_obj); +kfree (link); + } + +/* Remove all interfaces from the media device */ +list_for_each_entry_safe (intf, tmp_intf, &mdev->interfaces, + graph_obj.list) { +media_gobj_remove (&intf->graph_obj); +kfree (intf); + }list_for_each_entry_safe (entity, next, &mdev->entities, graph_obj.list)media_device_unregister_entity (entity);@@ -651,7 +667,6 @@ void media_device_unregister_entity(struct media_entity *entity)/* Remove all data links that belong to this entity */ list_for_each_entry_safe (link, tmp, &entity->links, list) {media_gobj_remove (&link->graph_obj); -list_del (&link->list);kfree (link); }drivers/media/media-entity.c +4
-0@@ -206,6 +206,10 @@ void media_gobj_remove(struct media_gobj *gobj)/* Remove the object from mdev list */ list_del (&gobj->list); + +/* Links have their own list - we need to drop them there too */ +if (media_type (gobj) ==MEDIA_GRAPH_LINK ) +list_del (&gobj_to_link (gobj)->list); }/** include/media/media-entity.h +9
-4@@ -153,7 +153,7 @@ struct media_entity { };/** -* struct media_intf_devnode - Define a Kernel API interface +* struct media_interface - Define a Kernel API interface * * @graph_obj: embedded graph object * @list: Linked list used to find other interfaces that belong @@ -163,6 +163,11 @@ struct media_entity {* uapi/media/media.h header, e. g. * MEDIA_INTF_T_* * @flags: Interface flags as defined at uapi/media/media.h +* +* NOTE: As media_device_unregister() will free the address of the +* media_interface, this structure should be embedded as the first +* element of the derived functions, in order for the address to be +* the same. */ struct media_interface {struct media_gobj graph_obj;@@ -179,11 +184,11 @@ struct media_interface {* @minor: Minor number of a device node */ struct media_intf_devnode { -struct media_interface intf; +struct media_interface intf;/* must be first field in struct */ /* Should match the fields at media_v2_intf_devnode */ -u32 major; -u32 minor; +u32 major; +u32 minor; };static inline u32 media_entity_id (struct media_entity *entity)
Laurent Pinchart
maintainerRe: [PATCH v8 52/55] [media] media-device: remove interfaces and interface links
In reply to Mauro Carvalho ChehabHi Mauro,
Thank you for the patch.
Quoted 34 lines · On Sunday 06 September 2015 09:03:12 Mauro Carvalho Chehab wrote:
Just like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there.
Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/media-device.c +16
-0@@ -574,6 +574,22 @@ void media_device_unregister(struct media_device *mdev) {struct media_entity *entity;struct media_entity *next; +struct media_link *link, *tmp_link; +struct media_interface *intf, *tmp_intf; + +/* Remove interface links from the media device */ +list_for_each_entry_safe (link, tmp_link, &mdev->links, + graph_obj.list) { +media_gobj_remove (&link->graph_obj); +kfree (link); + } + +/* Remove all interfaces from the media device */ +list_for_each_entry_safe (intf, tmp_intf, &mdev->interfaces, + graph_obj.list) { +media_gobj_remove (&intf->graph_obj); +kfree (intf); + }list_for_each_entry_safe (entity, next, &mdev->entities, graph_obj.list)media_device_unregister_entity (entity);
drivers/media/media-device.c void media_device_unregister_entity(struct media_entity · line 670
Quoted 5 lines
drivers/media/media-device.c +0
-1@@ -651,7 +667,6 @@ void media_device_unregister_entity(struct media_entity *entity) /* Remove all data links that belong to this entity */list_for_each_entry_safe (link, tmp, &entity->links, list) {media_gobj_remove (&link->graph_obj); -list_del (&link->list);kfree (link);
The link has already been freed in media_device_unregister(). You have access- after-free and double-free issues here.
Quoted 7 lines
drivers/media/media-device.c +0
-0}drivers/media/media-entity.c +0
-0
drivers/media/media-entity.c void media_gobj_remove(struct media_gobj *gobj) · line 212
Quoted 7 lines
drivers/media/media-entity.c +4
-0@@ -206,6 +206,10 @@ void media_gobj_remove(struct media_gobj *gobj)/* Remove the object from mdev list */ list_del (&gobj->list); + +/* Links have their own list - we need to drop them there too */ +if (media_type (gobj) ==MEDIA_GRAPH_LINK ) +list_del (&gobj_to_link (gobj)->list);
Please... That's a very bad layering violation. Let's not do that. Generic graph object code should not contain any type-specific code. You can create a media_link_remove() function for links that will remove the link from the entity links list and call media_gobj_remove().
include/media/media-entity.h struct media_entity { · line 156
Quoted 13 lines
drivers/media/media-entity.c +0
-0}/** include/media/media-entity.h +1
-1@@ -153,7 +153,7 @@ struct media_entity { };/** -* struct media_intf_devnode - Define a Kernel API interface +* struct media_interface - Define a Kernel API interface
This belongs to a different patch ;-)
include/media/media-entity.h struct media_entity { · line 170
Quoted 12 lines
include/media/media-entity.h +5
-0* * @graph_obj: embedded graph object * @list: Linked list used to find other interfaces that belong @@ -163,6 +163,11 @@ struct media_entity {* uapi/media/media.h header, e. g. * MEDIA_INTF_T_* * @flags: Interface flags as defined at uapi/media/media.h +* +* NOTE: As media_device_unregister() will free the address of the +* media_interface, this structure should be embedded as the first +* element of the derived functions, in order for the address to be +* the same.
s/NOTE/DIRTY HACK/
Or, much better, let's fix it :-) If you want to be able to destroy graph object without needing to know their type, you can add a destroy operation to the graph objects and have per-type implementations. There's probably other options as well.
Quoted 5 lines
include/media/media-entity.h +0
-0*/ struct media_interface {struct media_gobj graph_obj;@@ -179,11 +184,11 @@ struct media_interface {* @minor: Minor number of a device node
include/media/media-entity.h struct media_interface { · line 191
Quoted 10 lines
include/media/media-entity.h +3
-3*/ struct media_intf_devnode { -struct media_interface intf; +struct media_interface intf;/* must be first field in struct */ /* Should match the fields at media_v2_intf_devnode */ -u32 major; -u32 minor; +u32 major; +u32 minor;
This doesn't belong to this patch either.
Quoted 3 lines
include/media/media-entity.h +0
-0};static inline u32 media_entity_id (struct media_entity *entity)
Signature · 3 lines
Regards, Laurent Pinchart
Re: [PATCH v8 52/55] [media] media-device: remove interfaces and interface links
Em Mon, 23 Nov 2015 23:22:56 +0200
Laurent Pinchart <[email protected]> escreveu:
Quoted 114 lines
Hi Mauro,
Thank you for the patch.
Quoted 34 lines · On Sunday 06 September 2015 09:03:12 Mauro Carvalho Chehab wrote:
Just like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there.
Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/media-device.c +16
-0@@ -574,6 +574,22 @@ void media_device_unregister(struct media_device *mdev) {struct media_entity *entity;struct media_entity *next; +struct media_link *link, *tmp_link; +struct media_interface *intf, *tmp_intf; + +/* Remove interface links from the media device */ +list_for_each_entry_safe (link, tmp_link, &mdev->links, + graph_obj.list) { +media_gobj_remove (&link->graph_obj); +kfree (link); + } + +/* Remove all interfaces from the media device */ +list_for_each_entry_safe (intf, tmp_intf, &mdev->interfaces, + graph_obj.list) { +media_gobj_remove (&intf->graph_obj); +kfree (intf); + }list_for_each_entry_safe (entity, next, &mdev->entities, graph_obj.list)media_device_unregister_entity (entity);drivers/media/media-device.c void media_device_unregister_entity(struct media_entity · line 670
Quoted 5 lines
drivers/media/media-device.c +0
-1@@ -651,7 +667,6 @@ void media_device_unregister_entity(struct media_entity *entity) /* Remove all data links that belong to this entity */list_for_each_entry_safe (link, tmp, &entity->links, list) {media_gobj_remove (&link->graph_obj); -list_del (&link->list);kfree (link);The link has already been freed in
media_device_unregister(). You have access- after-free and double-free issues here.Quoted 7 lines
drivers/media/media-device.c +0
-0}drivers/media/media-entity.c +0
-0drivers/media/media-entity.c void media_gobj_remove(struct media_gobj *gobj) · line 212
Quoted 7 lines
drivers/media/media-entity.c +4
-0@@ -206,6 +206,10 @@ void media_gobj_remove(struct media_gobj *gobj)/* Remove the object from mdev list */ list_del (&gobj->list); + +/* Links have their own list - we need to drop them there too */ +if (media_type (gobj) ==MEDIA_GRAPH_LINK ) +list_del (&gobj_to_link (gobj)->list);Please... That's a very bad layering violation. Let's not do that. Generic graph object code should not contain any type-specific code. You can create a
media_link_remove()function for links that will remove the link from the entity links list and callmedia_gobj_remove().include/media/media-entity.h struct media_entity { · line 156
Quoted 13 lines
drivers/media/media-entity.c +0
-0}/** include/media/media-entity.h +1
-1@@ -153,7 +153,7 @@ struct media_entity { };/** -* struct media_intf_devnode - Define a Kernel API interface +* struct media_interface - Define a Kernel API interface This belongs to a different patch ;-)
include/media/media-entity.h struct media_entity { · line 170
Quoted 12 lines
include/media/media-entity.h +5
-0* * @graph_obj: embedded graph object * @list: Linked list used to find other interfaces that belong @@ -163,6 +163,11 @@ struct media_entity {* uapi/media/media.h header, e. g. * MEDIA_INTF_T_* * @flags: Interface flags as defined at uapi/media/media.h +* +* NOTE: As media_device_unregister() will free the address of the +* media_interface, this structure should be embedded as the first +* element of the derived functions, in order for the address to be +* the same. s/NOTE/DIRTY HACK/
Or, much better, let's fix it :-) If you want to be able to destroy graph object without needing to know their type, you can add a destroy operation to the graph objects and have per-type implementations. There's probably other options as well.
Quoted 10 lines
include/media/media-entity.h +1
-1*/ struct media_interface {struct media_gobj graph_obj;@@ -179,11 +184,11 @@ struct media_interface {* @minor: Minor number of a device node */ struct media_intf_devnode { -struct media_interface intf; +struct media_interface intf;/* must be first field in struct */
Quoted 12 lines
include/media/media-entity.h struct media_interface { · line 191
Quoted 5 lines
include/media/media-entity.h +2
-2/* Should match the fields at media_v2_intf_devnode */ -u32 major; -u32 minor; +u32 major; +u32 minor;This doesn't belong to this patch either.
Quoted 3 lines
include/media/media-entity.h +0
-0};static inline u32 media_entity_id (struct media_entity *entity)
Thanks for review!
Indeed, this patch had several troubles. I reworked on it, fixing the pointed issues. The new version is enclosed.
I tested it with both KASAN and KMEMLEAK, and it is working as expected:
- no memleaks at the media controller core;
- no memory usage on a freed data.
Regards,
Mauro
[media] media-device: remove interfaces and interface links
Just like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there.
--- drivers/media/media-device.c | 30 +++++++++++++++++++----------- drivers/media/media-entity.c | 7 ++++++- include/media/media-entity.h | 1 + 3 files changed, 26 insertions(+), 12 deletions(-)
drivers/media/media-device.c +19 -11
@@ -574,6 +574,17 @@ void media_device_unregister(struct medi {struct media_entity *entity;struct media_entity *next; +struct media_interface *intf, *tmp_intf; + +/* Remove all interfaces from the media device */ +spin_lock (&mdev->lock); +list_for_each_entry_safe (intf, tmp_intf, &mdev->interfaces, + graph_obj.list) { +__media_remove_intf_links (intf); +media_gobj_remove (&intf->graph_obj); +kfree (intf); + } +spin_unlock (&mdev->lock);list_for_each_entry_safe (entity, next, &mdev->entities, graph_obj.list)media_device_unregister_entity (entity);
@@ -633,27 +644,24 @@ void media_device_unregister_entity(struint i;struct media_device *mdev = entity->graph_obj.mdev;struct media_link *link, *tmp; +struct media_interface *intf;if (mdev ==NULL )return ;spin_lock (&mdev->lock); -/* Remove interface links with this entity on it */ -list_for_each_entry_safe (link, tmp, &mdev->links, graph_obj.list) { -if (media_type (link->gobj1) ==MEDIA_GRAPH_ENTITY - && link->entity == entity) { -media_gobj_remove (&link->graph_obj); -kfree (link); +/* Remove all interface links pointing to this entity */ +list_for_each_entry (intf, &mdev->interfaces, graph_obj.list) { +list_for_each_entry_safe (link, tmp, &intf->links, list) { +if (media_type (link->gobj1) ==MEDIA_GRAPH_ENTITY + && link->entity == entity) +__media_remove_intf_link (link); } }/* Remove all data links that belong to this entity */ -list_for_each_entry_safe (link, tmp, &entity->links, list) { -media_gobj_remove (&link->graph_obj); -list_del (&link->list); -kfree (link); - } +__media_entity_remove_links (entity);/* Remove all pads that belong to this entity */ for (i =0 ; i < entity->num_pads; i++)
drivers/media/media-entity.c +6 -1
@@ -674,9 +674,12 @@ static void __media_entity_remove_link(s/* Remove the remote link */ list_del (&rlink->list); +media_gobj_remove (&rlink->graph_obj); +kfree (rlink); }list_del (&link->list); +media_gobj_remove (&link->graph_obj);kfree (link); }
@@ -920,11 +923,13 @@ struct media_link *media_create_intf_linEXPORT_SYMBOL_GPL (media_create_intf_link); -static void __media_remove_intf_link (struct media_link *link) +void __media_remove_intf_link (struct media_link *link) { +list_del (&link->list);media_gobj_remove (&link->graph_obj);kfree (link); } +EXPORT_SYMBOL_GPL (__media_remove_intf_link);void media_remove_intf_link (struct media_link *link) {
include/media/media-entity.h +1 -0
@@ -325,6 +325,7 @@ void media_devnode_remove(struct media_istruct media_link *media_create_intf_link (struct media_entity *entity,struct media_interface *intf,u32 flags); +void __media_remove_intf_link (struct media_link *link);void media_remove_intf_link (struct media_link *link);void __media_remove_intf_links (struct media_interface *intf);void media_remove_intf_links (struct media_interface *intf);
Re: [PATCH v8 42/55] [media] dvb: modify core to implement interfaces/entities at MC new gen
In reply to Mauro Carvalho ChehabThe Media Controller New Generation redefines the types for both interfaces and entities to be used on DVB. Make the needed changes at the DVB core for all interfaces, entities and data and interface links to appear in the graph.
drivers/media/dvb-core/dmxdev.c +2 -2
@@ -1242,9 +1242,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) }dvb_register_device (dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, -DVB_DEVICE_DEMUX ); +DVB_DEVICE_DEMUX , dmxdev->filternum);dvb_register_device (dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, - dmxdev,DVB_DEVICE_DVR ); + dmxdev,DVB_DEVICE_DVR , dmxdev->filternum);dvb_ringbuffer_init (&dmxdev->dvr_buffer,NULL ,8192 );
drivers/media/dvb-core/dvb_ca_en50221.c +1 -1
@@ -1695,7 +1695,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, pubca->private = ca;/* register the DVB device */ - ret =dvb_register_device (dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca,DVB_DEVICE_CA ); + ret =dvb_register_device (dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca,DVB_DEVICE_CA ,0 );if (ret) goto free_slot_info;
drivers/media/dvb-core/dvb_frontend.c +1 -1
@@ -2754,7 +2754,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, fe->dvb->num, fe->id, fe->ops.info.name);dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, - fe,DVB_DEVICE_FRONTEND ); + fe,DVB_DEVICE_FRONTEND ,0 );/* * Initialize the cache to the proper values according with the
drivers/media/dvb-core/dvb_net.c +1 -1
@@ -1503,6 +1503,6 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet, dvbnet->state[i] =0 ;return dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net, - dvbnet,DVB_DEVICE_NET ); + dvbnet,DVB_DEVICE_NET ,0 ); }EXPORT_SYMBOL (dvb_net_init);
drivers/media/dvb-core/dvbdev.c +128 -18
244 lines not on this page · raw message
drivers/media/dvb-core/dvbdev.h +6 -3
@@ -148,9 +148,11 @@ struct dvb_device {const char *name;/* Allocated and filled inside dvbdev.c */ -struct media_entity *entity;struct media_intf_devnode *intf_devnode; -struct media_pad *pads; + +unsigned tsout_num_entities; +struct media_entity *entity, *tsout_entity; +struct media_pad *pads, *tsout_pads;#endif void *priv;
@@ -197,7 +199,8 @@ int dvb_register_device(struct dvb_adapter *adap,struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, - int type); + int type, + int demux_sink_pads);/** * dvb_unregister_device - Unregisters a DVB device
drivers/media/firewire/firedtv-ci.c +1 -1
@@ -241,7 +241,7 @@ int fdtv_ca_register(struct firedtv *fdtv)return -EFAULT ; err =dvb_register_device (&fdtv->adapter, &fdtv->cadev, - &fdtv_ca, fdtv,DVB_DEVICE_CA ); + &fdtv_ca, fdtv,DVB_DEVICE_CA ,0 );if (stat.ca_application_info ==0 )dev_err (fdtv->device,"CaApplicationInfo is not set\n" );
drivers/media/pci/bt8xx/dst_ca.c +2 -1
@@ -705,7 +705,8 @@ struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_struct dvb_device *dvbdev;dprintk (verbose,DST_CA_ERROR ,1 ,"registering DST-CA device" ); -if (dvb_register_device (dvb_adapter, &dvbdev, &dvbdev_ca, dst,DVB_DEVICE_CA ) ==0 ) { +if (dvb_register_device (dvb_adapter, &dvbdev, &dvbdev_ca, dst, +DVB_DEVICE_CA ,0 ) ==0 ) { dst->dst_ca = dvbdev;return dst->dst_ca; }
drivers/media/pci/ddbridge/ddbridge-core.c +1 -1
@@ -1065,7 +1065,7 @@ static int ddb_ci_attach(struct ddb_port *port) port->en, 0, 1); ret =dvb_register_device (&port->output->adap, &port->output->dev, &dvbdev_ci, (void *) port->output, -DVB_DEVICE_SEC ); +DVB_DEVICE_SEC ,0 );return ret; }
drivers/media/pci/ngene/ngene-core.c +1 -1
@@ -1513,7 +1513,7 @@ static int init_channel(struct ngene_channel *chan)set_transfer (&chan->dev->channel[2 ],1 );dvb_register_device (adapter, &chan->ci_dev, &ngene_dvbdev_ci, (void *) chan, -DVB_DEVICE_SEC ); +DVB_DEVICE_SEC ,0 );if (!chan->ci_dev) goto err; }
drivers/media/pci/ttpci/av7110.c +1 -1
@@ -1361,7 +1361,7 @@ static int av7110_register(struct av7110 *av7110)#ifdef CONFIG_DVB_AV7110_OSD dvb_register_device (&av7110->dvb_adapter, &av7110->osd_dev, - &dvbdev_osd, av7110,DVB_DEVICE_OSD ); + &dvbdev_osd, av7110,DVB_DEVICE_OSD ,0 );#endif dvb_net_init (&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);
drivers/media/pci/ttpci/av7110_av.c +2 -2
@@ -1589,10 +1589,10 @@ int av7110_av_register(struct av7110 *av7110)memset (&av7110->video_size,0 ,sizeof (video_size_t));dvb_register_device (&av7110->dvb_adapter, &av7110->video_dev, - &dvbdev_video, av7110,DVB_DEVICE_VIDEO ); + &dvbdev_video, av7110,DVB_DEVICE_VIDEO ,0 );dvb_register_device (&av7110->dvb_adapter, &av7110->audio_dev, - &dvbdev_audio, av7110,DVB_DEVICE_AUDIO ); + &dvbdev_audio, av7110,DVB_DEVICE_AUDIO ,0 );return 0 ; }
drivers/media/pci/ttpci/av7110_ca.c +1 -1
@@ -378,7 +378,7 @@ static struct dvb_device dvbdev_ca = {int av7110_ca_register (struct av7110 *av7110) {return dvb_register_device (&av7110->dvb_adapter, &av7110->ca_dev, - &dvbdev_ca, av7110,DVB_DEVICE_CA ); + &dvbdev_ca, av7110,DVB_DEVICE_CA ,0 ); }void av7110_ca_unregister (struct av7110 *av7110)
Signature · 1 line
2.4.3
Hans Verkuil
Acked-byRe: [PATCH v8 42/55] [media] dvb: modify core to implement interfaces/entities at MC new gen
Quoted 6 lines · Mauro Carvalho Chehab
The Media Controller New Generation redefines the types for both interfaces and entities to be used on DVB. Make the needed changes at the DVB core for all interfaces, entities and data and interface links to appear in the graph.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 440 lines
drivers/media/dvb-core/dmxdev.c +2
-2@@ -1242,9 +1242,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) }dvb_register_device (dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, -DVB_DEVICE_DEMUX ); +DVB_DEVICE_DEMUX , dmxdev->filternum);dvb_register_device (dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, - dmxdev,DVB_DEVICE_DVR ); + dmxdev,DVB_DEVICE_DVR , dmxdev->filternum);dvb_ringbuffer_init (&dmxdev->dvr_buffer,NULL ,8192 );drivers/media/dvb-core/dvb_ca_en50221.c +1
-1@@ -1695,7 +1695,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, pubca->private = ca;/* register the DVB device */ - ret =dvb_register_device (dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca,DVB_DEVICE_CA ); + ret =dvb_register_device (dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca,DVB_DEVICE_CA ,0 );if (ret) goto free_slot_info;drivers/media/dvb-core/dvb_frontend.c +1
-1@@ -2754,7 +2754,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, fe->dvb->num, fe->id, fe->ops.info.name);dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, - fe,DVB_DEVICE_FRONTEND ); + fe,DVB_DEVICE_FRONTEND ,0 );/* * Initialize the cache to the proper values according with the drivers/media/dvb-core/dvb_net.c +1
-1@@ -1503,6 +1503,6 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet, dvbnet->state[i] =0 ;return dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net, - dvbnet,DVB_DEVICE_NET ); + dvbnet,DVB_DEVICE_NET ,0 ); }EXPORT_SYMBOL (dvb_net_init);drivers/media/dvb-core/dvbdev.c +128
-18@@ -180,18 +180,86 @@ skip:return -ENFILE ; } +static void dvb_create_tsout_entity (struct dvb_device *dvbdev, +const char *name,int npads) +{ +#if defined(CONFIG_MEDIA_CONTROLLER_DVB ) +int i, ret =0 ; + + dvbdev->tsout_pads =kcalloc (npads,sizeof (*dvbdev->tsout_pads), +GFP_KERNEL ); +if (!dvbdev->tsout_pads) +return ; + dvbdev->tsout_entity =kcalloc (npads,sizeof (*dvbdev->tsout_entity), +GFP_KERNEL ); +if (!dvbdev->tsout_entity) { +kfree (dvbdev->tsout_pads); + dvbdev->tsout_pads =NULL ; +return ; + } +for (i =0 ; i < npads; i++) { +struct media_pad *pads = &dvbdev->tsout_pads[i]; +struct media_entity *entity = &dvbdev->tsout_entity[i]; + + entity->name =kasprintf (GFP_KERNEL ,"%s #%d" , name, i); +if (!entity->name) { + ret = -ENOMEM ; +break ; + } + + entity->type =MEDIA_ENT_T_DVB_TSOUT ; + pads->flags =MEDIA_PAD_FL_SINK ; + + ret =media_entity_init (entity,1 , pads); +if (ret <0 ) +break ; + + ret =media_device_register_entity (dvbdev->adapter->mdev, + entity); +if (ret <0 ) +break ; + } + +if (!ret) { + dvbdev->tsout_num_entities = npads; +return ; + } + +for (i--; i >=0 ; i--) { +media_device_unregister_entity (&dvbdev->tsout_entity[i]); +kfree (dvbdev->tsout_entity[i].name); + } + +printk (KERN_ERR +"%s: media_device_register_entity failed for %s\n" , + __func__, name); + +kfree (dvbdev->tsout_entity); +kfree (dvbdev->tsout_pads); + dvbdev->tsout_entity =NULL ; + dvbdev->tsout_pads =NULL ; +#endif +} + +#define DEMUX_TSOUT "demux-tsout" +#define DVR_TSOUT "dvr-tsout" +static void dvb_create_media_entity (struct dvb_device *dvbdev, -int type,int minor) +int type,int demux_sink_pads) {#if defined(CONFIG_MEDIA_CONTROLLER_DVB ) -int ret =0 , npads; +int i, ret =0 , npads;switch (type) {case DVB_DEVICE_FRONTEND : npads =2 ;break ; +case DVB_DEVICE_DVR : +dvb_create_tsout_entity (dvbdev,DVR_TSOUT , demux_sink_pads); +return ;case DVB_DEVICE_DEMUX : - npads =2 ; + npads =1 + demux_sink_pads; +dvb_create_tsout_entity (dvbdev,DEMUX_TSOUT , demux_sink_pads);break ;case DVB_DEVICE_CA : npads =2 ;@@ -215,8 +283,6 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,if (!dvbdev->entity)return ; - dvbdev->entity->info.dev.major =DVB_MAJOR ; - dvbdev->entity->info.dev.minor = minor; dvbdev->entity->name = dvbdev->name;if (npads) {@@ -237,7 +303,8 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,case DVB_DEVICE_DEMUX : dvbdev->entity->type =MEDIA_ENT_T_DVB_DEMUX ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; - dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ; +for (i =1 ; i < npads; i++) + dvbdev->pads[i].flags =MEDIA_PAD_FL_SOURCE ;break ;case DVB_DEVICE_CA : dvbdev->entity->type =MEDIA_ENT_T_DVB_CA ;@@ -259,8 +326,16 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,printk (KERN_ERR "%s: media_device_register_entity failed for %s\n" , __func__, dvbdev->entity->name); + +media_device_unregister_entity (dvbdev->entity); +for (i =0 ; i < dvbdev->tsout_num_entities; i++) { +media_device_unregister_entity (&dvbdev->tsout_entity[i]); +kfree (dvbdev->tsout_entity[i].name); + }kfree (dvbdev->pads);kfree (dvbdev->entity); +kfree (dvbdev->tsout_pads); +kfree (dvbdev->tsout_entity); dvbdev->entity =NULL ;return ; }@@ -271,7 +346,8 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, }static void dvb_register_media_device (struct dvb_device *dvbdev, -int type,int minor) +int type,int minor, +unsigned demux_sink_pads) {#if defined(CONFIG_MEDIA_CONTROLLER_DVB )u32 intf_type;@@ -279,7 +355,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,if (!dvbdev->adapter->mdev)return ; -dvb_create_media_entity (dvbdev, type, minor); +dvb_create_media_entity (dvbdev, type, demux_sink_pads);switch (type) {case DVB_DEVICE_FRONTEND :@@ -323,7 +399,8 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, }int dvb_register_device (struct dvb_adapter *adap,struct dvb_device **pdvbdev, -const struct dvb_device *template,void *priv,int type) +const struct dvb_device *template,void *priv,int type, +int demux_sink_pads) {struct dvb_device *dvbdev;struct file_operations *dvbdevfops;@@ -402,7 +479,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,dprintk (KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n" , adap->num, dnames[type], id, minor, minor); -dvb_register_media_device (dvbdev, type, minor); +dvb_register_media_device (dvbdev, type, minor, demux_sink_pads);return 0 ; }@@ -422,9 +499,18 @@ void dvb_unregister_device(struct dvb_device *dvbdev)#if defined(CONFIG_MEDIA_CONTROLLER_DVB )if (dvbdev->entity) { +int i; +media_device_unregister_entity (dvbdev->entity); +for (i =0 ; i < dvbdev->tsout_num_entities; i++) { +media_device_unregister_entity (&dvbdev->tsout_entity[i]); +kfree (dvbdev->tsout_entity[i].name); + } +kfree (dvbdev->entity);kfree (dvbdev->pads); +kfree (dvbdev->tsout_entity); +kfree (dvbdev->tsout_pads); }#endif @@ -440,8 +526,10 @@ void dvb_create_media_graph(struct dvb_adapter *adap) {struct media_device *mdev = adap->mdev;struct media_entity *entity, *tuner =NULL , *demod =NULL ; -struct media_entity *demux =NULL , *dvr =NULL , *ca =NULL ; +struct media_entity *demux =NULL , *ca =NULL ;struct media_interface *intf; +unsigned demux_pad =0 ; +unsigned dvr_pad =0 ;if (!mdev)return ;@@ -457,9 +545,6 @@ void dvb_create_media_graph(struct dvb_adapter *adap)case MEDIA_ENT_T_DVB_DEMUX : demux = entity;break ; -case MEDIA_ENT_T_DVB_TSOUT : - dvr = entity; -break ;case MEDIA_ENT_T_DVB_CA : ca = entity;break ;@@ -471,21 +556,46 @@ void dvb_create_media_graph(struct dvb_adapter *adap)if (demod && demux)media_create_pad_link (demod,1 , demux,0 ,MEDIA_LNK_FL_ENABLED ); - -if (demux && dvr) -media_create_pad_link (demux,1 , dvr,0 ,MEDIA_LNK_FL_ENABLED ); -if (demux && ca)media_create_pad_link (demux,1 , ca,0 ,MEDIA_LNK_FL_ENABLED ); +/* Create demux links for each ringbuffer/pad */ +if (demux) { +media_device_for_each_entity (entity, mdev) { +if (entity->type ==MEDIA_ENT_T_DVB_TSOUT ) { +if (!strncmp (entity->name,DVR_TSOUT , +strlen (DVR_TSOUT ))) +media_create_pad_link (demux, + ++dvr_pad, + entity,0 ,0 ); +if (!strncmp (entity->name,DEMUX_TSOUT , +strlen (DEMUX_TSOUT ))) +media_create_pad_link (demux, + ++demux_pad, + entity,0 ,0 ); + } + } + } +/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ list_for_each_entry (intf, &mdev->interfaces, list) {if (intf->type ==MEDIA_INTF_T_DVB_CA && ca)media_create_intf_link (ca, intf,0 );if (intf->type ==MEDIA_INTF_T_DVB_FE && tuner)media_create_intf_link (tuner, intf,0 ); +if (intf->type ==MEDIA_INTF_T_DVB_DVR && demux)media_create_intf_link (demux, intf,0 ); + +media_device_for_each_entity (entity, mdev) { +if (entity->type ==MEDIA_ENT_T_DVB_TSOUT ) { +if (!strcmp (entity->name,DVR_TSOUT )) +media_create_intf_link (entity, intf,0 ); +if (!strcmp (entity->name,DEMUX_TSOUT )) +media_create_intf_link (entity, intf,0 ); +break ; + } + } } }EXPORT_SYMBOL_GPL (dvb_create_media_graph);drivers/media/dvb-core/dvbdev.h +6
-3@@ -148,9 +148,11 @@ struct dvb_device {const char *name;/* Allocated and filled inside dvbdev.c */ -struct media_entity *entity;struct media_intf_devnode *intf_devnode; -struct media_pad *pads; + +unsigned tsout_num_entities; +struct media_entity *entity, *tsout_entity; +struct media_pad *pads, *tsout_pads;#endif void *priv;@@ -197,7 +199,8 @@ int dvb_register_device(struct dvb_adapter *adap,struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, - int type); + int type, + int demux_sink_pads);/** * dvb_unregister_device - Unregisters a DVB device drivers/media/firewire/firedtv-ci.c +1
-1@@ -241,7 +241,7 @@ int fdtv_ca_register(struct firedtv *fdtv)return -EFAULT ; err =dvb_register_device (&fdtv->adapter, &fdtv->cadev, - &fdtv_ca, fdtv,DVB_DEVICE_CA ); + &fdtv_ca, fdtv,DVB_DEVICE_CA ,0 );if (stat.ca_application_info ==0 )dev_err (fdtv->device,"CaApplicationInfo is not set\n" );drivers/media/pci/bt8xx/dst_ca.c +2
-1@@ -705,7 +705,8 @@ struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_struct dvb_device *dvbdev;dprintk (verbose,DST_CA_ERROR ,1 ,"registering DST-CA device" ); -if (dvb_register_device (dvb_adapter, &dvbdev, &dvbdev_ca, dst,DVB_DEVICE_CA ) ==0 ) { +if (dvb_register_device (dvb_adapter, &dvbdev, &dvbdev_ca, dst, +DVB_DEVICE_CA ,0 ) ==0 ) { dst->dst_ca = dvbdev;return dst->dst_ca; }drivers/media/pci/ddbridge/ddbridge-core.c +1
-1@@ -1065,7 +1065,7 @@ static int ddb_ci_attach(struct ddb_port *port) port->en, 0, 1); ret =dvb_register_device (&port->output->adap, &port->output->dev, &dvbdev_ci, (void *) port->output, -DVB_DEVICE_SEC ); +DVB_DEVICE_SEC ,0 );return ret; }drivers/media/pci/ngene/ngene-core.c +1
-1@@ -1513,7 +1513,7 @@ static int init_channel(struct ngene_channel *chan)set_transfer (&chan->dev->channel[2 ],1 );dvb_register_device (adapter, &chan->ci_dev, &ngene_dvbdev_ci, (void *) chan, -DVB_DEVICE_SEC ); +DVB_DEVICE_SEC ,0 );if (!chan->ci_dev) goto err; }drivers/media/pci/ttpci/av7110.c +1
-1@@ -1361,7 +1361,7 @@ static int av7110_register(struct av7110 *av7110)#ifdef CONFIG_DVB_AV7110_OSD dvb_register_device (&av7110->dvb_adapter, &av7110->osd_dev, - &dvbdev_osd, av7110,DVB_DEVICE_OSD ); + &dvbdev_osd, av7110,DVB_DEVICE_OSD ,0 );#endif dvb_net_init (&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx);drivers/media/pci/ttpci/av7110_av.c +2
-2@@ -1589,10 +1589,10 @@ int av7110_av_register(struct av7110 *av7110)memset (&av7110->video_size,0 ,sizeof (video_size_t));dvb_register_device (&av7110->dvb_adapter, &av7110->video_dev, - &dvbdev_video, av7110,DVB_DEVICE_VIDEO ); + &dvbdev_video, av7110,DVB_DEVICE_VIDEO ,0 );dvb_register_device (&av7110->dvb_adapter, &av7110->audio_dev, - &dvbdev_audio, av7110,DVB_DEVICE_AUDIO ); + &dvbdev_audio, av7110,DVB_DEVICE_AUDIO ,0 );return 0 ; }drivers/media/pci/ttpci/av7110_ca.c +1
-1@@ -378,7 +378,7 @@ static struct dvb_device dvbdev_ca = {int av7110_ca_register (struct av7110 *av7110) {return dvb_register_device (&av7110->dvb_adapter, &av7110->ca_dev, - &dvbdev_ca, av7110,DVB_DEVICE_CA ); + &dvbdev_ca, av7110,DVB_DEVICE_CA ,0 ); }void av7110_ca_unregister (struct av7110 *av7110)
Re: [PATCH v8.2 19/55] [media] media: convert links from array to list
In reply to Mauro Carvalho ChehabThe entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses krealloc() to change the size of the link, with is bad, as it leaves the memory fragmented.
So, convert links into a list.
Also, currently, both source and sink entities need the link at the graph traversal logic inside media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
drivers/media/dvb-core/dvb_frontend.c +3 -6
@@ -622,7 +622,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)struct media_device *mdev = adapter->mdev;struct media_entity *entity, *source;struct media_link *link, *found_link =NULL ; -int i, ret, n_links =0 , active_links =0 ; +int ret, n_links =0 , active_links =0 ; fepriv->pipe_start_entity =NULL ;
@@ -632,8 +632,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) entity = fepriv->dvbdev->entity; fepriv->pipe_start_entity = entity; -for (i =0 ; i < entity->num_links; i++) { - link = &entity->links[i]; +list_for_each_entry (link, &entity->links, list) {if (link->sink->entity == entity) { found_link = link; n_links++;
@@ -659,13 +658,11 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) source = found_link->source->entity; fepriv->pipe_start_entity = source; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity; -if (sink == entity) flags =MEDIA_LNK_FL_ENABLED ;
drivers/media/media-device.c +15 -10
@@ -25,6 +25,7 @@#include <linux/ioctl.h> #include <linux/media.h> #include <linux/types.h> +#include <linux/slab.h> #include <media/media-device.h> #include <media/media-devnode.h>
@@ -150,22 +151,21 @@ static long __media_device_enum_links(struct media_device *mdev, }if (links->links) { -struct media_link_desc __user *ulink; -unsigned int l; +struct media_link *ent_link; +struct media_link_desc __user *ulink = links->links; -for (l =0 , ulink = links->links; l < entity->num_links; l++) { +list_for_each_entry (ent_link, &entity->links, list) {struct media_link_desc link;/* Ignore backlinks. */ -if (entity->links[l].source->entity != entity) +if (ent_link->source->entity != entity)continue ; -memset (&link,0 ,sizeof (link)); -media_device_kpad_to_upad (entity->links[l].source, +media_device_kpad_to_upad (ent_link->source, &link.source); -media_device_kpad_to_upad (entity->links[l].sink, +media_device_kpad_to_upad (ent_link->sink, &link.sink); - link.flags = entity->links[l].flags; + link.flags = ent_link->flags;if (copy_to_user (ulink, &link,sizeof (*ulink)))return -EFAULT ; ulink++;
@@ -437,6 +437,7 @@ 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);spin_lock (&mdev->lock);/* Initialize media_gobj embedded at the entity */
@@ -465,13 +466,17 @@ void media_device_unregister_entity(struct media_entity *entity) {int i;struct media_device *mdev = entity->graph_obj.mdev; +struct media_link *link, *tmp;if (mdev ==NULL )return ;spin_lock (&mdev->lock); -for (i =0 ; i < entity->num_links; i++) -media_gobj_remove (&entity->links[i].graph_obj); +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link); + }for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj);media_gobj_remove (&entity->graph_obj);
drivers/media/media-entity.c +64 -66
249 lines not on this page · raw message
drivers/media/usb/au0828/au0828-core.c +5 -7
@@ -261,13 +261,11 @@ static void au0828_create_media_graph(struct au0828_dev *dev)if (tuner)media_create_pad_link (tuner,0 , decoder,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vdev.entity.links) -media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vbi_dev.entity.links) -media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , -MEDIA_LNK_FL_ENABLED ); +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , +MEDIA_LNK_FL_ENABLED );#endif }
drivers/media/usb/au0828/au0828-video.c +3 -5
@@ -643,7 +643,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)struct media_device *mdev = dev->media_dev;struct media_entity *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev || !dev->decoder)return 0 ;
@@ -655,8 +655,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)* do DVB streaming while the DMA engine is being used for V4L2, * this should be enough for the actual needs. */ -for (i =0 ; i < dev->decoder->num_links; i++) { - link = &dev->decoder->links[i]; +list_for_each_entry (link, &dev->decoder->links, list) {if (link->sink->entity == dev->decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -669,11 +668,10 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == dev->decoder)
drivers/media/usb/cx231xx/cx231xx-video.c +3 -5
@@ -106,7 +106,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)struct media_device *mdev = dev->media_dev;struct media_entity *entity, *decoder =NULL , *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev)return 0 ;
@@ -127,8 +127,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)if (!decoder)return 0 ; -for (i =0 ; i < decoder->num_links; i++) { - link = &decoder->links[i]; +list_for_each_entry (link, &decoder->links, list) {if (link->sink->entity == decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -141,11 +140,10 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == entity)
include/media/media-entity.h +5 -5
@@ -74,6 +74,7 @@ struct media_pipeline {struct media_link {struct media_gobj graph_obj; +struct list_head list;struct media_pad *source;/* Source pad */ struct media_pad *sink;/* Sink pad */ struct media_link *reverse;/* Link in the reverse direction */
@@ -116,10 +117,9 @@ struct media_entity {u16 num_links;/* Number of existing links, both * enabled and disabled */ u16 num_backlinks;/* Number of backlinks */ -u16 max_links;/* Maximum number of links */ -struct media_pad *pads;/* Pads array (num_pads elements) */ -struct media_link *links;/* Links array (max_links elements)*/ +struct media_pad *pads;/* Pads array (num_pads objects) */ +struct list_head links;/* Links list */ const struct media_entity_operations *ops;/* Entity operations */
@@ -213,7 +213,7 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)struct media_entity_graph {struct {struct media_entity *entity; -int link; +struct list_head *link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH ]; DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID);
@@ -247,7 +247,7 @@ void media_gobj_init(struct media_device *mdev,void media_gobj_remove (struct media_gobj *gobj);int media_entity_init (struct media_entity *entity,u16 num_pads, -struct media_pad *pads); +struct media_pad *pads);void media_entity_cleanup (struct media_entity *entity); int media_create_pad_link(struct media_entity *source, u16 source_pad,
Signature · 1 line
2.4.3
Laurent Pinchart
maintainerRe: [PATCH v8.2 19/55] [media] media: convert links from array to list
Hi Mauro,
(Resending as I've replied by mistake to the version of the patch you had sent to the media workshop list only)
Thank you for the patch.
Quoted 10 lines · On Monday 12 October 2015 13:43:13 Mauro Carvalho Chehab wrote:
The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses
krealloc()to change the size of the link, with is bad, as it leaves the memory fragmented.
I agree with the change made in this patch, but I'm not sure if fragmentation is really the issue. I wouldn't be surprised if we ended up with more fragmented memory.
Quoted 8 lines
So, convert links into a list.
Also, currently, both source and sink entities need the link at the graph traversal logic inside
media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.
Quoted 9 lines
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
The media_link structure uses 44 bytes on 32-bit architectures and 84 bytes on 64-bit architecture. It will thus be allocated out of the 64-bytes and 96- bytes pools respectively. That's a 12.5% memory waste on 64-bit architectures and 31.25% on 32-bit architecture. If you're concerned about memory usage (and I think we all should) a linked list is less efficient than an array in this case (and even more so if you take the struct list_head into account).
Quoted 1 line
Change-Id: I558e8f87f200fe5f83ddaafe5560f91f0d906b63
No need to infect mainline with gerrit nonsense
Quoted 10 lines
Signed-off-by Mauro Carvalho Chehab <[email protected]>--- drivers/media/dvb-core/dvb_frontend.c | 9 +-- drivers/media/media-device.c | 25 +++--- drivers/media/media-entity.c | 128 ++++++++++++--------------- drivers/media/usb/au0828/au0828-core.c | 12 ++- drivers/media/usb/au0828/au0828-video.c | 8 +- drivers/media/usb/cx231xx/cx231xx-video.c | 8 +- include/media/media-entity.h | 10 +-- 7 files changed, 97 insertions(+), 103 deletions(-)
[snip]
drivers/media/media-device.c line 28
Quoted 9 lines
drivers/media/media-device.c +1
-0@@ -25,6 +25,7 @@#include <linux/ioctl.h> #include <linux/media.h> #include <linux/types.h> +#include <linux/slab.h>
Could you please keep headers sorted alphabetically ?
Quoted 2 lines
drivers/media/media-device.c +0
-0#include <media/media-device.h> #include <media/media-devnode.h>
[snip]
drivers/media/media-device.c static long __media_device_enum_links(struct · line 155
Quoted 8 lines
drivers/media/media-device.c +2
-2@@ -150,22 +151,21 @@ static long __media_device_enum_links(struct media_device *mdev, }if (links->links) { -struct media_link_desc __user *ulink; -unsigned int l; +struct media_link *ent_link; +struct media_link_desc __user *ulink = links->links;
Might be slightly nitpicking, but I think variables would be more coherent if they were called
struct media_link_desc __user *ulink = links->links;
struct media_link *link;...
Quoted 2 lines
- for (l = 0, ulink =
links->links; l <entity->num_links; l++)
{
Quoted 2 lines
+ list_for_each_entry(ent_link, &entity->links, list) {
struct media_link_desc link;and
struct media_link_desc klink;
here.
Quoted 19 lines
/* Ignore backlinks. */drivers/media/media-device.c +4
-5-if (entity->links[l].source->entity != entity) +if (ent_link->source->entity != entity)continue ; -memset (&link,0 ,sizeof (link)); -media_device_kpad_to_upad (entity->links[l].source, +media_device_kpad_to_upad (ent_link->source, &link.source); -media_device_kpad_to_upad (entity->links[l].sink, +media_device_kpad_to_upad (ent_link->sink, &link.sink); - link.flags = entity->links[l].flags; + link.flags = ent_link->flags;if (copy_to_user (ulink, &link,sizeof (*ulink)))return -EFAULT ; ulink++;@@ -437,6 +437,7 @@ int __must_check media_device_register_entity(struct
media_device*mdev, /* Warn if we apparently re-register an entity */
Quoted 3 lines
WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev;+
INIT_LIST_HEAD(&entity->links);
I'd move this to media_entity_init(). I've spent time wondering how the code could work without crashing during testing as the list wasn't initialized in media_entity_init().
Speaking of testing, have you checked for memory leaks with kmemleak ? Given the extent of the rework I think this should really be tested.
Quoted 9 lines
spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */drivers/media/media-device.c +1
-0@@ -465,13 +466,17 @@ void media_device_unregister_entity(struct media_entity *entity) {int i;struct media_device *mdev = entity->graph_obj.mdev; +struct media_link *link, *tmp;
drivers/media/media-device.c void media_device_unregister_entity(struct · line 478
Quoted 10 lines
drivers/media/media-device.c +4
-2if (mdev ==NULL )return ;spin_lock (&mdev->lock); -for (i =0 ; i < entity->num_links; i++) -media_gobj_remove (&entity->links[i].graph_obj); +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link);
Shouldn't you remove the backlinks too ? How about calling __media_entity_remove_link() to centralize the link removal code ?
Quoted 10 lines
drivers/media/media-device.c +1
-0+ }for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj);media_gobj_remove (&entity->graph_obj);drivers/media/media-entity.c +0
-0@@ -221,21 +221,13 @@ int media_entity_init(struct media_entity *entity, u16 num_pads,
drivers/media/media-entity.c int · line 231
Quoted 10 lines
drivers/media/media-entity.c +0
-6struct media_pad *pads) { -struct media_link *links; -unsigned int max_links = num_pads;unsigned int i; - links =kzalloc (max_links *sizeof (links[0 ]),GFP_KERNEL ); -if (links ==NULL ) -return -ENOMEM ; -
Now that the function doesn't allocate links anymore you should fix its kerneldoc that still mentions preallocation.
Quoted 26 lines
drivers/media/media-entity.c +7
-3entity->group_id =0 ; - entity->max_links = max_links; entity->num_links =0 ; entity->num_backlinks =0 ; entity->num_pads = num_pads; entity->pads = pads; - entity->links = links;for (i =0 ; i < num_pads; i++) { pads[i].entity = entity;@@ -249,7 +241,13 @@ EXPORT_SYMBOL_GPL(media_entity_init);void media_entity_cleanup (struct media_entity *entity) { -kfree (entity->links); +struct media_link *link, *tmp; + +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link); + } }EXPORT_SYMBOL_GPL (media_entity_cleanup);
drivers/media/media-entity.c static void stack_push(struct media_entity_graph *graph, · line 276
Quoted 5 lines
drivers/media/media-entity.c +1
-1@@ -275,7 +273,7 @@ static void stack_push(struct media_entity_graph *graph,return ; } graph->top++; - graph->stack[graph->top].link =0 ; + graph->stack[graph->top].link = (&entity->links)->next;
Anything wrong with entity->links.next ?
drivers/media/media-entity.c void media_entity_graph_walk_start(struct · line 318
Quoted 8 lines
drivers/media/media-entity.c +1
-0graph->stack[graph->top].entity = entity; }@@ -317,6 +315,7 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, }EXPORT_SYMBOL_GPL (media_entity_graph_walk_start ); +
No need for an extra blank line.
drivers/media/media-entity.c media_entity_graph_walk_next(struct media_entity_graph · line 342
Quoted 9 lines
drivers/media/media-entity.c +1
-1/** * media_entity_graph_walk_next - Get the next entity in the graph * @graph: Media graph structure @@ -340,14 +339,16 @@ media_entity_graph_walk_next(struct media_entity_graph*graph) * top of the stack until no more entities on the level can be * found. */ -while (link_top (graph) <stack_top (graph)->num_links) { +while (link_top (graph) != &(stack_top (graph)->links)) {
No need for parentheses around the second operand of !=.
Quoted 13 lines
drivers/media/media-entity.c +4
-2struct media_entity *entity =stack_top (graph); -struct media_link *link = &entity->links[link_top (graph)]; +struct media_link *link;struct media_entity *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) =link_top (graph)->next;continue ; }
[snip]
drivers/media/media-entity.c __must_check int media_entity_pipeline_start(struct · line 399
Quoted 5 lines
drivers/media/media-entity.c +1
-0@@ -395,6 +396,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_device *mdev = entity->graph_obj.mdev;struct media_entity_graph graph;struct media_entity *entity_err = entity; +struct media_link *link;
Nitpicking, I would have placed the variable declaration inside of the while loop, where i was declared.
Quoted 21 lines
drivers/media/media-entity.c +0
-0int ret;mutex_lock (&mdev->graph_mutex);@@ -404,7 +406,6 @@ __must_check int media_entity_pipeline_start(struct
media_entity*entity, while ((entity =media_entity_graph_walk_next(&graph))) { DECLARE_BITMAP(active, entity->num_pads); DECLARE_BITMAP(has_no_links, entity->num_pads);drivers/media/media-entity.c +1
-3-unsigned int i; entity->stream_count++;WARN_ON (entity->pipe && entity->pipe != pipe);@@ -420,8 +421,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,bitmap_zero (active, entity->num_pads);bitmap_fill (has_no_links, entity->num_pads); -for (i =0 ; i < entity->num_links; i++) { -struct media_link *link = &entity->links[i]; +list_for_each_entry (link, &entity->links, list) {struct media_pad *pad = link->sink->entity == entity ? link->sink : link->source;
[snip]
drivers/media/media-entity.c EXPORT_SYMBOL_GPL(media_entity_put); · line 598
Quoted 3 lines
drivers/media/media-entity.c +3
-0+static void __media_entity_remove_link (struct media_entity *entity, +struct media_link *link); +
No forward declaration please, let's reorder functions instead.
Quoted 3 lines
int
media_create_pad_link(structmedia_entity*source, u16source_pad,
structmedia_entity*sink, u16sink_pad, u32 flags)
[snip]
drivers/media/media-entity.c media_create_pad_link(struct media_entity *source, u16 source_pad, · line 651
Quoted 3 lines
drivers/media/media-entity.c +2
-1-void __media_entity_remove_links (struct media_entity *entity) +static void __media_entity_remove_link (struct media_entity *entity, +struct media_link *link)
No need for a __ in the function name, there's not media_entity_remove_link() function.
Quoted 8 lines
{
drivers/media/media-entity.c +6
-1-unsigned int i; +struct media_link *rlink, *tmp; +struct media_entity *remote; +unsigned int r =0 ; + +if (link->source->entity == entity) + remote = link->sink->entity;
drivers/media/media-entity.c media_create_pad_link(struct media_entity *source, u16 source_pad,
Quoted 10 lines
drivers/media/media-entity.c +5
-4+else + remote = link->source->entity; -for (i =0 ; i < entity->num_links; i++) { -struct media_link *link = &entity->links[i]; -struct media_entity *remote; -unsigned int r =0 ; +list_for_each_entry_safe (rlink, tmp, &remote->links, list) { +if (rlink != link->reverse) { + r++;
The variable is incremented here but otherwise never used, you can remove it.
Quoted 12 lines
drivers/media/media-entity.c +3
-6+continue ; + }if (link->source->entity == entity) - remote = link->sink->entity; -else - remote = link->source->entity; + remote->num_backlinks--; -while (r < remote->num_links) { -struct media_link *rlink = &remote->links[r]; -
drivers/media/media-entity.c media_create_pad_link(struct media_entity *source, u16 source_pad,
Quoted 10 lines
drivers/media/media-entity.c +3
-6-if (rlink != link->reverse) { - r++; -continue ; - } +if (--remote->num_links ==0 ) +break ; -if (link->source->entity == entity) - remote->num_backlinks--; +/* Remove the remote link */
Shouldn't you call media_gobj_remove() ?
drivers/media/media-entity.c media_create_pad_link(struct media_entity *source, u16 source_pad, · line 680
Quoted 3 lines
drivers/media/media-entity.c +3
-0+list_del (&rlink->list); +kfree (rlink); + }
And here too ?
Quoted 19 lines
drivers/media/media-entity.c +8
-6+list_del (&link->list); +kfree (link); +} -if (--remote->num_links ==0 ) -break ; +void __media_entity_remove_links (struct media_entity *entity) +{ +struct media_link *link, *tmp; -/* Insert last entry in place of the dropped link. */ - *rlink = remote->links[remote->num_links]; - } - } +list_for_each_entry_safe (link, tmp, &entity->links, list) +__media_entity_remove_link (entity, link); entity->num_links =0 ; entity->num_backlinks =0 ;
Signature · 3 lines
Regards, Laurent Pinchart
Re: [PATCH v8.2 19/55] [media] media: convert links from array to list
Em Mon, 23 Nov 2015 17:37:54 +0200
Laurent Pinchart <[email protected]> escreveu:
Quoted 4 lines
Hi Mauro,
(Resending as I've replied by mistake to the version of the patch you had sent to the media workshop list only)
(resending my answer to your previously sent review to the WS only ML.
The e-mail contents is the same as the previously sent one)
Quoted 3 lines
Thank you for the patch.
Hi Laurent,
I'll be addressing the points below on separate patches, to avoid rebasing it and causing the need for we all (me, Shuah, Javier, Sakari) to re-test everything after patch 24 again. This way, if a regression happens, we know what change to blame ;)
Regards,
Mauro
Em Mon, 23 Nov 2015 15:30:36 +0200
Laurent Pinchart <[email protected]> escreveu:
Quoted 16 lines
Hi Mauro,
Thank you for the patch.
Quoted 10 lines · On Monday 12 October 2015 13:43:13 Mauro Carvalho Chehab wrote:
The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses
krealloc()to change the size of the link, with is bad, as it leaves the memory fragmented.
Quoted 3 lines
I agree with the change made in this patch, but I'm not sure if fragmentation is really the issue. I wouldn't be surprised if we ended up with more fragmented memory.
That would actually depend on how things get allocated/deallocated.
If we discover that fragmentation is actually increasing, we could change the code later to use a lookaside cache.
Quoted 19 lines
Quoted 9 lines
So, convert links into a list.
Also, currently, both source and sink entities need the link at the graph traversal logic inside
media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.Quoted 9 lines
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
Quoted 6 lines
The
media_linkstructure uses 44 bytes on 32-bit architectures and 84 bytes on 64-bit architecture. It will thus be allocated out of the 64-bytes and 96- bytes pools respectively. That's a 12.5% memory waste on 64-bit architectures and 31.25% on 32-bit architecture. If you're concerned about memory usage (and I think we all should) a linked list is less efficient than an array in this case (and even more so if you take the structlist_headinto account).
I doubt that the amount of memory spent at the media controller would actually cause impact, as the size of those structs are a way smaller than the size of video buffers. Anyway, if we found later that this would cause troubles, we can redesign it.
Quoted 4 lines
Quoted 2 lines
Change-Id: I558e8f87f200fe5f83ddaafe5560f91f0d906b63
No need to infect mainline with gerrit nonsense :-)
I'm not using gerrit ;) I'm just adding this crap because the change ID is a good way to detect if a patch is new or not. I have some scripts that use those IDs to detect it, when working with this 80+ patch series.
In any case, the scripts I use to pull patches at the main tree will remove those stuff.
Quoted 14 lines
Quoted 11 lines
Signed-off-by Mauro Carvalho Chehab <[email protected]>--- drivers/media/dvb-core/dvb_frontend.c | 9 +-- drivers/media/media-device.c | 25 +++--- drivers/media/media-entity.c | 128 ++++++++++++--------------- drivers/media/usb/au0828/au0828-core.c | 12 ++- drivers/media/usb/au0828/au0828-video.c | 8 +- drivers/media/usb/cx231xx/cx231xx-video.c | 8 +- include/media/media-entity.h | 10 +-- 7 files changed, 97 insertions(+), 103 deletions(-)[snip]
Quoted 11 lines
drivers/media/media-device.c line 28
Quoted 9 lines
drivers/media/media-device.c +1
-0@@ -25,6 +25,7 @@#include <linux/ioctl.h> #include <linux/media.h> #include <linux/types.h> +#include <linux/slab.h> Could you please keep headers sorted alphabetically ?
Ok, I'll reorder on a later patch.
Quoted 18 lines
Quoted 3 lines
drivers/media/media-device.c +0
-0#include <media/media-device.h> #include <media/media-devnode.h> [snip]
drivers/media/media-device.c static long __media_device_enum_links(struct · line 155
Quoted 8 lines
drivers/media/media-device.c +2
-2@@ -150,22 +151,21 @@ static long __media_device_enum_links(struct media_device *mdev, }if (links->links) { -struct media_link_desc __user *ulink; -unsigned int l; +struct media_link *ent_link; +struct media_link_desc __user *ulink = links->links;Might be slightly nitpicking, but I think variables would be more coherent if they were called
Quoted 2 lines
struct media_link_desc __user *ulink = links->links; struct media_link *link;
Nomenclatures tend to generate endless discussions ;)
IMO, calling it as "link" here is confusing, as it is not clear if this is a Kernel or an Userspace "link"...
Quoted 11 lines
...
drivers/media/media-device.c static long __media_device_enum_links(struct media_device *mdev, · line 158
Quoted 4 lines
drivers/media/media-device.c +1
-1-for (l =0 , ulink = links->links; l < entity->num_links; l++) { +list_for_each_entry (ent_link, &entity->links, list) {struct media_link_desc link;and
struct media_link_desc klink;
and calling it as "klink" is confusing to me ;) as this is the struct defined at the userspace API, and not the struct defined at the Kernelspace ABI.
Perhaps we could call those media_link_desc as "klink_desc" and "ulink_desc", instead.
Quoted 21 lines
here.
Quoted 18 lines
drivers/media/media-device.c +4
-5/* Ignore backlinks. */ -if (entity->links[l].source->entity != entity) +if (ent_link->source->entity != entity)continue ; -memset (&link,0 ,sizeof (link)); -media_device_kpad_to_upad (entity->links[l].source, +media_device_kpad_to_upad (ent_link->source, &link.source); -media_device_kpad_to_upad (entity->links[l].sink, +media_device_kpad_to_upad (ent_link->sink, &link.sink); - link.flags = entity->links[l].flags; + link.flags = ent_link->flags;if (copy_to_user (ulink, &link,sizeof (*ulink)))return -EFAULT ; ulink++;@@ -437,6 +437,7 @@ int __must_check media_device_register_entity(struct
Quoted 8 lines
drivers/media/media-device.c int __must_check media_device_register_entity(struct media_device *mdev, · line 440
Quoted 4 lines
media_device*mdev, /* Warn if we apparently re-register an entity */drivers/media/media-device.c +1
-0WARN_ON (entity->graph_obj.mdev !=NULL ); entity->graph_obj.mdev = mdev; +INIT_LIST_HEAD (&entity->links);I'd move this to
media_entity_init(). I've spent time wondering how the code could work without crashing during testing as the list wasn't initialized inmedia_entity_init().
I wrote this code lots of months ago... I guess there was a reason for this to be here, and not there, but I can't remember why.
I'll give it a try.
Quoted 3 lines
Speaking of testing, have you checked for memory leaks with kmemleak ? Given the extent of the rework I think this should really be tested.
No, I didn't. I'm not sure if au0828 currently passes on kmemleak or not. What I did is I checked that all created graph objects were removed, via enabling the dynamic_prinks at the graph object init/remove functions.
Quoted 13 lines
Quoted 13 lines
drivers/media/media-device.c +1
-0spin_lock (&mdev->lock);/* Initialize media_gobj embedded at the entity */ @@ -465,13 +466,17 @@ void media_device_unregister_entity(struct media_entity *entity) {int i;struct media_device *mdev = entity->graph_obj.mdev; +struct media_link *link, *tmp;if (mdev ==NULL )return ;
Quoted 10 lines
drivers/media/media-device.c void media_device_unregister_entity(struct media_entity *entity) · line 478
Quoted 7 lines
drivers/media/media-device.c +4
-2spin_lock (&mdev->lock); -for (i =0 ; i < entity->num_links; i++) -media_gobj_remove (&entity->links[i].graph_obj); +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link);Shouldn't you remove the backlinks too ? How about calling
__media_entity_remove_link()to centralize the link removal code ?
Yes. I'll use __media_entity_remove_link() here.
Quoted 17 lines
Quoted 17 lines
drivers/media/media-device.c +1
-0+ }for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj);media_gobj_remove (&entity->graph_obj);drivers/media/media-entity.c +0
-2@@ -221,21 +221,13 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads) { - struct media_link *links; -unsigned int max_links = num_pads; unsigned int i;
Quoted 7 lines
drivers/media/media-entity.c int · line 231
Quoted 4 lines
drivers/media/media-entity.c +0
-4- links =kzalloc (max_links *sizeof (links[0 ]),GFP_KERNEL ); -if (links ==NULL ) -return -ENOMEM ; -Now that the function doesn't allocate links anymore you should fix its kerneldoc that still mentions preallocation.
OK.
Quoted 25 lines
Quoted 25 lines
drivers/media/media-entity.c +7
-3entity->group_id =0 ; - entity->max_links = max_links; entity->num_links =0 ; entity->num_backlinks =0 ; entity->num_pads = num_pads; entity->pads = pads; - entity->links = links;for (i =0 ; i < num_pads; i++) { pads[i].entity = entity;@@ -249,7 +241,13 @@ EXPORT_SYMBOL_GPL(media_entity_init);void media_entity_cleanup (struct media_entity *entity) { -kfree (entity->links); +struct media_link *link, *tmp; + +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link); + } }EXPORT_SYMBOL_GPL (media_entity_cleanup);
Quoted 8 lines
drivers/media/media-entity.c static void stack_push(struct media_entity_graph *graph, · line 276
Quoted 6 lines
drivers/media/media-entity.c +1
-1@@ -275,7 +273,7 @@ static void stack_push(struct media_entity_graph *graph,return ; } graph->top++; - graph->stack[graph->top].link =0 ; + graph->stack[graph->top].link = (&entity->links)->next;Anything wrong with
entity->links.next?
No, but I use a regex to find all the occurrences of the previous struct ;)
I'll change it.
Quoted 11 lines
drivers/media/media-entity.c void media_entity_graph_walk_start(struct · line 318
Quoted 9 lines
drivers/media/media-entity.c +1
-0graph->stack[graph->top].entity = entity; }@@ -317,6 +315,7 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, }EXPORT_SYMBOL_GPL (media_entity_graph_walk_start ); +No need for an extra blank line.
OK.
Quoted 11 lines
drivers/media/media-entity.c media_entity_graph_walk_next(struct media_entity_graph · line 342
Quoted 9 lines
drivers/media/media-entity.c +1
-1/** * media_entity_graph_walk_next - Get the next entity in the graph * @graph: Media graph structure @@ -340,14 +339,16 @@ media_entity_graph_walk_next(struct media_entity_graph*graph) * top of the stack until no more entities on the level can be * found. */ -while (link_top (graph) <stack_top (graph)->num_links) { +while (link_top (graph) != &(stack_top (graph)->links)) {No need for parentheses around the second operand of !=.
Ok, I'll remove it.
Quoted 16 lines
Quoted 13 lines
drivers/media/media-entity.c +4
-2struct media_entity *entity =stack_top (graph); -struct media_link *link = &entity->links[link_top (graph)]; +struct media_link *link;struct media_entity *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) =link_top (graph)->next;continue ; }[snip]
Quoted 8 lines
drivers/media/media-entity.c __must_check int media_entity_pipeline_start(struct · line 399
Quoted 5 lines
drivers/media/media-entity.c +1
-0@@ -395,6 +396,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_device *mdev = entity->graph_obj.mdev;struct media_entity_graph graph;struct media_entity *entity_err = entity; +struct media_link *link;Nitpicking, I would have placed the variable declaration inside of the while loop, where i was declared.
OK.
Quoted 24 lines
Quoted 21 lines
drivers/media/media-entity.c +0
-0int ret;mutex_lock (&mdev->graph_mutex);@@ -404,7 +406,6 @@ __must_check int media_entity_pipeline_start(struct
media_entity*entity, while ((entity =media_entity_graph_walk_next(&graph))) {drivers/media/media-entity.c +1
-3DECLARE_BITMAP (active, entity->num_pads);DECLARE_BITMAP (has_no_links, entity->num_pads); -unsigned int i; entity->stream_count++;WARN_ON (entity->pipe && entity->pipe != pipe);@@ -420,8 +421,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,bitmap_zero (active, entity->num_pads);bitmap_fill (has_no_links, entity->num_pads); -for (i =0 ; i < entity->num_links; i++) { -struct media_link *link = &entity->links[i]; +list_for_each_entry (link, &entity->links, list) {struct media_pad *pad = link->sink->entity == entity ? link->sink : link->source;[snip]
Quoted 5 lines
drivers/media/media-entity.c EXPORT_SYMBOL_GPL(media_entity_put); · line 598
Quoted 3 lines
drivers/media/media-entity.c +3
-0+static void __media_entity_remove_link (struct media_entity *entity, +struct media_link *link); +No forward declaration please, let's reorder functions instead.
OK.
Quoted 6 lines
Quoted 4 lines
int
media_create_pad_link(structmedia_entity*source, u16source_pad,
structmedia_entity*sink, u16sink_pad, u32 flags)[snip]
Re: [PATCH v8 14/55] [media] media: add functions to allow creating interfaces
In reply to Mauro Carvalho ChehabHi Mauro,
Quoted 96 lines · Mauro Carvalho Chehab
Interfaces are different than entities: they represent a Kernel<->userspace interaction, while entities represent a piece of hardware/firmware/software that executes a function.
Let's distinguish them by creating a separate structure to store the interfaces.
Later patches should change the existing drivers and logic to split the current interface embedded inside the entity structure (device nodes) into a separate object of the graph.
Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/media-entity.c +49
-0@@ -44,11 +44,41 @@ static inline const char *gobj_type(enum media_gobj_type type)return "pad" ;case MEDIA_GRAPH_LINK :return "link" ; +case MEDIA_GRAPH_INTF_DEVNODE : +return "intf-devnode" ;default :return "unknown" ; } } +static inline const char *intf_type (struct media_interface *intf) +{ +switch (intf->type) { +case MEDIA_INTF_T_DVB_FE : +return "frontend" ; +case MEDIA_INTF_T_DVB_DEMUX : +return "demux" ; +case MEDIA_INTF_T_DVB_DVR : +return "DVR" ; +case MEDIA_INTF_T_DVB_CA : +return "CA" ; +case MEDIA_INTF_T_DVB_NET : +return "dvbnet" ; +case MEDIA_INTF_T_V4L_VIDEO : +return "video" ; +case MEDIA_INTF_T_V4L_VBI : +return "vbi" ; +case MEDIA_INTF_T_V4L_RADIO : +return "radio" ; +case MEDIA_INTF_T_V4L_SUBDEV : +return "v4l2-subdev" ; +case MEDIA_INTF_T_V4L_SWRADIO : +return "swradio" ; +default : +return "unknown-intf" ; + } +}; +static void dev_dbg_obj (const char *event_name,struct media_gobj *gobj) {#if defined(DEBUG ) || defined (CONFIG_DYNAMIC_DEBUG )@@ -84,6 +114,19 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj)"%s: id 0x%08x pad#%d: '%s':%d\n" , event_name, gobj->id,media_localid (gobj), pad->entity->name, pad->index); + break; + } +case MEDIA_GRAPH_INTF_DEVNODE : + { +struct media_interface *intf =gobj_to_intf (gobj); +struct media_intf_devnode *devnode =intf_to_devnode (intf); + +dev_dbg (gobj->mdev->dev, +"%s: id 0x%08x intf_devnode#%d: %s - major: %d, minor: %d\n" , + event_name, gobj->id,media_localid (gobj), +intf_type (intf), + devnode->major, devnode->minor); +break ; } }#endif @@ -119,6 +162,9 @@ void media_gobj_init(struct media_device *mdev,case MEDIA_GRAPH_LINK : gobj->id =media_gobj_gen_id (type, ++mdev->link_id);break ; +case MEDIA_GRAPH_INTF_DEVNODE : + gobj->id =media_gobj_gen_id (type, ++mdev->intf_devnode_id); +break ; }dev_dbg_obj (__func__, gobj); }@@ -793,3 +839,40 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad) }EXPORT_SYMBOL_GPL (media_entity_remote_pad); + + +/* Functions related to the media interface via device nodes */
drivers/media/media-entity.c struct media_pad *media_entity_remote_pad(struct media_pad *pad) · line 854
Quoted 10 lines
drivers/media/media-entity.c +10
-0+ +struct media_intf_devnode *media_devnode_create (struct media_device *mdev, +u32 type,u32 flags, +u32 major,u32 minor, +gfp_t gfp_flags) +{ +struct media_intf_devnode *devnode; +struct media_interface *intf; + + devnode =kzalloc (sizeof (*devnode), gfp_flags);
Do you think the user might want to specify something else then GFP_KERNEL as gfp_flags? If not, I'd keep this internal to the function. It can also be added later if needed.
Quoted 29 lines
drivers/media/media-entity.c +24
-0+if (!devnode) +return NULL ; + + intf = &devnode->intf; + + intf->type = type; + intf->flags = flags; + + devnode->major = major; + devnode->minor = minor; + +media_gobj_init (mdev,MEDIA_GRAPH_INTF_DEVNODE , + &devnode->intf.graph_obj); + +return devnode; +} +EXPORT_SYMBOL_GPL (media_devnode_create); + +void media_devnode_remove (struct media_intf_devnode *devnode) +{ +media_gobj_remove (&devnode->intf.graph_obj); +kfree (devnode); +} +EXPORT_SYMBOL_GPL (media_devnode_remove);include/media/media-device.h +0
-0
include/media/media-device.h struct device; · line 47
Quoted 4 lines
include/media/media-device.h +1
-0@@ -44,6 +44,7 @@ struct device;* @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered +* @intf_devnode_id: Unique ID used on the last interface devnode registered
What's your plan with the graph object IDs? Now we have several ID spaces, one for each object type. Should we export these to the user space, it would have to come together with an object type, or make the IDs unique.
I think I'd favour a flat ID space for all objects; they are reported separately by G_TOPOLOGY IOCTL so the user will gain the type information with the object IDs anyway.
This way, if there's a need to pass the objects back to the kernel, just the ID will be sufficient. Depending on how the API will develop in the future, the kernel may continue to keep a single data structure of graph objects or several data structures.
Quoted 66 lines
include/media/media-device.h +1
-0* @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -73,6 +74,7 @@ struct media_device {u32 entity_id;u32 pad_id;u32 link_id; +u32 intf_devnode_id;struct list_head entities;include/media/media-entity.h +31
-0@@ -36,11 +36,14 @@* @MEDIA_GRAPH_ENTITY: Identify a media entity * @MEDIA_GRAPH_PAD: Identify a media pad * @MEDIA_GRAPH_LINK: Identify a media link +* @MEDIA_GRAPH_INTF_DEVNODE: Identify a media Kernel API interface via +* a device node */ enum media_gobj_type {MEDIA_GRAPH_ENTITY ,MEDIA_GRAPH_PAD ,MEDIA_GRAPH_LINK , +MEDIA_GRAPH_INTF_DEVNODE , };#define MEDIA_BITS_PER_TYPE 8@@ -141,6 +144,34 @@ struct media_entity { } info; }; +/** +* struct media_intf_devnode - Define a Kernel API interface +* +* @graph_obj: embedded graph object +* @type: Type of the interface as defined at the +* uapi/media/media.h header, e. g. +* MEDIA_INTF_T_* +* @flags: Interface flags as defined at uapi/media/media.h +*/ +struct media_interface { +struct media_gobj graph_obj; +u32 type; +u32 flags; +}; + +/** +* struct media_intf_devnode - Define a Kernel API interface via a device node +* +* @intf: embedded interface object +* @major: Major number of a device node +* @minor: Minor number of a device node +*/ +struct media_intf_devnode { +struct media_interface intf; +u32 major; +u32 minor; +}; +static inline u32 media_entity_type (struct media_entity *entity) {return entity->type &MEDIA_ENT_TYPE_MASK ;
include/media/media-entity.h struct media_entity_graph { · line 233
Quoted 5 lines
include/media/media-entity.h +2
-0@@ -198,6 +229,18 @@ struct media_entity_graph {#define gobj_to_link (gobj) \ container_of(gobj, struct media_link, graph_obj) +#define gobj_to_link (gobj) \ + container_of(gobj, struct media_link, graph_obj)
How about media_gobj_to_link() etc.?
Quoted 25 lines
include/media/media-entity.h +15
-0+ +#define gobj_to_pad (gobj) \ + container_of(gobj, struct media_pad, graph_obj) + +#define gobj_to_intf (gobj) \ + container_of(gobj, struct media_interface, graph_obj) + +#define intf_to_devnode (intf) \ + container_of(intf, struct media_intf_devnode, intf) +void media_gobj_init (struct media_device *mdev,enum media_gobj_type type,struct media_gobj *gobj);@@ -229,6 +272,11 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe);void media_entity_pipeline_stop (struct media_entity *entity); +struct media_intf_devnode *media_devnode_create (struct media_device *mdev, +u32 type,u32 flags, +u32 major,u32 minor, +gfp_t gfp_flags); +void media_devnode_remove (struct media_intf_devnode *devnode); #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
Signature · 4 lines
Kind regards, Sakari Ailus e-mail: [email protected] XMPP: [email protected]
Re: [PATCH v8 14/55] [media] media: add functions to allow creating interfaces
Em Wed, 09 Sep 2015 10:34:05 +0300
Sakari Ailus <[email protected]> escreveu:
Quoted 105 lines
Hi Mauro,
Quoted 102 lines · Mauro Carvalho Chehab
Interfaces are different than entities: they represent a Kernel<->userspace interaction, while entities represent a piece of hardware/firmware/software that executes a function.
Let's distinguish them by creating a separate structure to store the interfaces.
Later patches should change the existing drivers and logic to split the current interface embedded inside the entity structure (device nodes) into a separate object of the graph.
Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/media-entity.c +55
-0@@ -44,11 +44,41 @@ static inline const char *gobj_type(enum media_gobj_type type)return "pad" ;case MEDIA_GRAPH_LINK :return "link" ; +case MEDIA_GRAPH_INTF_DEVNODE : +return "intf-devnode" ;default :return "unknown" ; } } +static inline const char *intf_type (struct media_interface *intf) +{ +switch (intf->type) { +case MEDIA_INTF_T_DVB_FE : +return "frontend" ; +case MEDIA_INTF_T_DVB_DEMUX : +return "demux" ; +case MEDIA_INTF_T_DVB_DVR : +return "DVR" ; +case MEDIA_INTF_T_DVB_CA : +return "CA" ; +case MEDIA_INTF_T_DVB_NET : +return "dvbnet" ; +case MEDIA_INTF_T_V4L_VIDEO : +return "video" ; +case MEDIA_INTF_T_V4L_VBI : +return "vbi" ; +case MEDIA_INTF_T_V4L_RADIO : +return "radio" ; +case MEDIA_INTF_T_V4L_SUBDEV : +return "v4l2-subdev" ; +case MEDIA_INTF_T_V4L_SWRADIO : +return "swradio" ; +default : +return "unknown-intf" ; + } +}; +static void dev_dbg_obj (const char *event_name,struct media_gobj *gobj) {#if defined(DEBUG ) || defined (CONFIG_DYNAMIC_DEBUG )@@ -84,6 +114,19 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj)"%s: id 0x%08x pad#%d: '%s':%d\n" , event_name, gobj->id,media_localid (gobj), pad->entity->name, pad->index); + break; + } +case MEDIA_GRAPH_INTF_DEVNODE : + { +struct media_interface *intf =gobj_to_intf (gobj); +struct media_intf_devnode *devnode =intf_to_devnode (intf); + +dev_dbg (gobj->mdev->dev, +"%s: id 0x%08x intf_devnode#%d: %s - major: %d, minor: %d\n" , + event_name, gobj->id,media_localid (gobj), +intf_type (intf), + devnode->major, devnode->minor); +break ; } }#endif @@ -119,6 +162,9 @@ void media_gobj_init(struct media_device *mdev,case MEDIA_GRAPH_LINK : gobj->id =media_gobj_gen_id (type, ++mdev->link_id);break ; +case MEDIA_GRAPH_INTF_DEVNODE : + gobj->id =media_gobj_gen_id (type, ++mdev->intf_devnode_id); +break ; }dev_dbg_obj (__func__, gobj); }@@ -793,3 +839,40 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad) }EXPORT_SYMBOL_GPL (media_entity_remote_pad); + + +/* Functions related to the media interface via device nodes */ + +struct media_intf_devnode *media_devnode_create (struct media_device *mdev, +u32 type,u32 flags, +u32 major,u32 minor, +gfp_t gfp_flags) +{
Quoted 8 lines
drivers/media/media-entity.c struct media_pad *media_entity_remote_pad(struct media_pad *pad) · line 854
Quoted 4 lines
drivers/media/media-entity.c +4
-0+struct media_intf_devnode *devnode; +struct media_interface *intf; + + devnode =kzalloc (sizeof (*devnode), gfp_flags);Do you think the user might want to specify something else then
GFP_KERNELasgfp_flags? If not, I'd keep this internal to the function. It can also be added later if needed.
Yeah, hardly interfaces would need something different than GFP_KERNEL.
I'll change it.
Quoted 30 lines
Quoted 30 lines
drivers/media/media-entity.c +24
-0+if (!devnode) +return NULL ; + + intf = &devnode->intf; + + intf->type = type; + intf->flags = flags; + + devnode->major = major; + devnode->minor = minor; + +media_gobj_init (mdev,MEDIA_GRAPH_INTF_DEVNODE , + &devnode->intf.graph_obj); + +return devnode; +} +EXPORT_SYMBOL_GPL (media_devnode_create); + +void media_devnode_remove (struct media_intf_devnode *devnode) +{ +media_gobj_remove (&devnode->intf.graph_obj); +kfree (devnode); +} +EXPORT_SYMBOL_GPL (media_devnode_remove);include/media/media-device.h +0
-0@@ -44,6 +44,7 @@ struct device;
Quoted 8 lines
include/media/media-device.h struct device; · line 47
Quoted 4 lines
include/media/media-device.h +1
-0* @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered +* @intf_devnode_id: Unique ID used on the last interface devnode registered What's your plan with the graph object IDs? Now we have several ID spaces, one for each object type. Should we export these to the user space, it would have to come together with an object type, or make the IDs unique.
The IDs are always unique, as they're created with 8 bits for type and 24 bits for the per-range ID.
Quoted 3 lines
I think I'd favour a flat ID space for all objects; they are reported separately by
G_TOPOLOGYIOCTL so the user will gain the type information with the object IDs anyway.
Actually, we still need to pass the type somehow to userspace, as we're actually grouping different object ID types at G_TOPOLOGY IOCTL:
- we're grouping different interface types together (currently, only devnode interfaces are there, but we'll add sysfs interfaces and maybe more in the future);
- we're passing data and control links together;
- we're passing connectors and entities together (ok, I used a flag for connectors, but Hans RFC proposed to use a different type for connectors).
Quoted 4 lines
This way, if there's a need to pass the objects back to the kernel, just the ID will be sufficient. Depending on how the API will develop in the future, the kernel may continue to keep a single data structure of graph objects or several data structures.
As I explained earlier, an unique object ID range would break the graph traversal algorithm at the Kernelspace. Several drivers rely on the fact that the entities ID will always be below 32. The graph traversal algorithm assumes that the entity ID will always be below
64. I won't doubt that userspace would also have the same assumption.
So, at least the entity ID should have a separate range than the other objects.
So, we actually have two alternatives only:
1) two ranges:
entity_id; non_entities_id;
I think it is really ugly to call it as "non_entities_id" and I can't find any nice name for such range.
2) one range per type, as proposed.
The drawback of one range per type is that mdev will have 4 ranges, so it will be spending 8 more bytes. It is not much, as we have just one media_device struct per machine.
There are some advantages of using one range per type: all object types will start on 1 and will have sequencial numbers. That makes easier for humans to read. See:
$ ./mc_nextgen_test -i interface intf_devnode#1: video /dev/video0 interface intf_devnode#2: vbi /dev/vbi0 interface intf_devnode#3: v4l2-subdev /dev/v4l-subdev0 interface intf_devnode#4: frontend /dev/dvb/adapter0/frontend0 interface intf_devnode#5: demux /dev/dvb/adapter0/demux0 interface intf_devnode#6: DVR /dev/dvb/adapter0/dvr0 interface intf_devnode#7: dvbnet /dev/dvb/adapter0/net0
$ ./mc_nextgen_test -e entity entity#1: 'ATV decoder' au8522 5-0047, 3 pad(s), 1 sink(s), 2 source(s) entity entity#2: 'tuner' Xceive XC5000, 2 pad(s), 1 sink(s), 1 source(s) entity entity#3: 'RF connector' Television, 1 pad(s), 1 source(s) entity entity#4: 'Composite connector' Composite, 1 pad(s), 1 source(s) entity entity#5: 'S-Video connector' S-Video, 1 pad(s), 1 source(s) entity entity#6: 'I/O' au0828a video, 1 pad(s), 1 sink(s) entity entity#7: 'I/O' au0828a vbi, 1 pad(s), 1 sink(s) entity entity#8: 'DTV demod' Auvitek AU8522 QAM/8VSB Frontend, 2 pad(s), 1 sink(s), 1 source(s) entity entity#9: 'I/O' demux-tsout #0, 1 pad(s), 1 sink(s) entity entity#10: 'I/O' demux-tsout #1, 1 pad(s), 1 sink(s) entity entity#11: 'I/O' demux-tsout #2, 1 pad(s), 1 sink(s) entity entity#12: 'I/O' demux-tsout #3, 1 pad(s), 1 sink(s) entity entity#13: 'I/O' demux-tsout #4, 1 pad(s), 1 sink(s) entity entity#14: 'MPEG-TS demux' dvb-demux, 6 pad(s), 1 sink(s), 5 source(s) entity entity#15: 'I/O' dvr-tsout #0, 1 pad(s), 1 sink(s) entity entity#16: 'I/O' dvr-tsout #1, 1 pad(s), 1 sink(s) entity entity#17: 'I/O' dvr-tsout #2, 1 pad(s), 1 sink(s) entity entity#18: 'I/O' dvr-tsout #3, 1 pad(s), 1 sink(s) entity entity#19: 'I/O' dvr-tsout #4, 1 pad(s), 1 sink(s)
$ ./mc_nextgen_test -l -I interface link link#1: intf_devnode#1 <=> entity#6 [ENABLED] interface link link#2: intf_devnode#2 <=> entity#7 [ENABLED] interface link link#3: intf_devnode#3 <=> entity#2 [ENABLED] interface link link#4: intf_devnode#4 <=> entity#8 [ENABLED] interface link link#5: intf_devnode#5 <=> entity#14 [ENABLED] data link link#6: pad#5 => pad#11 [ENABLED] data link link#8: pad#12 => pad#18 [ENABLED] data link link#10: pad#19 => pad#13 data link link#12: pad#20 => pad#14 data link link#14: pad#21 => pad#15 data link link#16: pad#22 => pad#16 data link link#18: pad#23 => pad#17 data link link#20: pad#19 => pad#24 data link link#22: pad#20 => pad#25 data link link#24: pad#21 => pad#26 data link link#26: pad#22 => pad#27 data link link#28: pad#23 => pad#28 interface link link#30: intf_devnode#4 <=> entity#2 [ENABLED] interface link link#31: intf_devnode#5 <=> entity#9 [ENABLED] interface link link#32: intf_devnode#5 <=> entity#10 [ENABLED] interface link link#33: intf_devnode#5 <=> entity#11 [ENABLED] interface link link#34: intf_devnode#5 <=> entity#12 [ENABLED] interface link link#35: intf_devnode#5 <=> entity#13 [ENABLED] interface link link#36: intf_devnode#6 <=> entity#15 [ENABLED] interface link link#37: intf_devnode#6 <=> entity#16 [ENABLED] interface link link#38: intf_devnode#6 <=> entity#17 [ENABLED] interface link link#39: intf_devnode#6 <=> entity#18 [ENABLED] interface link link#40: intf_devnode#6 <=> entity#19 [ENABLED] data link link#41: pad#5 => pad#1 [ENABLED] data link link#43: pad#2 => pad#9 [ENABLED] data link link#45: pad#3 => pad#10 [ENABLED] data link link#47: pad#6 => pad#4 [ENABLED] data link link#49: pad#7 => pad#1 data link link#51: pad#8 => pad#1
That, IMHO, makes easier for humans to read and if they need, for example, to refer to an interface, use intf#5.
Anyway, I wouldn't mind to change to two ranges, if this is the only way for us to move forward.
Quoted 70 lines
Quoted 70 lines
include/media/media-device.h +1
-0* @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -73,6 +74,7 @@ struct media_device {u32 entity_id;u32 pad_id;u32 link_id; +u32 intf_devnode_id;struct list_head entities;include/media/media-entity.h +31
-0@@ -36,11 +36,14 @@* @MEDIA_GRAPH_ENTITY: Identify a media entity * @MEDIA_GRAPH_PAD: Identify a media pad * @MEDIA_GRAPH_LINK: Identify a media link +* @MEDIA_GRAPH_INTF_DEVNODE: Identify a media Kernel API interface via +* a device node */ enum media_gobj_type {MEDIA_GRAPH_ENTITY ,MEDIA_GRAPH_PAD ,MEDIA_GRAPH_LINK , +MEDIA_GRAPH_INTF_DEVNODE , };#define MEDIA_BITS_PER_TYPE 8@@ -141,6 +144,34 @@ struct media_entity { } info; }; +/** +* struct media_intf_devnode - Define a Kernel API interface +* +* @graph_obj: embedded graph object +* @type: Type of the interface as defined at the +* uapi/media/media.h header, e. g. +* MEDIA_INTF_T_* +* @flags: Interface flags as defined at uapi/media/media.h +*/ +struct media_interface { +struct media_gobj graph_obj; +u32 type; +u32 flags; +}; + +/** +* struct media_intf_devnode - Define a Kernel API interface via a device node +* +* @intf: embedded interface object +* @major: Major number of a device node +* @minor: Minor number of a device node +*/ +struct media_intf_devnode { +struct media_interface intf; +u32 major; +u32 minor; +}; +static inline u32 media_entity_type (struct media_entity *entity) {return entity->type &MEDIA_ENT_TYPE_MASK ;@@ -198,6 +229,18 @@ struct media_entity_graph {#define gobj_to_link (gobj) \ container_of(gobj, struct media_link, graph_obj)
Quoted 4 lines
include/media/media-entity.h struct media_entity_graph { · line 233
Quoted 2 lines
include/media/media-entity.h +2
-0+#define gobj_to_link (gobj) \ + container_of(gobj, struct media_link, graph_obj)How about
media_gobj_to_link()etc.?
I already answered that to a previous e-mail series:
If you do a check at the global defines with:
$ git grep -B1 container_of include/
you'll see that there are two namespaces used for those container_of macros:
1) to_bar
2) foo_to_bar
Those defines are meant to be short, to avoid needing to break long lines whenever those macros are used.
(1) is used when the origin type is always the same.
(2) is used when you might have more than one origin type, as we'll have on interfaces.
I opted for the longest form (2).
Adding "media_" on those macros would require to re-check all lines where those macros are used, breaking several of them into two lines for no good reason, as the only symbols that usually have the "_to_" sub-string inside Kernel are those container_of macros.
I really hate typing long names. Ok, I do when needed, but this is not needed here: there's no namespace conflict. I checked, as everything compiled fine both with allyesconfig/allmodconfig and building for all arm sub-arch that have media drivers.
Quoted 26 lines
Quoted 25 lines
include/media/media-entity.h +15
-0+ +#define gobj_to_pad (gobj) \ + container_of(gobj, struct media_pad, graph_obj) + +#define gobj_to_intf (gobj) \ + container_of(gobj, struct media_interface, graph_obj) + +#define intf_to_devnode (intf) \ + container_of(intf, struct media_intf_devnode, intf) +void media_gobj_init (struct media_device *mdev,enum media_gobj_type type,struct media_gobj *gobj);@@ -229,6 +272,11 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe);void media_entity_pipeline_stop (struct media_entity *entity); +struct media_intf_devnode *media_devnode_create (struct media_device *mdev, +u32 type,u32 flags, +u32 major,u32 minor, +gfp_t gfp_flags); +void media_devnode_remove (struct media_intf_devnode *devnode); #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
Javier Martinez Canillas
Reviewed-byRe: [PATCH v8 14/55] [media] media: add functions to allow creating interfaces
In reply to Mauro Carvalho ChehabQuoted 4 lines · Mauro Carvalho Chehab
Interfaces are different than entities: they represent a Kernel<->userspace interaction, while entities represent a piece of hardware/firmware/software that executes a function.
Quoted 9 lines
Let's distinguish them by creating a separate structure to store the interfaces.
Later patches should change the existing drivers and logic to split the current interface embedded inside the entity structure (device nodes) into a separate object of the graph.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
Best regards,
Javier
Hans Verkuil
Acked-byRe: [PATCH v8 14/55] [media] media: add functions to allow creating interfaces
In reply to Mauro Carvalho ChehabQuoted 4 lines · Mauro Carvalho Chehab
Interfaces are different than entities: they represent a Kernel<->userspace interaction, while entities represent a piece of hardware/firmware/software that executes a function.
Quoted 8 lines
Let's distinguish them by creating a separate structure to store the interfaces.
Later patches should change the existing drivers and logic to split the current interface embedded inside the entity structure (device nodes) into a separate object of the graph.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
But see a small note below:
Quoted 17 lines
drivers/media/media-entity.c +3
-0@@ -44,11 +44,41 @@ static inline const char *gobj_type(enum media_gobj_type type)return "pad" ;case MEDIA_GRAPH_LINK :return "link" ; +case MEDIA_GRAPH_INTF_DEVNODE : +return "intf-devnode" ;default :return "unknown" ; } } +static inline const char *intf_type (struct media_interface *intf)
drivers/media/media-entity.c static inline const char *gobj_type(enum media_gobj_type type) · line 64
Quoted 10 lines
drivers/media/media-entity.c +10
-0+{ +switch (intf->type) { +case MEDIA_INTF_T_DVB_FE : +return "frontend" ; +case MEDIA_INTF_T_DVB_DEMUX : +return "demux" ; +case MEDIA_INTF_T_DVB_DVR : +return "DVR" ; +case MEDIA_INTF_T_DVB_CA : +return "CA" ;
Would lower case be better? "dvr" and "ca"? Although for some reason I feel that "CA" is fine too. Not sure why :-)
What is the name of the associated device node? Upper or lower case? I feel that the name here should match the name of the device node.
Quoted 6 lines
drivers/media/media-entity.c +6
-0+case MEDIA_INTF_T_DVB_NET : +return "dvbnet" ; +case MEDIA_INTF_T_V4L_VIDEO : +return "video" ; +case MEDIA_INTF_T_V4L_VBI : +return "vbi" ;
drivers/media/media-entity.c static inline const char *gobj_type(enum media_gobj_type type) · line 80
Quoted 10 lines
drivers/media/media-entity.c +10
-0+case MEDIA_INTF_T_V4L_RADIO : +return "radio" ; +case MEDIA_INTF_T_V4L_SUBDEV : +return "v4l2-subdev" ; +case MEDIA_INTF_T_V4L_SWRADIO : +return "swradio" ; +default : +return "unknown-intf" ; + } +};
Regards,
Hans
Re: [PATCH v8 14/55] [media] media: add functions to allow creating interfaces
Em Fri, 11 Sep 2015 14:57:41 +0200
Hans Verkuil <[email protected]> escreveu:
Quoted 49 lines · Mauro Carvalho Chehab
Quoted 4 lines
Interfaces are different than entities: they represent a Kernel<->userspace interaction, while entities represent a piece of hardware/firmware/software that executes a function.
Quoted 8 lines
Let's distinguish them by creating a separate structure to store the interfaces.
Later patches should change the existing drivers and logic to split the current interface embedded inside the entity structure (device nodes) into a separate object of the graph.
Signed-off-by Mauro Carvalho Chehab <[email protected]>Acked-by Hans Verkuil <[email protected]>But see a small note below:
Quoted 17 lines
drivers/media/media-entity.c +3
-0@@ -44,11 +44,41 @@ static inline const char *gobj_type(enum media_gobj_type type)return "pad" ;case MEDIA_GRAPH_LINK :return "link" ; +case MEDIA_GRAPH_INTF_DEVNODE : +return "intf-devnode" ;default :return "unknown" ; } } +static inline const char *intf_type (struct media_interface *intf)drivers/media/media-entity.c static inline const char *gobj_type(enum media_gobj_type type) · line 64
Quoted 10 lines
drivers/media/media-entity.c +10
-0+{ +switch (intf->type) { +case MEDIA_INTF_T_DVB_FE : +return "frontend" ; +case MEDIA_INTF_T_DVB_DEMUX : +return "demux" ; +case MEDIA_INTF_T_DVB_DVR : +return "DVR" ; +case MEDIA_INTF_T_DVB_CA : +return "CA" ;Would lower case be better? "dvr" and "ca"? Although for some reason I feel that "CA" is fine too. Not sure why :-)
Quoted 2 lines
What is the name of the associated device node? Upper or lower case? I feel that the name here should match the name of the device node.
Not sure if I answered that before. I opted to use upper case for DVR and CA because both are initials:
DVR - Digital Video Record
CA - Conditional Access
and initials are in upper case, in English.
The devnode names are whatever the udev rules tell ;) The Kernel actually asks to create DVB class devices for the first DVR and CA, located on the first DVB adapter as:
/dev/dvb/adapter0/dvr0 /dev/dvb/adapter0/ca0
I don't mind changing those to lowercase to match the devnames on some future patch, if it is a consensus that making those names matching the device node is a requirement, but, in this case, maybe we should rename the dvb stuff to:
dvb/adapter/foo, in order to better reflect how they'll appear
at devfs.
Please also notice that:
+ case MEDIA_INTF_T_DVB_NET:
+ return "dvbnet";
This is also not the device node. The device node there is actually:
/dev/dvb/adapter0/net0
So, IMHO, it is fine the way it is, as we don't want big names here on those printks.
Regards,
Mauro
PATCH v8 15/55 uapi/media.h: Declare interface types for ALSA
In reply to Mauro Carvalho ChehabDeclare the interface types to be used on alsa for the new G_TOPOLOGY ioctl.
drivers/media/media-entity.c +12 -0
@@ -74,6 +74,18 @@ static inline const char *intf_type(struct media_interface *intf)return "v4l2-subdev" ;case MEDIA_INTF_T_V4L_SWRADIO :return "swradio" ; +case MEDIA_INTF_T_ALSA_PCM_CAPTURE : +return "pcm-capture" ; +case MEDIA_INTF_T_ALSA_PCM_PLAYBACK : +return "pcm-playback" ; +case MEDIA_INTF_T_ALSA_CONTROL : +return "alsa-control" ; +case MEDIA_INTF_T_ALSA_COMPRESS : +return "compress" ; +case MEDIA_INTF_T_ALSA_RAWMIDI : +return "rawmidi" ; +case MEDIA_INTF_T_ALSA_HWDEP : +return "hwdep" ;default :return "unknown-intf" ; }
include/uapi/linux/media.h +8 -0
@@ -171,6 +171,7 @@ struct media_links_enum {#define MEDIA_INTF_T_DVB_BASE 0x00000100#define MEDIA_INTF_T_V4L_BASE 0x00000200 +#define MEDIA_INTF_T_ALSA_BASE 0x00000300/* Interface types */
@@ -186,6 +187,13 @@ struct media_links_enum {#define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3)#define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) +#define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) +#define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) +#define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2) +#define MEDIA_INTF_T_ALSA_COMPRESS (MEDIA_INTF_T_ALSA_BASE + 3) +#define MEDIA_INTF_T_ALSA_RAWMIDI (MEDIA_INTF_T_ALSA_BASE + 4) +#define MEDIA_INTF_T_ALSA_HWDEP (MEDIA_INTF_T_ALSA_BASE + 5) +/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */ #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info)
Signature · 1 line
2.4.3
PATCH v8 16/55 media: Don't accept early-created links
In reply to Mauro Carvalho ChehabLinks are graph objects that represent the links of two already existing objects in the graph.
While with the current implementation, it is possible to create the links earlier, It doesn't make any sense to allow linking two objects when they are not both created.
So, remove the code that would be handling those early-created links and add a BUG_ON() to ensure that.
drivers/media/media-device.c +0 -7
@@ -443,13 +443,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,media_gobj_init (mdev,MEDIA_GRAPH_ENTITY , &entity->graph_obj);list_add_tail (&entity->list, &mdev->entities); -/* -* Initialize objects at the links -* in the case where links got created before entity register -*/ -for (i =0 ; i < entity->num_links; i++) -media_gobj_init (mdev,MEDIA_GRAPH_LINK , - &entity->links[i].graph_obj);/* Initialize objects at the pads */ for (i =0 ; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD,
drivers/media/media-entity.c +2 -0
@@ -161,6 +161,8 @@ void media_gobj_init(struct media_device *mdev,enum media_gobj_type type, struct media_gobj *gobj) { + BUG_ON(!mdev); + gobj->mdev = mdev;/* Create a per-type unique object ID */
Signature · 1 line
2.4.3
Re: [PATCH v8 16/55] [media] media: Don't accept early-created links
Quoted 11 lines · Mauro Carvalho Chehab
Links are graph objects that represent the links of two already existing objects in the graph.
While with the current implementation, it is possible to create the links earlier, It doesn't make any sense to allow linking two objects when they are not both created.
So, remove the code that would be handling those early-created links and add a
BUG_ON()to ensure that.Signed-off-by Mauro Carvalho Chehab <[email protected]>
The code is OK, so:
But shouldn't this go *after* the omap3isp fixes? After this patch the omap3isp will call BUG_ON, and that's not what you want.
It is also not clear if the omap3isp driver is the only one that has this 'create link before objects' problem. I would expect that the omap4 staging driver has the same issue and possibly others as well.
Did someone look at that?
Regards,
Hans
Quoted 33 lines
drivers/media/media-device.c +0
-7@@ -443,13 +443,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,media_gobj_init (mdev,MEDIA_GRAPH_ENTITY , &entity->graph_obj);list_add_tail (&entity->list, &mdev->entities); -/* -* Initialize objects at the links -* in the case where links got created before entity register -*/ -for (i =0 ; i < entity->num_links; i++) -media_gobj_init (mdev,MEDIA_GRAPH_LINK , - &entity->links[i].graph_obj);/* Initialize objects at the pads */ for (i =0 ; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD,drivers/media/media-entity.c +2
-0@@ -161,6 +161,8 @@ void media_gobj_init(struct media_device *mdev,enum media_gobj_type type, struct media_gobj *gobj) { + BUG_ON(!mdev); + gobj->mdev = mdev;/* Create a per-type unique object ID */
Re: [PATCH v8 16/55] [media] media: Don't accept early-created links
Em Mon, 31 Aug 2015 12:30:16 +0200
Hans Verkuil <[email protected]> escreveu:
Quoted 11 lines · Mauro Carvalho Chehab
Quoted 10 lines
Links are graph objects that represent the links of two already existing objects in the graph.
While with the current implementation, it is possible to create the links earlier, It doesn't make any sense to allow linking two objects when they are not both created.
So, remove the code that would be handling those early-created links and add a
BUG_ON()to ensure that.
Quoted 8 lines
Quoted 1 line
Signed-off-by Mauro Carvalho Chehab <[email protected]>The code is OK, so:
Acked-by Hans Verkuil <[email protected]>But shouldn't this go *after* the omap3isp fixes? After this patch the omap3isp will call
BUG_ON, and that's not what you want.
Yes. I'll change the order on my git tree.
Quoted 5 lines
It is also not clear if the omap3isp driver is the only one that has this 'create link before objects' problem. I would expect that the omap4 staging driver has the same issue and possibly others as well.
Did someone look at that?
I guess other drivers are doing the same.
Javier's planning to review the other platform drivers in order to add the needed fixes there too, and to do more tests with some other platform drivers that he has hardware for testing.
Quoted 39 lines
Regards,
Hans
Quoted 33 lines
drivers/media/media-device.c +0
-7@@ -443,13 +443,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,media_gobj_init (mdev,MEDIA_GRAPH_ENTITY , &entity->graph_obj);list_add_tail (&entity->list, &mdev->entities); -/* -* Initialize objects at the links -* in the case where links got created before entity register -*/ -for (i =0 ; i < entity->num_links; i++) -media_gobj_init (mdev,MEDIA_GRAPH_LINK , - &entity->links[i].graph_obj);/* Initialize objects at the pads */ for (i =0 ; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD,drivers/media/media-entity.c +2
-0@@ -161,6 +161,8 @@ void media_gobj_init(struct media_device *mdev,enum media_gobj_type type, struct media_gobj *gobj) { + BUG_ON(!mdev); + gobj->mdev = mdev;/* Create a per-type unique object ID */
Re: [PATCH v8 16/55] [media] media: Don't accept early-created links
Quoted 29 lines · Mauro Carvalho Chehab
Em Mon, 31 Aug 2015 12:30:16 +0200
Hans Verkuil <[email protected]> escreveu:Quoted 11 lines · Mauro Carvalho Chehab
Quoted 10 lines
Links are graph objects that represent the links of two already existing objects in the graph.
While with the current implementation, it is possible to create the links earlier, It doesn't make any sense to allow linking two objects when they are not both created.
So, remove the code that would be handling those early-created links and add a
BUG_ON()to ensure that.Quoted 8 lines
Quoted 1 line
Signed-off-by Mauro Carvalho Chehab <[email protected]>The code is OK, so:
Acked-by Hans Verkuil <[email protected]>But shouldn't this go *after* the omap3isp fixes? After this patch the omap3isp will call
BUG_ON, and that's not what you want.Yes. I'll change the order on my git tree.
Quoted 4 lines
It is also not clear if the omap3isp driver is the only one that has this 'create link before objects' problem. I would expect that the omap4 staging driver has the same issue and possibly others as well.
Quoted 7 lines
Quoted 1 line
Did someone look at that?
I guess other drivers are doing the same.
Javier's planning to review the other platform drivers in order to add the needed fixes there too, and to do more tests with some other platform drivers that he has hardware for testing.
OK, good. Just wanted to know that.
Perhaps it is a good idea to add a TODO list to the cover letter. This would be one item on that list.
Regards,
Hans
Quoted 45 lines
Quoted 37 lines
Regards,
Hans
Quoted 31 lines
drivers/media/media-device.c +0
-7@@ -443,13 +443,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,media_gobj_init (mdev,MEDIA_GRAPH_ENTITY , &entity->graph_obj);list_add_tail (&entity->list, &mdev->entities); -/* -* Initialize objects at the links -* in the case where links got created before entity register -*/ -for (i =0 ; i < entity->num_links; i++) -media_gobj_init (mdev,MEDIA_GRAPH_LINK , - &entity->links[i].graph_obj);/* Initialize objects at the pads */ for (i =0 ; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD,drivers/media/media-entity.c +2
-0@@ -161,6 +161,8 @@ void media_gobj_init(struct media_device *mdev,enum media_gobj_type type, struct media_gobj *gobj) { + BUG_ON(!mdev); + gobj->mdev = mdev;Quoted 3 lines
drivers/media/media-entity.c void media_gobj_init(struct media_device *mdev, · line 168
Quoted 2 lines
drivers/media/media-entity.c +0
-0/* Create a per-type unique object ID */ --
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v8 16/55] [media] media: Don't accept early-created links
Hello Hans,
Quoted 32 lines · Hans Verkuil
Quoted 31 lines · Mauro Carvalho Chehab
Em Mon, 31 Aug 2015 12:30:16 +0200
Hans Verkuil <[email protected]> escreveu:Quoted 11 lines · Mauro Carvalho Chehab
Quoted 10 lines
Links are graph objects that represent the links of two already existing objects in the graph.
While with the current implementation, it is possible to create the links earlier, It doesn't make any sense to allow linking two objects when they are not both created.
So, remove the code that would be handling those early-created links and add a
BUG_ON()to ensure that.Quoted 8 lines
Quoted 1 line
Signed-off-by Mauro Carvalho Chehab <[email protected]>The code is OK, so:
Acked-by Hans Verkuil <[email protected]>But shouldn't this go *after* the omap3isp fixes? After this patch the omap3isp will call
BUG_ON, and that's not what you want.Yes. I'll change the order on my git tree.
Quoted 5 lines
It is also not clear if the omap3isp driver is the only one that has this 'create link before objects' problem. I would expect that the omap4 staging driver has the same issue and possibly others as well.
Did someone look at that?
Quoted 8 lines
Quoted 5 lines
I guess other drivers are doing the same.
Javier's planning to review the other platform drivers in order to add the needed fixes there too, and to do more tests with some other platform drivers that he has hardware for testing.
OK, good. Just wanted to know that.
Yes, the omap4iss driver in staging has a similar logic and thus the same issues than the omap3isp driver. I'll write patches for this as well but I don't have an OMAP4 board here so testing is appreciated.
As Mauro mentioned, I was reviewing the others driver that are creating pad links and found more that are creating links before registering:
drivers/media/usb/uvcdrivers/media/platform/vsp1drivers/media/i2c/smiapp
I'll try to take care of these too.
The other drivers that are creating pad links are doing the right thing AFAICT by registering the entity with the media device before.
Quoted 3 lines
Perhaps it is a good idea to add a TODO list to the cover letter. This would be one item on that list.
A TODO list is a good idea indeed.
Quoted 4 lines
Regards,
Hans
Best regards,
Signature · 3 lines
Javier Martinez Canillas Open Source Group Samsung Research America
Re: [PATCH v8 16/55] [media] media: Don't accept early-created links
Em Mon, 31 Aug 2015 16:39:34 +0200
Javier Martinez Canillas <[email protected]> escreveu:
Quoted 41 lines
Hello Hans,
Quoted 38 lines · Hans Verkuil
Quoted 36 lines · Mauro Carvalho Chehab
Em Mon, 31 Aug 2015 12:30:16 +0200
Hans Verkuil <[email protected]> escreveu:Quoted 11 lines · Mauro Carvalho Chehab
Quoted 10 lines
Links are graph objects that represent the links of two already existing objects in the graph.
While with the current implementation, it is possible to create the links earlier, It doesn't make any sense to allow linking two objects when they are not both created.
So, remove the code that would be handling those early-created links and add a
BUG_ON()to ensure that.Quoted 8 lines
Quoted 1 line
Signed-off-by Mauro Carvalho Chehab <[email protected]>The code is OK, so:
Acked-by Hans Verkuil <[email protected]>But shouldn't this go *after* the omap3isp fixes? After this patch the omap3isp will call
BUG_ON, and that's not what you want.Yes. I'll change the order on my git tree.
Quoted 5 lines
It is also not clear if the omap3isp driver is the only one that has this 'create link before objects' problem. I would expect that the omap4 staging driver has the same issue and possibly others as well.
Did someone look at that?
I guess other drivers are doing the same.
Javier's planning to review the other platform drivers in order to add the needed fixes there too, and to do more tests with some other platform drivers that he has hardware for testing.
Quoted 6 lines
Quoted 2 lines
OK, good. Just wanted to know that.
Yes, the omap4iss driver in staging has a similar logic and thus the same issues than the omap3isp driver. I'll write patches for this as well but I don't have an OMAP4 board here so testing is appreciated.
Well, I can try to test it here on my PandaBoard. Not sure if it will work, as I think that the sensor connector was not properly soldered.
Quoted 25 lines
As Mauro mentioned, I was reviewing the others driver that are creating pad links and found more that are creating links before registering:
drivers/media/usb/uvcdrivers/media/platform/vsp1drivers/media/i2c/smiappI'll try to take care of these too.
The other drivers that are creating pad links are doing the right thing AFAICT by registering the entity with the media device before.
Quoted 3 lines
Perhaps it is a good idea to add a TODO list to the cover letter. This would be one item on that list.
A TODO list is a good idea indeed.
Quoted 4 lines
Regards,
Hans
Best regards,
PATCH v8 17/55 omap3isp: separate links creation from entities init
In reply to Mauro Carvalho ChehabFrom: Javier Martinez Canillas <[email protected]>
The omap3isp driver initializes the entities and creates the pads links before the entities are registered with the media device. This does not work now that object IDs are used to create links so the media_device has to be set.
Split out the pads links creation from the entity initialization so are made after the entities registration.
Series-to: [email protected]
Series-cc: Mauro Carvalho Chehab <[email protected]>
Series-cc: [email protected]
Series-cc: Shuah Khan <[email protected]>
Series-cc: Laurent Pinchart <[email protected]>
Cover-letter:
Patches to test MC next gen patches in OMAP3 ISP
Hello,
This series contains two patches that are needed to test the "[PATCH v7 00/44] MC next generation patches" [0] in a OMAP3 board by using the omap3isp driver.
I found two issues during testing, the first one is that the media_entity_cleanup() function tries to empty the pad links list but the list is initialized when a entity is registered causing a NULL pointer deference error.
The second issue is that the omap3isp driver creates links when the entities are initialized but before the media device is registered causing a NULL pointer deference as well.
Patch 1/1 fixes the first issue by removing the links list empty logic from media_entity_cleanup() since that is made in media_device_unregister_entity() and 2/2 fixes the second issue by separating the entities initialization from the pads links creation after the entities have been registered.
Patch 1/1 was posted before [1] but forgot to add the [media] prefix in the subject line so I'm including in this set again. Sorry about that.
The testing was made on an OMAP3 DM3735 IGEPv2 board and test that the media-ctl -p prints out the topology. More extensive testing will be made but I wanted to share these patches in order to make easier for other people that were looking at it.
[0]: https://www.mail-archive.com/[email protected]/msg91528.html
[1]: https://lkml.org/lkml/2015/8/24/649
Best regards,
Javier
END
drivers/media/platform/omap3isp/isp.c +98 -54
@@ -1933,6 +1933,100 @@ done:return ret; } +/* +* isp_create_pads_links - Pads links creation for the subdevices +* @isp : Pointer to ISP device +* return negative error code or zero on success +*/ +static int isp_create_pads_links (struct isp_device *isp) +{ +int ret; + + ret =omap3isp_csi2_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CSI2 pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_ccp2_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CCP2 pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_ccdc_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CCDC pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_preview_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"Preview pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_resizer_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"Resizer pads links creation failed\n" ); +return ret; + } + +/* Connect the submodules. */ + ret =media_create_pad_link ( + &isp->isp_csi2a.subdev.entity,CSI2_PAD_SOURCE , + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccp2.subdev.entity,CCP2_PAD_SOURCE , + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_prev.subdev.entity,PREV_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_OF , + &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_prev.subdev.entity,PREV_PAD_SOURCE , + &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_aewb.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_af.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_hist.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + +return 0 ; +} +static void isp_cleanup_modules (struct isp_device *isp) {omap3isp_h3a_aewb_cleanup (isp);
@@ -2003,62 +2097,8 @@ static int isp_initialize_modules(struct isp_device *isp) goto error_h3a_af; } -/* Connect the submodules. */ - ret =media_create_pad_link ( - &isp->isp_csi2a.subdev.entity,CSI2_PAD_SOURCE , - &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link ( - &isp->isp_ccp2.subdev.entity,CCP2_PAD_SOURCE , - &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link ( - &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , - &isp->isp_prev.subdev.entity,PREV_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link ( - &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_OF , - &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link ( - &isp->isp_prev.subdev.entity,PREV_PAD_SOURCE , - &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link ( - &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , - &isp->isp_aewb.subdev.entity,0 , -MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link ( - &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , - &isp->isp_af.subdev.entity,0 , -MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link ( - &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , - &isp->isp_hist.subdev.entity,0 , -MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); -if (ret <0 ) - goto error_link; -return 0 ; -error_link: -omap3isp_h3a_af_cleanup (isp); error_h3a_af:omap3isp_h3a_aewb_cleanup (isp); error_h3a_aewb:
@@ -2468,6 +2508,10 @@ static int isp_probe(struct platform_device *pdev)if (ret <0 ) goto error_modules; + ret =isp_create_pads_links (isp); +if (ret <0 ) + goto error_register_entities; + isp->notifier.bound = isp_subdev_notifier_bound; isp->notifier.complete = isp_subdev_notifier_complete;
drivers/media/platform/omap3isp/ispccdc.c +14 -8
@@ -2666,16 +2666,8 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)if (ret <0 ) goto error_video; -/* Connect the CCDC subdev to the video node. */ - ret =media_create_pad_link (&ccdc->subdev.entity,CCDC_PAD_SOURCE_OF , - &ccdc->video_out.video.entity,0 ,0 ); -if (ret <0 ) - goto error_link; -return 0 ; -error_link: -omap3isp_video_cleanup (&ccdc->video_out); error_video:media_entity_cleanup (me);return ret;
@@ -2721,6 +2713,20 @@ int omap3isp_ccdc_init(struct isp_device *isp) }/* +* omap3isp_ccdc_create_pads_links - CCDC pads links creation +* @isp : Pointer to ISP device +* return negative error code or zero on success +*/ +int omap3isp_ccdc_create_pads_links (struct isp_device *isp) +{ +struct isp_ccdc_device *ccdc = &isp->isp_ccdc; + +/* Connect the CCDC subdev to the video node. */ +return media_create_pad_link (&ccdc->subdev.entity,CCDC_PAD_SOURCE_OF , + &ccdc->video_out.video.entity,0 ,0 ); +} + +/* * omap3isp_ccdc_cleanup - CCDC module cleanup. * @isp: Device pointer specific to the OMAP3 ISP. */
drivers/media/platform/omap3isp/ispccdc.h +1 -0
@@ -163,6 +163,7 @@ struct isp_ccdc_device {struct isp_device ;int omap3isp_ccdc_init (struct isp_device *isp); +int omap3isp_ccdc_create_pads_links (struct isp_device *isp);void omap3isp_ccdc_cleanup (struct isp_device *isp);int omap3isp_ccdc_register_entities (struct isp_ccdc_device *ccdc,struct v4l2_device *vdev);
drivers/media/platform/omap3isp/ispccp2.c +14 -8
@@ -1099,16 +1099,8 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)if (ret <0 ) goto error_video; -/* Connect the video node to the ccp2 subdev. */ - ret =media_create_pad_link (&ccp2->video_in.video.entity,0 , - &ccp2->subdev.entity,CCP2_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; -return 0 ; -error_link: -omap3isp_video_cleanup (&ccp2->video_in); error_video:media_entity_cleanup (&ccp2->subdev.entity);return ret;
@@ -1157,6 +1149,20 @@ int omap3isp_ccp2_init(struct isp_device *isp) }/* +* omap3isp_ccp2_create_pads_links - CCP2 pads links creation +* @isp : Pointer to ISP device +* return negative error code or zero on success +*/ +int omap3isp_ccp2_create_pads_links (struct isp_device *isp) +{ +struct isp_ccp2_device *ccp2 = &isp->isp_ccp2; + +/* Connect the video node to the ccp2 subdev. */ +return media_create_pad_link (&ccp2->video_in.video.entity,0 , + &ccp2->subdev.entity,CCP2_PAD_SINK ,0 ); +} + +/* * omap3isp_ccp2_cleanup - CCP2 un-initialization * @isp : Pointer to ISP device */
drivers/media/platform/omap3isp/ispccp2.h +1 -0
@@ -79,6 +79,7 @@ struct isp_ccp2_device {/* Function declarations */ int omap3isp_ccp2_init (struct isp_device *isp); +int omap3isp_ccp2_create_pads_links (struct isp_device *isp);void omap3isp_ccp2_cleanup (struct isp_device *isp);int omap3isp_ccp2_register_entities (struct isp_ccp2_device *ccp2,struct v4l2_device *vdev);
drivers/media/platform/omap3isp/ispcsi2.c +14 -8
@@ -1264,16 +1264,8 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)if (ret <0 ) goto error_video; -/* Connect the CSI2 subdev to the video node. */ - ret =media_create_pad_link (&csi2->subdev.entity,CSI2_PAD_SOURCE , - &csi2->video_out.video.entity,0 ,0 ); -if (ret <0 ) - goto error_link; -return 0 ; -error_link: -omap3isp_video_cleanup (&csi2->video_out); error_video:media_entity_cleanup (&csi2->subdev.entity);return ret;
@@ -1314,6 +1306,20 @@ int omap3isp_csi2_init(struct isp_device *isp) }/* +* omap3isp_csi2_create_pads_links - CSI2 pads links creation +* @isp : Pointer to ISP device +* return negative error code or zero on success +*/ +int omap3isp_csi2_create_pads_links (struct isp_device *isp) +{ +struct isp_csi2_device *csi2a = &isp->isp_csi2a; + +/* Connect the CSI2 subdev to the video node. */ +return media_create_pad_link (&csi2a->subdev.entity,CSI2_PAD_SOURCE , + &csi2a->video_out.video.entity,0 ,0 ); +} + +/* * omap3isp_csi2_cleanup - Routine for module driver cleanup */ void omap3isp_csi2_cleanup (struct isp_device *isp)
drivers/media/platform/omap3isp/ispcsi2.h +1 -0
@@ -148,6 +148,7 @@ struct isp_csi2_device {void omap3isp_csi2_isr (struct isp_csi2_device *csi2);int omap3isp_csi2_reset (struct isp_csi2_device *csi2);int omap3isp_csi2_init (struct isp_device *isp); +int omap3isp_csi2_create_pads_links (struct isp_device *isp);void omap3isp_csi2_cleanup (struct isp_device *isp);void omap3isp_csi2_unregister_entities (struct isp_csi2_device *csi2); int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
drivers/media/platform/omap3isp/isppreview.c +20 -13
@@ -2311,21 +2311,8 @@ static int preview_init_entities(struct isp_prev_device *prev)if (ret <0 ) goto error_video_out; -/* Connect the video nodes to the previewer subdev. */ - ret =media_create_pad_link (&prev->video_in.video.entity,0 , - &prev->subdev.entity,PREV_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link (&prev->subdev.entity,PREV_PAD_SOURCE , - &prev->video_out.video.entity,0 ,0 ); -if (ret <0 ) - goto error_link; -return 0 ; -error_link: -omap3isp_video_cleanup (&prev->video_out); error_video_out:omap3isp_video_cleanup (&prev->video_in); error_video_in:
@@ -2349,6 +2336,26 @@ int omap3isp_preview_init(struct isp_device *isp)return preview_init_entities (prev); } +/* +* omap3isp_preview_create_pads_links - Previewer pads links creation +* @isp : Pointer to ISP device +* return negative error code or zero on success +*/ +int omap3isp_preview_create_pads_links (struct isp_device *isp) +{ +struct isp_prev_device *prev = &isp->isp_prev; +int ret; + +/* Connect the video nodes to the previewer subdev. */ + ret =media_create_pad_link (&prev->video_in.video.entity,0 , + &prev->subdev.entity,PREV_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + +return media_create_pad_link (&prev->subdev.entity,PREV_PAD_SOURCE , + &prev->video_out.video.entity,0 ,0 ); +} +void omap3isp_preview_cleanup (struct isp_device *isp) {struct isp_prev_device *prev = &isp->isp_prev;
drivers/media/platform/omap3isp/isppreview.h +1 -0
@@ -148,6 +148,7 @@ struct isp_prev_device {struct isp_device ;int omap3isp_preview_init (struct isp_device *isp); +int omap3isp_preview_create_pads_links (struct isp_device *isp);void omap3isp_preview_cleanup (struct isp_device *isp); int omap3isp_preview_register_entities(struct isp_prev_device *prv,
drivers/media/platform/omap3isp/ispresizer.c +20 -13
@@ -1755,21 +1755,8 @@ static int resizer_init_entities(struct isp_res_device *res) res->video_out.video.entity.flags |=MEDIA_ENT_FL_DEFAULT ; -/* Connect the video nodes to the resizer subdev. */ - ret =media_create_pad_link (&res->video_in.video.entity,0 , - &res->subdev.entity,RESZ_PAD_SINK ,0 ); -if (ret <0 ) - goto error_link; - - ret =media_create_pad_link (&res->subdev.entity,RESZ_PAD_SOURCE , - &res->video_out.video.entity,0 ,0 ); -if (ret <0 ) - goto error_link; -return 0 ; -error_link: -omap3isp_video_cleanup (&res->video_out); error_video_out:omap3isp_video_cleanup (&res->video_in); error_video_in:
@@ -1793,6 +1780,26 @@ int omap3isp_resizer_init(struct isp_device *isp)return resizer_init_entities (res); } +/* +* omap3isp_resizer_create_pads_links - Resizer pads links creation +* @isp : Pointer to ISP device +* return negative error code or zero on success +*/ +int omap3isp_resizer_create_pads_links (struct isp_device *isp) +{ +struct isp_res_device *res = &isp->isp_res; +int ret; + +/* Connect the video nodes to the resizer subdev. */ + ret =media_create_pad_link (&res->video_in.video.entity,0 , + &res->subdev.entity,RESZ_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + +return media_create_pad_link (&res->subdev.entity,RESZ_PAD_SOURCE , + &res->video_out.video.entity,0 ,0 ); +} +void omap3isp_resizer_cleanup (struct isp_device *isp) {struct isp_res_device *res = &isp->isp_res;
drivers/media/platform/omap3isp/ispresizer.h +1 -0
@@ -119,6 +119,7 @@ struct isp_res_device {struct isp_device ;int omap3isp_resizer_init (struct isp_device *isp); +int omap3isp_resizer_create_pads_links (struct isp_device *isp);void omap3isp_resizer_cleanup (struct isp_device *isp); int omap3isp_resizer_register_entities(struct isp_res_device *res,
Signature · 1 line
2.4.3
Laurent Pinchart
maintainerRe: [PATCH v8 17/55] [media] omap3isp: separate links creation from entities init
Hi Javier and Mauro,
Thank you for the patch.
Quoted 9 lines · On Monday 12 October 2015 13:43:05 Mauro Carvalho Chehab wrote:
From: Javier Martinez Canillas <[email protected]>
The omap3isp driver initializes the entities and creates the pads links before the entities are registered with the media device. This does not work now that object IDs are used to create links so the
media_devicehas to be set.Split out the pads links creation from the entity initialization so are made after the entities registration.
Is a part of this sentence missing ?
Quoted 10 lines
Suggested-by Mauro Carvalho Chehab <[email protected]>Signed-off-by Javier Martinez Canillas <[email protected]>Series-to: [email protected]
Series-cc: Mauro Carvalho Chehab <[email protected]>
Series-cc: [email protected]
Series-cc: Shuah Khan <[email protected]>
Series-cc: Laurent Pinchart <[email protected]>Cover-letter:
I don't think those are known tags. Could you rework the commit message to merge both part into something coherent without copying the cover letter ?
Quoted 31 lines
Patches to test MC next gen patches in OMAP3 ISP
Hello,This series contains two patches that are needed to test the "[PATCH v7 00/44] MC next generation patches" [0] in a OMAP3 board by using the omap3isp driver.
I found two issues during testing, the first one is that the
media_entity_cleanup()function tries to empty the pad links list but the list is initialized when a entity is registered causing a NULL pointer deference error.The second issue is that the omap3isp driver creates links when the entities are initialized but before the media device is registered causing a NULL pointer deference as well.
Patch 1/1 fixes the first issue by removing the links list empty logic from
media_entity_cleanup()since that is made inmedia_device_unregister_entity()and 2/2 fixes the second issue by separating the entities initialization from the pads links creation after the entities have been registered.Patch 1/1 was posted before [1] but forgot to add the [media] prefix in the subject line so I'm including in this set again. Sorry about that.
The testing was made on an OMAP3 DM3735 IGEPv2 board and test that the media-ctl -p prints out the topology. More extensive testing will be made but I wanted to share these patches in order to make easier for other people that were looking at it.
Quoted 8 lines
[0]: https://www.mail-archive.com/[email protected]/msg91528.html
[1]: https://lkml.org/lkml/2015/8/24/649Best regards,
Javier
ENDChange-Id: I44abb9b67d6378cbd54ba4e0673a5d6d5721fc77
No gerrit craziness please.
Quoted 20 lines
--- drivers/media/platform/omap3isp/isp.c | 152 ++++++++++++++---------- drivers/media/platform/omap3isp/ispccdc.c | 22 ++-- drivers/media/platform/omap3isp/ispccdc.h | 1 + drivers/media/platform/omap3isp/ispccp2.c | 22 ++-- drivers/media/platform/omap3isp/ispccp2.h | 1 + drivers/media/platform/omap3isp/ispcsi2.c | 22 ++-- drivers/media/platform/omap3isp/ispcsi2.h | 1 + drivers/media/platform/omap3isp/isppreview.c | 33 +++--- drivers/media/platform/omap3isp/isppreview.h | 1 + drivers/media/platform/omap3isp/ispresizer.c | 33 +++--- drivers/media/platform/omap3isp/ispresizer.h | 1 + 11 files changed, 185 insertions(+), 104 deletions(-)(quoted diff) +0
-0
b/drivers/media/platform/omap3isp/isp.cindexaa13b17d19a0..b8f6f81d2db2100644
drivers/media/platform/omap3isp/isp.c done: · line 1938
Quoted 6 lines
drivers/media/platform/omap3isp/isp.c +3
-0@@ -1933,6 +1933,100 @@ done:return ret; } +/* +* isp_create_pads_links - Pads links creation for the subdevices +* @isp : Pointer to ISP device
Missing blank line here. And missing description of the function for that matter. You can use
"This function creates all links between ISP internal and external entities."
drivers/media/platform/omap3isp/isp.c done: · line 1939
Quoted 1 line
drivers/media/platform/omap3isp/isp.c +1
-0+* return negative error code or zero on success
In kerneldoc style that should be
Return: A negative error code on failure or zero on success. Possible error codes are those returned by media_create_pad_link().
Same for the other functions below, the return line should start with "Return:".
drivers/media/platform/omap3isp/isp.c done: · line 1941
Quoted 2 lines
drivers/media/platform/omap3isp/isp.c +2
-0+*/ +static int isp_create_pads_links (struct isp_device *isp)
This should be called isp_create_pad_links() if you want the include the pad prefix, but I'd just name it isp_create_links() as the driver doesn't handle any other kind of links. Same for all the *_create_pads_links() functions below.
drivers/media/platform/omap3isp/isp.c done: · line 1947
Quoted 6 lines
drivers/media/platform/omap3isp/isp.c +6
-0+{ +int ret; + + ret =omap3isp_csi2_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CSI2 pads links creation failed\n" );
That's lots of error strings. You would save memory by turning the messages into "%s pads links creation failed\n", "CSI2" as the compiler will then avoid multiple copies of the first string.
I would actually remove the messages as the only source of error is a memory allocation failure, which will already print a message. You could add a single dev_err() in the location where isp_create_pads_links() is called if you want to.
Quoted 18 lines
drivers/media/platform/omap3isp/isp.c +18
-0+return ret; + } + + ret =omap3isp_ccp2_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CCP2 pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_ccdc_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CCDC pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_preview_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"Preview pads links creation failed\n" );
drivers/media/platform/omap3isp/isp.c done: · line 1975
Quoted 10 lines
drivers/media/platform/omap3isp/isp.c +10
-0+return ret; + } + + ret =omap3isp_resizer_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"Resizer pads links creation failed\n" ); +return ret; + } + +/* Connect the submodules. */
I'd write "Create links between entities." and add a comment at the beginning of the function that states "Create links between entities and video nodes.".
Quoted 53 lines
drivers/media/platform/omap3isp/isp.c +53
-0+ ret =media_create_pad_link ( + &isp->isp_csi2a.subdev.entity,CSI2_PAD_SOURCE , + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccp2.subdev.entity,CCP2_PAD_SOURCE , + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_prev.subdev.entity,PREV_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_OF , + &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_prev.subdev.entity,PREV_PAD_SOURCE , + &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_aewb.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_af.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_hist.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + +return 0 ; +}
[snip]
Quoted 21 lines
drivers/media/platform/omap3isp/isp.c +4
-0@@ -2468,6 +2508,10 @@ static int isp_probe(struct platform_device *pdev)if (ret <0 ) goto error_modules; + ret =isp_create_pads_links (isp); +if (ret <0 ) + goto error_register_entities; + isp->notifier.bound = isp_subdev_notifier_bound; isp->notifier.complete = isp_subdev_notifier_complete;(quoted diff) +0
-0
b/drivers/media/platform/omap3isp/ispccdc.cindex27555e4f4aa8..9a811f5741fa100644drivers/media/platform/omap3isp/ispccdc.c +0
-1@@ -2666,16 +2666,8 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) if (ret < 0) goto error_video; -/* Connect the CCDC subdev to the video node. */
drivers/media/platform/omap3isp/ispccdc.c static int ccdc_init_entities(struct isp_ccdc_device · line 2671
Quoted 10 lines
drivers/media/platform/omap3isp/ispccdc.c +0
-7- ret =media_create_pad_link (&ccdc->subdev.entity,CCDC_PAD_SOURCE_OF , - &ccdc->video_out.video.entity,0 ,0 ); -if (ret <0 ) - goto error_link; -return 0 ; -error_link: -omap3isp_video_cleanup (&ccdc->video_out); error_video:
As there's now a single error label I'd rename it to just "error:". Same comment for the other ISP modules.
Quoted 8 lines
drivers/media/platform/omap3isp/ispccdc.c +2
-0media_entity_cleanup (me);return ret;@@ -2721,6 +2713,20 @@ int omap3isp_ccdc_init(struct isp_device *isp) }/* +* omap3isp_ccdc_create_pads_links - CCDC pads links creation +* @isp : Pointer to ISP device
drivers/media/platform/omap3isp/ispccdc.c int omap3isp_ccdc_init(struct isp_device *isp) · line 2727
Quoted 10 lines
drivers/media/platform/omap3isp/ispccdc.c +10
-0+* return negative error code or zero on success +*/ +int omap3isp_ccdc_create_pads_links (struct isp_device *isp) +{ +struct isp_ccdc_device *ccdc = &isp->isp_ccdc; + +/* Connect the CCDC subdev to the video node. */ +return media_create_pad_link (&ccdc->subdev.entity,CCDC_PAD_SOURCE_OF , + &ccdc->video_out.video.entity,0 ,0 ); +}
Given that this function and the other similar functions for other modules just link entities and video devices, it could make sense to inline them directly in the caller in order to group all the link create calls together. No strong opinion though, I'll leave it up to you and on whether you want to fix the kerneldoc or remove it ;-)
Quoted 5 lines
drivers/media/platform/omap3isp/ispccdc.c +2
-0+ +/* * omap3isp_ccdc_cleanup - CCDC module cleanup. * @isp: Device pointer specific to the OMAP3 ISP. */
[snip]
Signature · 3 lines
Regards, Laurent Pinchart
Re: [PATCH v8 17/55] [media] omap3isp: separate links creation from entities init
Hello Laurent,
Quoted 4 lines · Laurent Pinchart
Hi Javier and Mauro,
Thank you for the patch.
Thanks for your feedback.
Quoted 8 lines · On Monday 12 October 2015 13:43:05 Mauro Carvalho Chehab wrote:
Quoted 7 lines
From: Javier Martinez Canillas <[email protected]>
The omap3isp driver initializes the entities and creates the pads links before the entities are registered with the media device. This does not work now that object IDs are used to create links so the
media_devicehas to be set.
Quoted 5 lines
Quoted 2 lines
Split out the pads links creation from the entity initialization so are made after the entities registration.
Is a part of this sentence missing ?
The sentence is not clear indeed, I think it should be something like:
"so the links are created after the entities have been registered with the media device"
Quoted 9 lines
Quoted 9 lines
Suggested-by Mauro Carvalho Chehab <[email protected]>Signed-off-by Javier Martinez Canillas <[email protected]>Series-to: [email protected]
Series-cc: Mauro Carvalho Chehab <[email protected]>
Series-cc: [email protected]
Series-cc: Shuah Khan <[email protected]>
Series-cc: Laurent Pinchart <[email protected]>
Quoted 5 lines
Quoted 1 line
Cover-letter:
I don't think those are known tags. Could you rework the commit message to merge both part into something coherent without copying the cover letter ?
Yes, sorry about that. I use patman to manage and post my patches and forgot to remove the patman tags before handling the patches to Mauro.
I mentioned to him already and he told me that would strip the tags before pushing to the media tree or posting the patches again.
[remove left over cover letter from a different series]
Quoted 5 lines
Quoted 2 lines
Change-Id: I44abb9b67d6378cbd54ba4e0673a5d6d5721fc77
No gerrit craziness please.
I believe this is something similar, a left over from Mauro since he uses gerrit to manage this patch series.
Quoted 34 lines
Quoted 20 lines
--- drivers/media/platform/omap3isp/isp.c | 152 ++++++++++++++---------- drivers/media/platform/omap3isp/ispccdc.c | 22 ++-- drivers/media/platform/omap3isp/ispccdc.h | 1 + drivers/media/platform/omap3isp/ispccp2.c | 22 ++-- drivers/media/platform/omap3isp/ispccp2.h | 1 + drivers/media/platform/omap3isp/ispcsi2.c | 22 ++-- drivers/media/platform/omap3isp/ispcsi2.h | 1 + drivers/media/platform/omap3isp/isppreview.c | 33 +++--- drivers/media/platform/omap3isp/isppreview.h | 1 + drivers/media/platform/omap3isp/ispresizer.c | 33 +++--- drivers/media/platform/omap3isp/ispresizer.h | 1 + 11 files changed, 185 insertions(+), 104 deletions(-)(quoted diff) +0
-0
b/drivers/media/platform/omap3isp/isp.cindexaa13b17d19a0..b8f6f81d2db2100644drivers/media/platform/omap3isp/isp.c done: · line 1938
Quoted 6 lines
drivers/media/platform/omap3isp/isp.c +3
-0@@ -1933,6 +1933,100 @@ done:return ret; } +/* +* isp_create_pads_links - Pads links creation for the subdevices +* @isp : Pointer to ISP device Missing blank line here. And missing description of the function for that matter. You can use
"This function creates all links between ISP internal and external entities."
drivers/media/platform/omap3isp/isp.c done: · line 1939
Quoted 1 line
drivers/media/platform/omap3isp/isp.c +1
-0+* return negative error code or zero on success
Quoted 8 lines
In kerneldoc style that should be
Return: A negative error code on failure or zero on success. Possible error codes are those returned by
media_create_pad_link().Same for the other functions below, the return line should start with "Return:".
You are right, the kerneldoc is not correct. I'll fix it.
Quoted 8 lines
drivers/media/platform/omap3isp/isp.c done: · line 1941
Quoted 2 lines
drivers/media/platform/omap3isp/isp.c +2
-0+*/ +static int isp_create_pads_links (struct isp_device *isp)This should be called
isp_create_pad_links()if you want the include the pad prefix, but I'd just name itisp_create_links()as the driver doesn't handle any other kind of links. Same for all the*_create_pads_links()functions below.
Ok.
Quoted 11 lines
drivers/media/platform/omap3isp/isp.c done: · line 1947
Quoted 6 lines
drivers/media/platform/omap3isp/isp.c +6
-0+{ +int ret; + + ret =omap3isp_csi2_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CSI2 pads links creation failed\n" );That's lots of error strings. You would save memory by turning the messages into "%s pads links creation failed\n", "CSI2" as the compiler will then avoid multiple copies of the first string.
Quoted 5 lines
I would actually remove the messages as the only source of error is a memory allocation failure, which will already print a message. You could add a single
dev_err()in the location whereisp_create_pads_links()is called if you want to.
Agreed, I'll just remove the messages.
Quoted 23 lines
Quoted 23 lines
drivers/media/platform/omap3isp/isp.c +23
-0+return ret; + } + + ret =omap3isp_ccp2_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CCP2 pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_ccdc_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"CCDC pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_preview_create_pads_links (isp); +if (ret <0 ) { +dev_err (isp->dev,"Preview pads links creation failed\n" ); +return ret; + } + + ret =omap3isp_resizer_create_pads_links (isp); +if (ret <0 ) {
Quoted 9 lines
drivers/media/platform/omap3isp/isp.c done: · line 1975
Quoted 5 lines
drivers/media/platform/omap3isp/isp.c +5
-0+dev_err (isp->dev,"Resizer pads links creation failed\n" ); +return ret; + } + +/* Connect the submodules. */ I'd write "Create links between entities." and add a comment at the beginning of the function that states "Create links between entities and video nodes.".
Ok.
Quoted 84 lines
Quoted 53 lines
drivers/media/platform/omap3isp/isp.c +53
-0+ ret =media_create_pad_link ( + &isp->isp_csi2a.subdev.entity,CSI2_PAD_SOURCE , + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccp2.subdev.entity,CCP2_PAD_SOURCE , + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_prev.subdev.entity,PREV_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_OF , + &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_prev.subdev.entity,PREV_PAD_SOURCE , + &isp->isp_res.subdev.entity,RESZ_PAD_SINK ,0 ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_aewb.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_af.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + + ret =media_create_pad_link ( + &isp->isp_ccdc.subdev.entity,CCDC_PAD_SOURCE_VP , + &isp->isp_hist.subdev.entity,0 , +MEDIA_LNK_FL_ENABLED |MEDIA_LNK_FL_IMMUTABLE ); +if (ret <0 ) +return ret; + +return 0 ; +}[snip]
Quoted 28 lines
drivers/media/platform/omap3isp/isp.c +4
-0@@ -2468,6 +2508,10 @@ static int isp_probe(struct platform_device *pdev)if (ret <0 ) goto error_modules; + ret =isp_create_pads_links (isp); +if (ret <0 ) + goto error_register_entities; + isp->notifier.bound = isp_subdev_notifier_bound; isp->notifier.complete = isp_subdev_notifier_complete;(quoted diff) +0
-0
b/drivers/media/platform/omap3isp/ispccdc.cindex27555e4f4aa8..9a811f5741fa100644drivers/media/platform/omap3isp/ispccdc.c +0
-6@@ -2666,16 +2666,8 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) if (ret < 0) goto error_video; -/* Connect the CCDC subdev to the video node. */ - ret =media_create_pad_link (&ccdc->subdev.entity,CCDC_PAD_SOURCE_OF , - &ccdc->video_out.video.entity,0 ,0 ); -if (ret <0 ) - goto error_link; -return 0 ;
Quoted 7 lines
drivers/media/platform/omap3isp/ispccdc.c static int ccdc_init_entities(struct isp_ccdc_device *ccdc) · line 2671
Quoted 3 lines
drivers/media/platform/omap3isp/ispccdc.c +0
-2-error_link: -omap3isp_video_cleanup (&ccdc->video_out); error_video:As there's now a single error label I'd rename it to just "error:". Same comment for the other ISP modules.
Ok.
Quoted 16 lines
Quoted 16 lines
drivers/media/platform/omap3isp/ispccdc.c +10
-0media_entity_cleanup (me);return ret;@@ -2721,6 +2713,20 @@ int omap3isp_ccdc_init(struct isp_device *isp) }/* +* omap3isp_ccdc_create_pads_links - CCDC pads links creation +* @isp : Pointer to ISP device +* return negative error code or zero on success +*/ +int omap3isp_ccdc_create_pads_links (struct isp_device *isp) +{ +struct isp_ccdc_device *ccdc = &isp->isp_ccdc; + +/* Connect the CCDC subdev to the video node. */ + return media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
Quoted 9 lines
drivers/media/platform/omap3isp/ispccdc.c int omap3isp_ccdc_init(struct isp_device *isp) · line 2727
Quoted 2 lines
drivers/media/platform/omap3isp/ispccdc.c +2
-0+ &ccdc->video_out.video.entity, 0, 0); +}Given that this function and the other similar functions for other modules just link entities and video devices, it could make sense to inline them directly in the caller in order to group all the link create calls together. No strong opinion though, I'll leave it up to you and on whether you want to fix the kerneldoc or remove it ;-)
Right, would make sense to remove them indeed and just inline in the caller.
Quoted 8 lines
Quoted 5 lines
drivers/media/platform/omap3isp/ispccdc.c +2
-0+ +/* * omap3isp_ccdc_cleanup - CCDC module cleanup. * @isp: Device pointer specific to the OMAP3 ISP. */ [snip]
Best regards,
Signature · 3 lines
Javier Martinez Canillas Open Source Group Samsung Research America
PATCH v8 18/55 omap3isp: create links after all subdevs have been bound
In reply to Mauro Carvalho ChehabFrom: Javier Martinez Canillas <[email protected]>
The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed.
Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration.
So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound.
drivers/media/platform/omap3isp/isp.c +15 -8
@@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) { - struct isp_device *isp = container_of(async, struct isp_device, - notifier); struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd); -int ret; - - ret =isp_link_entity (isp, &subdev->entity, isd->bus.interface); -if (ret <0 ) -return ret; isd->sd = subdev; isd->sd->host_priv = &isd->bus; -return ret; +return 0 ; }static int isp_subdev_notifier_complete (struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); +struct v4l2_device *v4l2_dev = &isp->v4l2_dev; +struct v4l2_subdev *sd; +struct isp_bus_cfg *bus; +int ret; + +list_for_each_entry (sd, &v4l2_dev->subdevs, list) { +/* Only try to link entities whose interface was set on bound */ +if (sd->host_priv) { + bus = (struct isp_bus_cfg *)sd->host_priv; + ret =isp_link_entity (isp, &sd->entity, bus->interface); +if (ret <0 ) +return ret; + } + }return v4l2_device_register_subdev_nodes (&isp->v4l2_dev); }
Signature · 1 line
2.4.3
Re: [PATCH v8 18/55] [media] omap3isp: create links after all subdevs have been bound
Hi Javier and Mauro,
Quoted 54 lines · Mauro Carvalho Chehab
From: Javier Martinez Canillas <[email protected]>
The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed.
Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration.
So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound.
Signed-off-by Javier Martinez Canillas <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/omap3isp/isp.c +8
-8@@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) { - struct isp_device *isp = container_of(async, struct isp_device, - notifier); struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd); -int ret; - - ret =isp_link_entity (isp, &subdev->entity, isd->bus.interface); -if (ret <0 ) -return ret; isd->sd = subdev; isd->sd->host_priv = &isd->bus; -return ret; +return 0 ; }static int isp_subdev_notifier_complete (struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); +struct v4l2_device *v4l2_dev = &isp->v4l2_dev; +struct v4l2_subdev *sd; +struct isp_bus_cfg *bus; +int ret; + +list_for_each_entry (sd, &v4l2_dev->subdevs, list) { +/* Only try to link entities whose interface was set on bound */
drivers/media/platform/omap3isp/isp.c static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, · line 2353
Quoted 10 lines
drivers/media/platform/omap3isp/isp.c +7
-0+if (sd->host_priv) { + bus = (struct isp_bus_cfg *)sd->host_priv; + ret =isp_link_entity (isp, &sd->entity, bus->interface); +if (ret <0 ) +return ret; + } + }return v4l2_device_register_subdev_nodes (&isp->v4l2_dev); }
I think you're working around a problem here, not really fixing it.
This change will create the links only after the media device is registered, which means the user may obtain a partial enumeration of links if the enumeration is performed too early.
Before this set, the problem also was that the media device was registered before the async entities were bound, again making it possible to obtain a partial enumeration of entities.
What I'd suggest instead is that we split media device initialisation and registration to the system; that way the media device can be prepared (entities registered and links created) before it becomes visible to the user space. I can write a patch for that if you like.
Signature · 4 lines
Kind regards, Sakari Ailus e-mail: [email protected] XMPP: [email protected]
Re: [PATCH v8 18/55] [media] omap3isp: create links after all subdevs have been bound
Hello Sakari,
Quoted 70 lines · Sakari Ailus
Hi Javier and Mauro,
Quoted 54 lines · Mauro Carvalho Chehab
From: Javier Martinez Canillas <[email protected]>
The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed.
Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration.
So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound.
Signed-off-by Javier Martinez Canillas <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/omap3isp/isp.c +8
-8@@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) { - struct isp_device *isp = container_of(async, struct isp_device, - notifier); struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd); -int ret; - - ret =isp_link_entity (isp, &subdev->entity, isd->bus.interface); -if (ret <0 ) -return ret; isd->sd = subdev; isd->sd->host_priv = &isd->bus; -return ret; +return 0 ; }static int isp_subdev_notifier_complete (struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); +struct v4l2_device *v4l2_dev = &isp->v4l2_dev; +struct v4l2_subdev *sd; +struct isp_bus_cfg *bus; +int ret; + +list_for_each_entry (sd, &v4l2_dev->subdevs, list) { +/* Only try to link entities whose interface was set on bound */ drivers/media/platform/omap3isp/isp.c static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, · line 2353
Quoted 10 lines
drivers/media/platform/omap3isp/isp.c +7
-0+if (sd->host_priv) { + bus = (struct isp_bus_cfg *)sd->host_priv; + ret =isp_link_entity (isp, &sd->entity, bus->interface); +if (ret <0 ) +return ret; + } + }return v4l2_device_register_subdev_nodes (&isp->v4l2_dev); }I think you're working around a problem here, not really fixing it.
Quoted 8 lines
This change will create the links only after the media device is registered, which means the user may obtain a partial enumeration of links if the enumeration is performed too early.
Before this set, the problem also was that the media device was registered before the async entities were bound, again making it possible to obtain a partial enumeration of entities.
You are absolutely correct but I think these are separate issues. The problem here is that v4l2_async_test_notify() [0] first invokes the bound notifier callback and then calls v4l2_device_register_subdev() that register the media entity with the media device.
Since now is a requirement that the entities must be registered prior creating pads links (because to init a MEDIA_GRAPH_LINK object a mdev has to be set), $SUBJECT is needed regardless of the race between subdev registration and the media dev node being available to user-space before everything is registered.
Quoted 5 lines
What I'd suggest instead is that we split media device initialisation and registration to the system; that way the media device can be prepared (entities registered and links created) before it becomes visible to the user space. I can write a patch for that if you like.
Agreed, looking at the implementation it seems that __media_device_register() has to be split (possibly being renamed to __media_device_init) so it only contains the initialization logic and all the media device node registration logic moved to another function (that would become media_device_register).
I think the media dev node registration has to be made in the complete callback to make sure that happens when all the subdevs have been already registered.
Is that what you had in mind? I can also write such a patch if you want.
[0]: http://lxr.free-electrons.com/source/drivers/media/v4l2-core/v4l2-async.c#L96
[1]: http://lxr.free-electrons.com/source/drivers/media/media-device.c#L372
Best regards,
Signature · 3 lines
Javier Martinez Canillas Open Source Group Samsung Research America
Laurent Pinchart
maintainerRe: [PATCH v8 18/55] [media] omap3isp: create links after all subdevs have been bound
Hi Javier,
Thank you for the patch.
Quoted 102 lines · On Wednesday 09 September 2015 10:48:29 Javier Martinez Canillas wrote:
Quoted 72 lines · Sakari Ailus
Quoted 67 lines · Mauro Carvalho Chehab
From: Javier Martinez Canillas <[email protected]>
The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed.
Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration.
So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound.
Signed-off-by Javier Martinez Canillas <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>(quoted diff) +0
-0
b/drivers/media/platform/omap3isp/isp.cindexb8f6f81d2db2..69e7733d36cd100644drivers/media/platform/omap3isp/isp.c +15
-8@@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(structv4l2_async_notifier *async, struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) { - struct isp_device *isp = container_of(async, struct isp_device, - notifier); struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd); -int ret; - - ret =isp_link_entity (isp, &subdev->entity, isd->bus.interface); -if (ret <0 ) -return ret; isd->sd = subdev; isd->sd->host_priv = &isd->bus; -return ret; +return 0 ; }static int isp_subdev_notifier_complete (struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); +struct v4l2_device *v4l2_dev = &isp->v4l2_dev; +struct v4l2_subdev *sd; +struct isp_bus_cfg *bus; +int ret; + +list_for_each_entry (sd, &v4l2_dev->subdevs, list) { +/* Only try to link entities whose interface was set on bound */ +if (sd->host_priv) { + bus = (struct isp_bus_cfg *)sd->host_priv; + ret =isp_link_entity (isp, &sd->entity, bus->interface); +if (ret <0 ) +return ret; + } + }return v4l2_device_register_subdev_nodes (&isp->v4l2_dev);Quoted 1 line
}
I think you're working around a problem here, not really fixing it.
Quoted 7 lines
This change will create the links only after the media device is registered, which means the user may obtain a partial enumeration of links if the enumeration is performed too early.
Before this set, the problem also was that the media device was registered before the async entities were bound, again making it possible to obtain a partial enumeration of entities.
You are absolutely correct but I think these are separate issues. The problem here is that
v4l2_async_test_notify()[0] first invokes the bound notifier callback and then callsv4l2_device_register_subdev()that register the media entity with the media device.Since now is a requirement that the entities must be registered prior creating pads links (because to init a
MEDIA_GRAPH_LINKobject a mdev has to be set), $SUBJECT is needed regardless of the race between subdev registration and the media dev node being available to user-space before everything is registered.Quoted 4 lines
What I'd suggest instead is that we split media device initialisation and registration to the system; that way the media device can be prepared (entities registered and links created) before it becomes visible to the user space. I can write a patch for that if you like.
Agreed, looking at the implementation it seems that
__media_device_register()has to be split (possibly being renamed to__media_device_init) so it only contains the initialization logic and all the media device node registration logic moved to another function (that would becomemedia_device_register).
Quoted 5 lines
I think the media dev node registration has to be made in the complete callback to make sure that happens when all the subdevs have been already registered.
Is that what you had in mind? I can also write such a patch if you want.
I think I've already commented on it in my review of another patch (but can't find it right now), I agree with you. We need to properly think about initialization (and, for that matter, cleanup as well) order, both for the media device and the entities. And, as a corollary, for subdevs too. The current media entity and subdevs initialization and registration code grew in an organic way without much design behind it, let's not repeat the same mistake.
Quoted 4 lines
[0]:
http://lxr.free-electrons.com/source/drivers/media/v4l2-core/v4l2-async.c#L
96 [1]:
http://lxr.free-electrons.com/source/drivers/media/media-device.c#L372
Signature · 3 lines
Regards, Laurent Pinchart
Re: [PATCH v8 18/55] [media] omap3isp: create links after all subdevs have been bound
Hello Laurent,
Quoted 107 lines · Laurent Pinchart
Hi Javier,
Thank you for the patch.
Quoted 102 lines · On Wednesday 09 September 2015 10:48:29 Javier Martinez Canillas wrote:
Quoted 72 lines · Sakari Ailus
Quoted 67 lines · Mauro Carvalho Chehab
From: Javier Martinez Canillas <[email protected]>
The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed.
Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration.
So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound.
Signed-off-by Javier Martinez Canillas <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>(quoted diff) +0
-0
b/drivers/media/platform/omap3isp/isp.cindexb8f6f81d2db2..69e7733d36cd100644drivers/media/platform/omap3isp/isp.c +15
-8@@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(structv4l2_async_notifier *async, struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) { - struct isp_device *isp = container_of(async, struct isp_device, - notifier); struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd); -int ret; - - ret =isp_link_entity (isp, &subdev->entity, isd->bus.interface); -if (ret <0 ) -return ret; isd->sd = subdev; isd->sd->host_priv = &isd->bus; -return ret; +return 0 ; }static int isp_subdev_notifier_complete (struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); +struct v4l2_device *v4l2_dev = &isp->v4l2_dev; +struct v4l2_subdev *sd; +struct isp_bus_cfg *bus; +int ret; + +list_for_each_entry (sd, &v4l2_dev->subdevs, list) { +/* Only try to link entities whose interface was set on bound */ +if (sd->host_priv) { + bus = (struct isp_bus_cfg *)sd->host_priv; + ret =isp_link_entity (isp, &sd->entity, bus->interface); +if (ret <0 ) +return ret; + } + }return v4l2_device_register_subdev_nodes (&isp->v4l2_dev);Quoted 1 line
}
I think you're working around a problem here, not really fixing it.
Quoted 7 lines
This change will create the links only after the media device is registered, which means the user may obtain a partial enumeration of links if the enumeration is performed too early.
Before this set, the problem also was that the media device was registered before the async entities were bound, again making it possible to obtain a partial enumeration of entities.
You are absolutely correct but I think these are separate issues. The problem here is that
v4l2_async_test_notify()[0] first invokes the bound notifier callback and then callsv4l2_device_register_subdev()that register the media entity with the media device.Since now is a requirement that the entities must be registered prior creating pads links (because to init a
MEDIA_GRAPH_LINKobject a mdev has to be set), $SUBJECT is needed regardless of the race between subdev registration and the media dev node being available to user-space before everything is registered.Quoted 4 lines
What I'd suggest instead is that we split media device initialisation and registration to the system; that way the media device can be prepared (entities registered and links created) before it becomes visible to the user space. I can write a patch for that if you like.
Agreed, looking at the implementation it seems that
__media_device_register()has to be split (possibly being renamed to__media_device_init) so it only contains the initialization logic and all the media device node registration logic moved to another function (that would becomemedia_device_register).
Quoted 8 lines
Quoted 5 lines
I think the media dev node registration has to be made in the complete callback to make sure that happens when all the subdevs have been already registered.
Is that what you had in mind? I can also write such a patch if you want.
I think I've already commented on it in my review of another patch (but can't find it right now), I agree with you. We need to properly think about
I'm glad that you agree, could you please review the v4 of patch series "Fix race between graph enumeration and entities registration" [0] that I posted a while ago?
Quoted 6 lines
initialization (and, for that matter, cleanup as well) order, both for the media device and the entities. And, as a corollary, for subdevs too. The current media entity and subdevs initialization and registration code grew in an organic way without much design behind it, let's not repeat the same mistake.
Agreed, and this should be properly documented so driver authors can follow.
[0]: https://lkml.org/lkml/2015/9/15/371
Best regards,
Signature · 3 lines
Javier Martinez Canillas Open Source Group Samsung Research America
Re: [PATCH v8 18/55] [media] omap3isp: create links after all subdevs have been bound
In reply to Sakari AilusHi Sakari,
Em Wed, 09 Sep 2015 11:03:33 +0300
Sakari Ailus <[email protected]> escreveu:
Quoted 70 lines
Hi Javier and Mauro,
Quoted 54 lines · Mauro Carvalho Chehab
From: Javier Martinez Canillas <[email protected]>
The omap3isp driver parses the graph endpoints to know how many subdevices needs to be registered async and register notifiers callbacks for to know when these are bound and when the async registrations are completed.
Currently the entities pad are linked with the correct ISP input interface when the subdevs are bound but it happens before entitities are registered with the media device so that won't work now that the entity links list is initialized on device registration.
So instead creating the pad links when the subdevice is bound, create them on the complete callback once all the subdevices have been bound but only try to create for the ones that have a bus configuration set during bound.
Signed-off-by Javier Martinez Canillas <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/omap3isp/isp.c +8
-8@@ -2321,26 +2321,33 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) { - struct isp_device *isp = container_of(async, struct isp_device, - notifier); struct isp_async_subdev *isd = container_of(asd, struct isp_async_subdev, asd); -int ret; - - ret =isp_link_entity (isp, &subdev->entity, isd->bus.interface); -if (ret <0 ) -return ret; isd->sd = subdev; isd->sd->host_priv = &isd->bus; -return ret; +return 0 ; }static int isp_subdev_notifier_complete (struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, notifier); +struct v4l2_device *v4l2_dev = &isp->v4l2_dev; +struct v4l2_subdev *sd; +struct isp_bus_cfg *bus; +int ret; + +list_for_each_entry (sd, &v4l2_dev->subdevs, list) { +/* Only try to link entities whose interface was set on bound */ drivers/media/platform/omap3isp/isp.c static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async, · line 2353
Quoted 10 lines
drivers/media/platform/omap3isp/isp.c +7
-0+if (sd->host_priv) { + bus = (struct isp_bus_cfg *)sd->host_priv; + ret =isp_link_entity (isp, &sd->entity, bus->interface); +if (ret <0 ) +return ret; + } + }return v4l2_device_register_subdev_nodes (&isp->v4l2_dev); }I think you're working around a problem here, not really fixing it.
Quoted 7 lines
This change will create the links only after the media device is registered, which means the user may obtain a partial enumeration of links if the enumeration is performed too early.
Before this set, the problem also was that the media device was registered before the async entities were bound, again making it possible to obtain a partial enumeration of entities.
Before of after this series, if userspace tries to read the topology too early, it will get a partial topology. Before this series, it may lose entities and links; after this series, it may lose any object.
In any case, userspace won't do the right thing, whatever order we initialize.
The patches on this series is not meant to solve this issue.
The rationale for this patch is due to a different reason. You should notice that, due to the G_TOPOLOGY ioctl requirements, all objects should have their ID assigned and should be added at the mdev linked lists, as those are used by G_TOPOLOGY loops that copy the object data to userspace.
So, before registering/creating any object, the media_device struct need to exist internally at Kernelspace.
Quoted 5 lines
What I'd suggest instead is that we split media device initialisation and registration to the system; that way the media device can be prepared (entities registered and links created) before it becomes visible to the user space. I can write a patch for that if you like.
Yes, we can split the internal media register stuff from the creation of the /dev/media0 device node, doing that only after having everything set in Kernel, as the patch that Javier proposed on IRC.
Another alternative would be to add a "busy" flag at media_device, making all ioctl's at /dev/mdeia0 to return -EBUSY during massive graph changes.
Such flag would be rised at media_device registration and dropped at the end of the device probe routine.
The advantage of using such flags is that this could be used, for example, on ARA project, when a module is removed or inserted.
The disadvantage is that current userspace apps may not be prepared to receive -EBUSY.
I'm OK with both strategies.
Regards,
Mauro
PATCH v8 19/55 media: convert links from array to list
In reply to Mauro Carvalho ChehabThe entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses krealloc() to change the size of the link, with is bad, as it leaves the memory fragmented.
So, convert links into a list.
Also, currently, both source and sink entities need the link at the graph traversal logic inside media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
drivers/media/dvb-core/dvb_frontend.c +3 -6
@@ -622,7 +622,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)struct media_device *mdev = adapter->mdev;struct media_entity *entity, *source;struct media_link *link, *found_link =NULL ; -int i, ret, n_links =0 , active_links =0 ; +int ret, n_links =0 , active_links =0 ; fepriv->pipe_start_entity =NULL ;
@@ -632,8 +632,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) entity = fepriv->dvbdev->entity; fepriv->pipe_start_entity = entity; -for (i =0 ; i < entity->num_links; i++) { - link = &entity->links[i]; +list_for_each_entry (link, &entity->links, list) {if (link->sink->entity == entity) { found_link = link; n_links++;
@@ -659,13 +658,11 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) source = found_link->source->entity; fepriv->pipe_start_entity = source; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity; -if (sink == entity) flags =MEDIA_LNK_FL_ENABLED ;
drivers/media/media-device.c +15 -10
@@ -25,6 +25,7 @@#include <linux/ioctl.h> #include <linux/media.h> #include <linux/types.h> +#include <linux/slab.h> #include <media/media-device.h> #include <media/media-devnode.h>
@@ -150,22 +151,21 @@ static long __media_device_enum_links(struct media_device *mdev, }if (links->links) { -struct media_link_desc __user *ulink; -unsigned int l; +struct media_link *ent_link; +struct media_link_desc __user *ulink = links->links; -for (l =0 , ulink = links->links; l < entity->num_links; l++) { +list_for_each_entry (ent_link, &entity->links, list) {struct media_link_desc link;/* Ignore backlinks. */ -if (entity->links[l].source->entity != entity) +if (ent_link->source->entity != entity)continue ; -memset (&link,0 ,sizeof (link)); -media_device_kpad_to_upad (entity->links[l].source, +media_device_kpad_to_upad (ent_link->source, &link.source); -media_device_kpad_to_upad (entity->links[l].sink, +media_device_kpad_to_upad (ent_link->sink, &link.sink); - link.flags = entity->links[l].flags; + link.flags = ent_link->flags;if (copy_to_user (ulink, &link,sizeof (*ulink)))return -EFAULT ; ulink++;
@@ -437,6 +437,7 @@ 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);spin_lock (&mdev->lock);/* Initialize media_gobj embedded at the entity */
@@ -465,13 +466,17 @@ void media_device_unregister_entity(struct media_entity *entity) {int i;struct media_device *mdev = entity->graph_obj.mdev; +struct media_link *link, *tmp;if (mdev ==NULL )return ;spin_lock (&mdev->lock); -for (i =0 ; i < entity->num_links; i++) -media_gobj_remove (&entity->links[i].graph_obj); +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link); + }for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj);media_gobj_remove (&entity->graph_obj);
drivers/media/media-entity.c +64 -66
249 lines not on this page · raw message
drivers/media/usb/au0828/au0828-core.c +5 -7
@@ -261,13 +261,11 @@ static void au0828_create_media_graph(struct au0828_dev *dev)if (tuner)media_create_pad_link (tuner,0 , decoder,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vdev.entity.links) -media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vbi_dev.entity.links) -media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , -MEDIA_LNK_FL_ENABLED ); +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , +MEDIA_LNK_FL_ENABLED );#endif }
drivers/media/usb/au0828/au0828-video.c +3 -5
@@ -643,7 +643,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)struct media_device *mdev = dev->media_dev;struct media_entity *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev || !dev->decoder)return 0 ;
@@ -655,8 +655,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)* do DVB streaming while the DMA engine is being used for V4L2, * this should be enough for the actual needs. */ -for (i =0 ; i < dev->decoder->num_links; i++) { - link = &dev->decoder->links[i]; +list_for_each_entry (link, &dev->decoder->links, list) {if (link->sink->entity == dev->decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -669,11 +668,10 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == dev->decoder)
drivers/media/usb/cx231xx/cx231xx-video.c +3 -5
@@ -106,7 +106,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)struct media_device *mdev = dev->media_dev;struct media_entity *entity, *decoder =NULL , *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev)return 0 ;
@@ -127,8 +127,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)if (!decoder)return 0 ; -for (i =0 ; i < decoder->num_links; i++) { - link = &decoder->links[i]; +list_for_each_entry (link, &decoder->links, list) {if (link->sink->entity == decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -141,11 +140,10 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == entity)
include/media/media-entity.h +5 -5
@@ -74,6 +74,7 @@ struct media_pipeline {struct media_link {struct media_gobj graph_obj; +struct list_head list;struct media_pad *source;/* Source pad */ struct media_pad *sink;/* Sink pad */ struct media_link *reverse;/* Link in the reverse direction */
@@ -116,10 +117,9 @@ struct media_entity {u16 num_links;/* Number of existing links, both * enabled and disabled */ u16 num_backlinks;/* Number of backlinks */ -u16 max_links;/* Maximum number of links */ -struct media_pad *pads;/* Pads array (num_pads elements) */ -struct media_link *links;/* Links array (max_links elements)*/ +struct media_pad *pads;/* Pads array (num_pads objects) */ +struct list_head links;/* Links list */ const struct media_entity_operations *ops;/* Entity operations */
@@ -213,7 +213,7 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)struct media_entity_graph {struct {struct media_entity *entity; -int link; +struct list_head link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH ]; DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID);
@@ -247,7 +247,7 @@ void media_gobj_init(struct media_device *mdev,void media_gobj_remove (struct media_gobj *gobj);int media_entity_init (struct media_entity *entity,u16 num_pads, -struct media_pad *pads); +struct media_pad *pads);void media_entity_cleanup (struct media_entity *entity); int media_create_pad_link(struct media_entity *source, u16 source_pad,
Signature · 1 line
2.4.3
Re: [PATCH v8 19/55] [media] media: convert links from array to list
Hi Mauro,
Quoted 10 lines · Mauro Carvalho Chehab
The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses
krealloc()to change the size of the link, with is bad, as it leaves the memory fragmented.
The Linux kernel constantly allocates and releases memory for various reasons. Even the V4L2 IOCTL handler does that when the argument is too large to fit into the stack-allocated buffer. There's no reason to avoid allocating and releasing small chunks of memory when hardware configuration changes.
Quoted 2 lines
So, convert links into a list.
Instead, if you're worried about the time the memory re-allocation takes that'd be needed to dynamically add a large number of links, I'd just allocate more memory at a time, say, rounding up to a power of two, and use vmalloc() instead of kmalloc() when the size grows over one page.
That'd avoid the vast majority of reallocs without wasting much memory: the granularity of memory allocation is much larger than the size of struct media_link except in the case of very small link numbers.
The reason I'm proposing this is that linked lists, as you're allocating them, can end up anywhere in the system memory. Walking over the media graph is quite a job if you have as many links as in your example, and the additional cache misses caused by scattering the data structure all over the system memory will not make the effort smaller.
Adding links dynamically (for a change in hardware topology?) is by far less performance critical than e.g. starting and stopping streaming or enumerating the links so the latter should have the priority IMHO.
Quoted 7 lines
Also, currently, both source and sink entities need the link at the graph traversal logic inside
media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.
Quoted 9 lines
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
Would keeping the links in a linked list help with that?
I think this could be done using both the current arrays or linked lists --- instead of storing links themselves, you'd store pointers to the links (array or a linked list) which then are stored elsewhere. Helper functions would be needed to e.g. loop over the links in that case though.
Signature · 4 lines
Kind regards, Sakari Ailus e-mail: [email protected] XMPP: [email protected]
Re: [PATCH v8 19/55] [media] media: convert links from array to list
Quoted 38 lines · Sakari Ailus
Hi Mauro,
Quoted 10 lines · Mauro Carvalho Chehab
The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses
krealloc()to change the size of the link, with is bad, as it leaves the memory fragmented.The Linux kernel constantly allocates and releases memory for various reasons. Even the V4L2 IOCTL handler does that when the argument is too large to fit into the stack-allocated buffer. There's no reason to avoid allocating and releasing small chunks of memory when hardware configuration changes.
Quoted 2 lines
So, convert links into a list.
Instead, if you're worried about the time the memory re-allocation takes that'd be needed to dynamically add a large number of links, I'd just allocate more memory at a time, say, rounding up to a power of two, and use
vmalloc()instead ofkmalloc()when the size grows over one page.That'd avoid the vast majority of reallocs without wasting much memory: the granularity of memory allocation is much larger than the size of struct
media_linkexcept in the case of very small link numbers.The reason I'm proposing this is that linked lists, as you're allocating them, can end up anywhere in the system memory. Walking over the media graph is quite a job if you have as many links as in your example, and the additional cache misses caused by scattering the data structure all over the system memory will not make the effort smaller.
Quoted 3 lines
Adding links dynamically (for a change in hardware topology?) is by far less performance critical than e.g. starting and stopping streaming or enumerating the links so the latter should have the priority IMHO.
You don't do either of these jobs very often either. As I have said before, the enemy of media drivers is rarely performance but always complexity. Based on the patches I've seen I agree with Mauro that a linked list is a better fit and simplifies the code.
If you have *proof* that this hurts performance in certain real-life cases, then this can always be optimized later.
But unless someone shows me proof that it really hurts performance in realistic cases, I will always favor simplicity.
In all the time that I have been involved in the media subsystem the only performance issue I am aware of was that enumerating all the links in the MC can be too slow due to all the ioctl calls that it takes (vsp driver). This will be solved with the proposed G_TOPOLOGY ioctl since that returns everything in a single call (or two calls if you need to know how much memory to allocate first).
Hmm, actually, I think there is another related issue if you want to enumerate all combinations of pixelformats, discrete framesizes and framerates. There too the problem is the number of ioctl calls you have to do. It's never been important enough to do something about it, though.
Bottom line, always go for simplicity unless you can demonstrate with numbers that there are real performance issues.
Regards,
Hans
Quoted 25 lines
Quoted 8 lines
Also, currently, both source and sink entities need the link at the graph traversal logic inside
media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.Quoted 9 lines
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
Would keeping the links in a linked list help with that?
I think this could be done using both the current arrays or linked lists --- instead of storing links themselves, you'd store pointers to the links (array or a linked list) which then are stored elsewhere. Helper functions would be needed to e.g. loop over the links in that case though.
Re: [PATCH v8 19/55] [media] media: convert links from array to list
Em Fri, 04 Sep 2015 11:00:38 +0200
Hans Verkuil <[email protected]> escreveu:
Quoted 22 lines · Sakari Ailus
Quoted 21 lines
Hi Mauro,
Quoted 10 lines · Mauro Carvalho Chehab
The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses
krealloc()to change the size of the link, with is bad, as it leaves the memory fragmented.The Linux kernel constantly allocates and releases memory for various reasons. Even the V4L2 IOCTL handler does that when the argument is too large to fit into the stack-allocated buffer. There's no reason to avoid allocating and releasing small chunks of memory when hardware configuration changes.
Quoted 1 line
Quoted 6 lines
Quoted 6 lines
Quoted 1 line
So, convert links into a list.
Instead, if you're worried about the time the memory re-allocation takes that'd be needed to dynamically add a large number of links, I'd just allocate more memory at a time, say, rounding up to a power of two, and use
vmalloc()instead ofkmalloc()when the size grows over one page.
We had support to allocate more links via that "extra_links" parameter. This never worked in practice: there was no single client for that.
Quoted 10 lines
Quoted 10 lines
That'd avoid the vast majority of reallocs without wasting much memory: the granularity of memory allocation is much larger than the size of struct
media_linkexcept in the case of very small link numbers.The reason I'm proposing this is that linked lists, as you're allocating them, can end up anywhere in the system memory. Walking over the media graph is quite a job if you have as many links as in your example, and the additional cache misses caused by scattering the data structure all over the system memory will not make the effort smaller.
First of all, I agree with Hans: the major issues we have is not due to performance, but due to complexity.
Talking about the graph traversal algorithm, it curently doesn't work even for simple hybrid TV devices, as it currently allows to have only 64 entities, due to the loop detection code there.
Ok, it would be possible to extend it to support real case scenarios, but the patch is not as trivial as changing the max number of entities. Just doing that would cause the stack to crash, as the bitmap structs are allocated at the stack.
Also, what you're saying regards to the increase of cache misses, this is not true. The links memory are still fragmented, as they're allocated during entities init code. On most codes, that means that they'll be allocated after each entity.
So, memory would look like:
entity#1
links for entity#1
entity#2
links for entity#2
...
If you want to put the links at consecutive addresses, what you would need to do is to create first all entities, and then create the links altogether. After this patch, drivers that have timing issues can do it, having the memory allocated as:
entity#1
entity#2
links for entity#1
links for entity#2
...
So, I won't doubt that this patch would actually improve performance by putting the links altogether ;)
Ok, when we have lots of dynamic entity creation/removal, the memory will become more fragmented, but that would happen with or without this change.
I mean, if this patch is not applied and entity#2 is created after a long runtime, we would have:
entity#1
links for entity #1
<some other data allocated>
entity#2
links for entity #2
While, on the other case, the memory would be:
entity#1
links for entity #1 (except for the link with entity#2) backlinks for entity #1 (except for the link with entity#2)
<some other data allocated>
entity#2
link between entity#1 and entity#2
other links for entity #2
I bet performance would be pretty much the same.
Anyway, let's go to real numbers. Javier ran some tests in order to check what would be the difference using the omap3isp driver.
He hacked yavta to suppress glibc calls to printf() with this hack:
#define printf(...) do { } while (0)
Then, he measured the times with and without this patch series. Doing the graph traversal needed for this command:
$ time ./yavta/yavta -f UYVY -s 720x312 -n 1 --capture=1 -F /dev/video2
Resulted in:
real 0m0.022s user 0m0.000s sys 0m0.010s
The complete results form Javier are at:
http://hastebin.com/turixebuyo.pl
He did that with both with and without this patch series.
On all cases, it took 10ms to setup the pipeline.
Quoted 16 lines
Quoted 4 lines
Adding links dynamically (for a change in hardware topology?) is by far less performance critical than e.g. starting and stopping streaming or enumerating the links so the latter should have the priority IMHO.
You don't do either of these jobs very often either. As I have said before, the enemy of media drivers is rarely performance but always complexity. Based on the patches I've seen I agree with Mauro that a linked list is a better fit and simplifies the code.
If you have *proof* that this hurts performance in certain real-life cases, then this can always be optimized later.
But unless someone shows me proof that it really hurts performance in realistic cases, I will always favor simplicity.
Quoted 6 lines
In all the time that I have been involved in the media subsystem the only performance issue I am aware of was that enumerating all the links in the MC can be too slow due to all the ioctl calls that it takes (vsp driver). This will be solved with the proposed
G_TOPOLOGYioctl since that returns everything in a single call (or two calls if you need to know how much memory to allocate first).
Some timing measurements using au0828 driver:
This is the time mc_nextgen_test takes with a hack that:
- Reduces the number of demux outputs from 256 to 5;
- Reduces the number of output ringbuffers from 512 to 10;
- Adds one subdev for tuner (helps me to test subdevs).
$ time ~/mc_nextgen_test version: 97 number of entities: 19 number of interfaces: 7 number of pads: 28 number of links: 25
real 0m0.002s
user 0m0.000s
sys 0m0.000s
The time spent at the Kernel (sys) is less than 1ms. Hardly would cause any harm.
Btw, that's with the real graph (without a fake subdev for tuner, and with all ringbuffers mapped):
$ time ~/mc_nextgen_test version: 2354 number of entities: 521 number of interfaces: 6 number of pads: 781 number of links: 526
real 0m0.002s
user 0m0.000s
sys 0m0.000s
No difference: it still took less than 1 ms.
Ok, this is not graph traversal, but the G_TOPOLOGY should read all objects that belong to the graph. So, if cache miss would cause any performance issue, some difference would be noticed here.
Also, please notice that cache misses inside a graph traversal loop should happen only one for a given memory object, as, the memory will be cached on the second access to it (provided, of course, that the amount of memory used to store the links is smaller than the size of the cache - that should be the case even for graphs like what we have at au0828 without the hacks).
We might try to use ftrace to measure the time spent in Kernel to have a better measurement, but I'm afraid that ftrace could actually mangle the results by causing cache flushes at L1 cache, due to the long jump to the ftrace event store routine.
Quoted 6 lines
Hmm, actually, I think there is another related issue if you want to enumerate all combinations of pixelformats, discrete framesizes and framerates. There too the problem is the number of ioctl calls you have to do. It's never been important enough to do something about it, though.
Quoted 26 lines
Bottom line, always go for simplicity unless you can demonstrate with numbers that there are real performance issues.
Regards,
Hans
Quoted 19 lines
Quoted 8 lines
Also, currently, both source and sink entities need the link at the graph traversal logic inside
media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.Quoted 9 lines
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
Would keeping the links in a linked list help with that?
Well, if we reduce the links by half, removing the allocation of a memory for backlinks, then yes. I was planning to to that, but this would require a non-trivial change at the graph traversal algorithm and the usage of a separate linked list for the backlink.
Please notice that, if you're concerned with cache misses, using half of the memory to store the links/backlinks would actually be an improvement in terms of performance.
Quoted 7 lines
Quoted 6 lines
I think this could be done using both the current arrays or linked lists --- instead of storing links themselves, you'd store pointers to the links (array or a linked list) which then are stored elsewhere. Helper functions would be needed to e.g. loop over the links in that case though.
PATCH v8 19/55 media: convert links from array to list
In reply to Mauro Carvalho ChehabThe entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses krealloc() to change the size of the link, with is bad, as it leaves the memory fragmented.
So, convert links into a list.
Also, currently, both source and sink entities need the link at the graph traversal logic inside media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
---
This version contains a few bug fixes folded on it, resulted from Javier's tests. I won't be respinning the entire series just due to that.
Javier: Thanks for that! I'll add you proper credits on the final version.
drivers/media/dvb-core/dvb_frontend.c +3 -6
@@ -622,7 +622,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)struct media_device *mdev = adapter->mdev;struct media_entity *entity, *source;struct media_link *link, *found_link =NULL ; -int i, ret, n_links =0 , active_links =0 ; +int ret, n_links =0 , active_links =0 ; fepriv->pipe_start_entity =NULL ;
@@ -632,8 +632,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) entity = fepriv->dvbdev->entity; fepriv->pipe_start_entity = entity; -for (i =0 ; i < entity->num_links; i++) { - link = &entity->links[i]; +list_for_each_entry (link, &entity->links, list) {if (link->sink->entity == entity) { found_link = link; n_links++;
@@ -659,13 +658,11 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) source = found_link->source->entity; fepriv->pipe_start_entity = source; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity; -if (sink == entity) flags =MEDIA_LNK_FL_ENABLED ;
drivers/media/media-device.c +15 -10
@@ -25,6 +25,7 @@#include <linux/ioctl.h> #include <linux/media.h> #include <linux/types.h> +#include <linux/slab.h> #include <media/media-device.h> #include <media/media-devnode.h>
@@ -150,22 +151,21 @@ static long __media_device_enum_links(struct media_device *mdev, }if (links->links) { -struct media_link_desc __user *ulink; -unsigned int l; +struct media_link *ent_link; +struct media_link_desc __user *ulink = links->links; -for (l =0 , ulink = links->links; l < entity->num_links; l++) { +list_for_each_entry (ent_link, &entity->links, list) {struct media_link_desc link;/* Ignore backlinks. */ -if (entity->links[l].source->entity != entity) +if (ent_link->source->entity != entity)continue ; -memset (&link,0 ,sizeof (link)); -media_device_kpad_to_upad (entity->links[l].source, +media_device_kpad_to_upad (ent_link->source, &link.source); -media_device_kpad_to_upad (entity->links[l].sink, +media_device_kpad_to_upad (ent_link->sink, &link.sink); - link.flags = entity->links[l].flags; + link.flags = ent_link->flags;if (copy_to_user (ulink, &link,sizeof (*ulink)))return -EFAULT ; ulink++;
@@ -437,6 +437,7 @@ 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);spin_lock (&mdev->lock);/* Initialize media_gobj embedded at the entity */
@@ -465,13 +466,17 @@ void media_device_unregister_entity(struct media_entity *entity) {int i;struct media_device *mdev = entity->graph_obj.mdev; +struct media_link *link, *tmp;if (mdev ==NULL )return ;spin_lock (&mdev->lock); -for (i =0 ; i < entity->num_links; i++) -media_gobj_remove (&entity->links[i].graph_obj); +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link); + }for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj);media_gobj_remove (&entity->graph_obj);
drivers/media/media-entity.c +64 -66
249 lines not on this page · raw message
drivers/media/usb/au0828/au0828-core.c +5 -7
@@ -261,13 +261,11 @@ static void au0828_create_media_graph(struct au0828_dev *dev)if (tuner)media_create_pad_link (tuner,0 , decoder,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vdev.entity.links) -media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vbi_dev.entity.links) -media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , -MEDIA_LNK_FL_ENABLED ); +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , +MEDIA_LNK_FL_ENABLED );#endif }
drivers/media/usb/au0828/au0828-video.c +3 -5
@@ -643,7 +643,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)struct media_device *mdev = dev->media_dev;struct media_entity *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev || !dev->decoder)return 0 ;
@@ -655,8 +655,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)* do DVB streaming while the DMA engine is being used for V4L2, * this should be enough for the actual needs. */ -for (i =0 ; i < dev->decoder->num_links; i++) { - link = &dev->decoder->links[i]; +list_for_each_entry (link, &dev->decoder->links, list) {if (link->sink->entity == dev->decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -669,11 +668,10 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == dev->decoder)
drivers/media/usb/cx231xx/cx231xx-video.c +3 -5
@@ -106,7 +106,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)struct media_device *mdev = dev->media_dev;struct media_entity *entity, *decoder =NULL , *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev)return 0 ;
@@ -127,8 +127,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)if (!decoder)return 0 ; -for (i =0 ; i < decoder->num_links; i++) { - link = &decoder->links[i]; +list_for_each_entry (link, &decoder->links, list) {if (link->sink->entity == decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -141,11 +140,10 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == entity)
include/media/media-entity.h +5 -5
@@ -74,6 +74,7 @@ struct media_pipeline {struct media_link {struct media_gobj graph_obj; +struct list_head list;struct media_pad *source;/* Source pad */ struct media_pad *sink;/* Sink pad */ struct media_link *reverse;/* Link in the reverse direction */
@@ -116,10 +117,9 @@ struct media_entity {u16 num_links;/* Number of existing links, both * enabled and disabled */ u16 num_backlinks;/* Number of backlinks */ -u16 max_links;/* Maximum number of links */ -struct media_pad *pads;/* Pads array (num_pads elements) */ -struct media_link *links;/* Links array (max_links elements)*/ +struct media_pad *pads;/* Pads array (num_pads objects) */ +struct list_head links;/* Links list */ const struct media_entity_operations *ops;/* Entity operations */
@@ -213,7 +213,7 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)struct media_entity_graph {struct {struct media_entity *entity; -int link; +struct list_head link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH ]; DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID);
@@ -247,7 +247,7 @@ void media_gobj_init(struct media_device *mdev,void media_gobj_remove (struct media_gobj *gobj);int media_entity_init (struct media_entity *entity,u16 num_pads, -struct media_pad *pads); +struct media_pad *pads);void media_entity_cleanup (struct media_entity *entity); int media_create_pad_link(struct media_entity *source, u16 source_pad,
Signature · 1 line
2.4.3
PATCH v8 19/55 media: convert links from array to list
The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct.
As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses krealloc() to change the size of the link, with is bad, as it leaves the memory fragmented.
So, convert links into a list.
Also, currently, both source and sink entities need the link at the graph traversal logic inside media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big.
Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed.
---
Sorry, I did some mess with my trees, and just re-sent the same patch as before. That's the right one with Javier fixes. Please ignore PATCH v8.1.
This version contains a few bug fixes folded on it, resulted from Javier's tests. I won't be respinning the entire series just due to that.
Javier: Thanks for that! I'll add you proper credits on the final version.
drivers/media/dvb-core/dvb_frontend.c +3 -6
@@ -622,7 +622,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)struct media_device *mdev = adapter->mdev;struct media_entity *entity, *source;struct media_link *link, *found_link =NULL ; -int i, ret, n_links =0 , active_links =0 ; +int ret, n_links =0 , active_links =0 ; fepriv->pipe_start_entity =NULL ;
@@ -632,8 +632,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) entity = fepriv->dvbdev->entity; fepriv->pipe_start_entity = entity; -for (i =0 ; i < entity->num_links; i++) { - link = &entity->links[i]; +list_for_each_entry (link, &entity->links, list) {if (link->sink->entity == entity) { found_link = link; n_links++;
@@ -659,13 +658,11 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe) source = found_link->source->entity; fepriv->pipe_start_entity = source; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity; -if (sink == entity) flags =MEDIA_LNK_FL_ENABLED ;
drivers/media/media-device.c +15 -10
@@ -25,6 +25,7 @@#include <linux/ioctl.h> #include <linux/media.h> #include <linux/types.h> +#include <linux/slab.h> #include <media/media-device.h> #include <media/media-devnode.h>
@@ -150,22 +151,21 @@ static long __media_device_enum_links(struct media_device *mdev, }if (links->links) { -struct media_link_desc __user *ulink; -unsigned int l; +struct media_link *ent_link; +struct media_link_desc __user *ulink = links->links; -for (l =0 , ulink = links->links; l < entity->num_links; l++) { +list_for_each_entry (ent_link, &entity->links, list) {struct media_link_desc link;/* Ignore backlinks. */ -if (entity->links[l].source->entity != entity) +if (ent_link->source->entity != entity)continue ; -memset (&link,0 ,sizeof (link)); -media_device_kpad_to_upad (entity->links[l].source, +media_device_kpad_to_upad (ent_link->source, &link.source); -media_device_kpad_to_upad (entity->links[l].sink, +media_device_kpad_to_upad (ent_link->sink, &link.sink); - link.flags = entity->links[l].flags; + link.flags = ent_link->flags;if (copy_to_user (ulink, &link,sizeof (*ulink)))return -EFAULT ; ulink++;
@@ -437,6 +437,7 @@ 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);spin_lock (&mdev->lock);/* Initialize media_gobj embedded at the entity */
@@ -465,13 +466,17 @@ void media_device_unregister_entity(struct media_entity *entity) {int i;struct media_device *mdev = entity->graph_obj.mdev; +struct media_link *link, *tmp;if (mdev ==NULL )return ;spin_lock (&mdev->lock); -for (i =0 ; i < entity->num_links; i++) -media_gobj_remove (&entity->links[i].graph_obj); +list_for_each_entry_safe (link, tmp, &entity->links, list) { +media_gobj_remove (&link->graph_obj); +list_del (&link->list); +kfree (link); + }for (i =0 ; i < entity->num_pads; i++)media_gobj_remove (&entity->pads[i].graph_obj);media_gobj_remove (&entity->graph_obj);
drivers/media/media-entity.c +64 -66
249 lines not on this page · raw message
drivers/media/usb/au0828/au0828-core.c +5 -7
@@ -261,13 +261,11 @@ static void au0828_create_media_graph(struct au0828_dev *dev)if (tuner)media_create_pad_link (tuner,0 , decoder,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vdev.entity.links) -media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , -MEDIA_LNK_FL_ENABLED ); -if (dev->vbi_dev.entity.links) -media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , -MEDIA_LNK_FL_ENABLED ); +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,1 , &dev->vdev.entity,0 , +MEDIA_LNK_FL_ENABLED ); +media_create_pad_link (decoder,2 , &dev->vbi_dev.entity,0 , +MEDIA_LNK_FL_ENABLED );#endif }
drivers/media/usb/au0828/au0828-video.c +3 -5
@@ -643,7 +643,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)struct media_device *mdev = dev->media_dev;struct media_entity *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev || !dev->decoder)return 0 ;
@@ -655,8 +655,7 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)* do DVB streaming while the DMA engine is being used for V4L2, * this should be enough for the actual needs. */ -for (i =0 ; i < dev->decoder->num_links; i++) { - link = &dev->decoder->links[i]; +list_for_each_entry (link, &dev->decoder->links, list) {if (link->sink->entity == dev->decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -669,11 +668,10 @@ static int au0828_enable_analog_tuner(struct au0828_dev *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == dev->decoder)
drivers/media/usb/cx231xx/cx231xx-video.c +3 -5
@@ -106,7 +106,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)struct media_device *mdev = dev->media_dev;struct media_entity *entity, *decoder =NULL , *source;struct media_link *link, *found_link =NULL ; -int i, ret, active_links =0 ; +int ret, active_links =0 ;if (!mdev)return 0 ;
@@ -127,8 +127,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)if (!decoder)return 0 ; -for (i =0 ; i < decoder->num_links; i++) { - link = &decoder->links[i]; +list_for_each_entry (link, &decoder->links, list) {if (link->sink->entity == decoder) { found_link = link;if (link->flags &MEDIA_LNK_FL_ENABLED )
@@ -141,11 +140,10 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)return 0 ; source = found_link->source->entity; -for (i =0 ; i < source->num_links; i++) { +list_for_each_entry (link, &source->links, list) {struct media_entity *sink;int flags =0 ; - link = &source->links[i]; sink = link->sink->entity;if (sink == entity)
include/media/media-entity.h +5 -5
@@ -74,6 +74,7 @@ struct media_pipeline {struct media_link {struct media_gobj graph_obj; +struct list_head list;struct media_pad *source;/* Source pad */ struct media_pad *sink;/* Sink pad */ struct media_link *reverse;/* Link in the reverse direction */
@@ -116,10 +117,9 @@ struct media_entity {u16 num_links;/* Number of existing links, both * enabled and disabled */ u16 num_backlinks;/* Number of backlinks */ -u16 max_links;/* Maximum number of links */ -struct media_pad *pads;/* Pads array (num_pads elements) */ -struct media_link *links;/* Links array (max_links elements)*/ +struct media_pad *pads;/* Pads array (num_pads objects) */ +struct list_head links;/* Links list */ const struct media_entity_operations *ops;/* Entity operations */
@@ -213,7 +213,7 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)struct media_entity_graph {struct {struct media_entity *entity; -int link; +struct list_head *link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH ]; DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID);
@@ -247,7 +247,7 @@ void media_gobj_init(struct media_device *mdev,void media_gobj_remove (struct media_gobj *gobj);int media_entity_init (struct media_entity *entity,u16 num_pads, -struct media_pad *pads); +struct media_pad *pads);void media_entity_cleanup (struct media_entity *entity); int media_create_pad_link(struct media_entity *source, u16 source_pad,
Signature · 1 line
2.4.3
PATCH v8 20/55 media: make add link more generic
In reply to Mauro Carvalho ChehabThe media_entity_add_link() function takes an entity as an argument just to get the list head.
Make it more generic by changing the function argument to list_head.
No functional changes.
drivers/media/media-entity.c +4 -4
@@ -580,7 +580,7 @@ EXPORT_SYMBOL_GPL(media_entity_put);* Links management */ -static struct media_link *media_entity_add_link (struct media_entity *entity) +static struct media_link *media_add_link (struct list_head *head) {struct media_link *link;
@@ -588,7 +588,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity)if (link ==NULL )return NULL ; -list_add_tail (&link->list, &entity->links); +list_add_tail (&link->list, head);return link; }
@@ -607,7 +607,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,BUG_ON (source_pad >= source->num_pads);BUG_ON (sink_pad >= sink->num_pads); - link =media_entity_add_link (source); + link =media_add_link (&source->links);if (link ==NULL )return -ENOMEM ;
@@ -622,7 +622,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,/* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. */ - backlink =media_entity_add_link (sink); + backlink =media_add_link (&sink->links);if (backlink ==NULL ) {__media_entity_remove_link (source, link);return -ENOMEM ;
Signature · 1 line
2.4.3
Re: [PATCH v8 20/55] [media] media: make add link more generic
Quoted 9 lines · Mauro Carvalho Chehab
The
media_entity_add_link()function takes an entity as an argument just to get the list head.Make it more generic by changing the function argument to
list_head.No functional changes.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 42 lines
drivers/media/media-entity.c +4
-4@@ -580,7 +580,7 @@ EXPORT_SYMBOL_GPL(media_entity_put);* Links management */ -static struct media_link *media_entity_add_link (struct media_entity *entity) +static struct media_link *media_add_link (struct list_head *head) {struct media_link *link;@@ -588,7 +588,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity)if (link ==NULL )return NULL ; -list_add_tail (&link->list, &entity->links); +list_add_tail (&link->list, head);return link; }@@ -607,7 +607,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,BUG_ON (source_pad >= source->num_pads);BUG_ON (sink_pad >= sink->num_pads); - link =media_entity_add_link (source); + link =media_add_link (&source->links);if (link ==NULL )return -ENOMEM ;@@ -622,7 +622,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,/* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. */ - backlink =media_entity_add_link (sink); + backlink =media_add_link (&sink->links);if (backlink ==NULL ) {__media_entity_remove_link (source, link);return -ENOMEM ;
PATCH v8 21/55 media: make media_link more generic to handle interace links
In reply to Mauro Carvalho ChehabBy adding an union at media_link, we get for free a way to represent interface->entity links.
No need to change anything at the code, just at the internal header file.
include/media/media-entity.h +11 -5
@@ -75,14 +75,20 @@ struct media_pipeline {struct media_link {struct media_gobj graph_obj;struct list_head list; -struct media_pad *source;/* Source pad */ -struct media_pad *sink;/* Sink pad */ +union { +struct media_gobj *gobj0; +struct media_pad *source; + }; +union { +struct media_gobj *gobj1; +struct media_pad *sink; + };struct media_link *reverse;/* Link in the reverse direction */ unsigned long flags;/* Link flags (MEDIA_LNK_FL_*) */ };struct media_pad { -struct media_gobj graph_obj; +struct media_gobj graph_obj;/* must be first field in struct */ struct media_entity *entity;/* Entity this pad belongs to */ u16 index;/* Pad index in the entity pads array */ unsigned long flags;/* Pad flags (MEDIA_PAD_FL_*) */
@@ -105,7 +111,7 @@ struct media_entity_operations { };struct media_entity { -struct media_gobj graph_obj; +struct media_gobj graph_obj;/* must be first field in struct */ struct list_head list;const char *name;/* Entity name */ u32 type;/* Entity type (MEDIA_ENT_T_*) */
@@ -119,7 +125,7 @@ struct media_entity {u16 num_backlinks;/* Number of backlinks */ struct media_pad *pads;/* Pads array (num_pads objects) */ -struct list_head links;/* Links list */ +struct list_head links;/* Pad-to-pad links list */ const struct media_entity_operations *ops;/* Entity operations */
Signature · 1 line
2.4.3
Re: [PATCH v8 21/55] [media] media: make media_link more generic to handle interace links
Quoted 7 lines · Mauro Carvalho Chehab
By adding an union at
media_link, we get for free a way to representinterface->entitylinks.No need to change anything at the code, just at the internal header file.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 48 lines
include/media/media-entity.h +11
-5@@ -75,14 +75,20 @@ struct media_pipeline {struct media_link {struct media_gobj graph_obj;struct list_head list; -struct media_pad *source;/* Source pad */ -struct media_pad *sink;/* Sink pad */ +union { +struct media_gobj *gobj0; +struct media_pad *source; + }; +union { +struct media_gobj *gobj1; +struct media_pad *sink; + };struct media_link *reverse;/* Link in the reverse direction */ unsigned long flags;/* Link flags (MEDIA_LNK_FL_*) */ };struct media_pad { -struct media_gobj graph_obj; +struct media_gobj graph_obj;/* must be first field in struct */ struct media_entity *entity;/* Entity this pad belongs to */ u16 index;/* Pad index in the entity pads array */ unsigned long flags;/* Pad flags (MEDIA_PAD_FL_*) */ @@ -105,7 +111,7 @@ struct media_entity_operations { };struct media_entity { -struct media_gobj graph_obj; +struct media_gobj graph_obj;/* must be first field in struct */ struct list_head list;const char *name;/* Entity name */ u32 type;/* Entity type (MEDIA_ENT_T_*) */ @@ -119,7 +125,7 @@ struct media_entity {u16 num_backlinks;/* Number of backlinks */ struct media_pad *pads;/* Pads array (num_pads objects) */ -struct list_head links;/* Links list */ +struct list_head links;/* Pad-to-pad links list */ const struct media_entity_operations *ops;/* Entity operations */
PATCH v8 22/55 media: make link debug printk more generic
In reply to Mauro Carvalho ChehabRemove entity name from the link as this exists only if the object type is PAD on both link ends.
drivers/media/media-entity.c +5 -7
@@ -106,16 +106,14 @@ 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 0x%08x link#%d: '%s' %s#%d ==> '%s' %s#%d\n" , +"%s: id 0x%08x link#%d: %s#%d ==> %s#%d\n" , event_name, gobj->id,media_localid (gobj), - link->source->entity->name, -gobj_type (media_type (&link->source->graph_obj)), -media_localid (&link->source->graph_obj), +gobj_type (media_type (link->gobj0)), +media_localid (link->gobj0), - link->sink->entity->name, -gobj_type (media_type (&link->sink->graph_obj)), -media_localid (&link->sink->graph_obj)); +gobj_type (media_type (link->gobj1)), +media_localid (link->gobj1));break ; }case MEDIA_GRAPH_PAD :
Signature · 1 line
2.4.3
PATCH v8 23/55 media: add support to link interfaces and entities
In reply to Mauro Carvalho ChehabNow that we have a new graph object called "interfaces", we need to be able to link them to the entities.
Add a linked list to the interfaces to allow them to be linked to the entities.
drivers/media/media-entity.c +38 -0
@@ -869,6 +869,7 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, intf->type = type; intf->flags = flags; +INIT_LIST_HEAD (&intf->links); devnode->major = major; devnode->minor = minor;
@@ -886,3 +887,40 @@ void media_devnode_remove(struct media_intf_devnode *devnode)kfree (devnode); }EXPORT_SYMBOL_GPL (media_devnode_remove); + +struct media_link *media_create_intf_link (struct media_entity *entity, +struct media_interface *intf, +u32 flags) +{ +struct media_link *link; + + link =media_add_link (&intf->links); +if (link ==NULL ) +return NULL ; + + link->intf = intf; + link->entity = entity; + link->flags = flags; + +/* Initialize graph object embedded at the new link */ +media_gobj_init (intf->graph_obj.mdev,MEDIA_GRAPH_LINK , + &link->graph_obj); + +return link; +} +EXPORT_SYMBOL_GPL (media_create_intf_link); + + +static void __media_remove_intf_link (struct media_link *link) +{ +media_gobj_remove (&link->graph_obj); +kfree (link); +} + +void media_remove_intf_link (struct media_link *link) +{ +mutex_lock (&link->graph_obj.mdev->graph_mutex); +__media_remove_intf_link (link); +mutex_unlock (&link->graph_obj.mdev->graph_mutex); +} +EXPORT_SYMBOL_GPL (media_remove_intf_link);
include/media/media-entity.h +9 -0
@@ -78,10 +78,12 @@ struct media_link {union {struct media_gobj *gobj0;struct media_pad *source; +struct media_interface *intf; };union {struct media_gobj *gobj1;struct media_pad *sink; +struct media_entity *entity; };struct media_link *reverse;/* Link in the reverse direction */ unsigned long flags;/* Link flags (MEDIA_LNK_FL_*) */
@@ -154,6 +156,7 @@ struct media_entity {* struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object +* @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g. * MEDIA_INTF_T_*
@@ -161,6 +164,7 @@ struct media_entity {*/ struct media_interface {struct media_gobj graph_obj; +struct list_head links;u32 type;u32 flags; };
@@ -283,6 +287,11 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, u32 major, u32 minor, gfp_t gfp_flags);void media_devnode_remove (struct media_intf_devnode *devnode); +struct media_link *media_create_intf_link (struct media_entity *entity, +struct media_interface *intf, +u32 flags); +void media_remove_intf_link (struct media_link *link); + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
Signature · 1 line
2.4.3
Re: [PATCH v8 23/55] [media] media: add support to link interfaces and entities
Quoted 7 lines · Mauro Carvalho Chehab
Now that we have a new graph object called "interfaces", we need to be able to link them to the entities.
Add a linked list to the interfaces to allow them to be linked to the entities.
Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 42 lines
drivers/media/media-entity.c +26
-0@@ -869,6 +869,7 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, intf->type = type; intf->flags = flags; +INIT_LIST_HEAD (&intf->links); devnode->major = major; devnode->minor = minor;@@ -886,3 +887,40 @@ void media_devnode_remove(struct media_intf_devnode *devnode)kfree (devnode); }EXPORT_SYMBOL_GPL (media_devnode_remove); + +struct media_link *media_create_intf_link (struct media_entity *entity, +struct media_interface *intf, +u32 flags) +{ +struct media_link *link; + + link =media_add_link (&intf->links); +if (link ==NULL ) +return NULL ; + + link->intf = intf; + link->entity = entity; + link->flags = flags; + +/* Initialize graph object embedded at the new link */ +media_gobj_init (intf->graph_obj.mdev,MEDIA_GRAPH_LINK , + &link->graph_obj); + +return link; +} +EXPORT_SYMBOL_GPL (media_create_intf_link); + + +static void __media_remove_intf_link (struct media_link *link)
drivers/media/media-entity.c void media_devnode_remove(struct media_intf_devnode *devnode) · line 924
Quoted 10 lines
drivers/media/media-entity.c +10
-0+{ +media_gobj_remove (&link->graph_obj); +kfree (link); +} + +void media_remove_intf_link (struct media_link *link) +{ +mutex_lock (&link->graph_obj.mdev->graph_mutex); +__media_remove_intf_link (link); +mutex_unlock (&link->graph_obj.mdev->graph_mutex);
link was just freed, so you can't dereference link anymore.
Instead use a temp 'mdev' pointer to access the mutex.
Regards,
Hans
Quoted 48 lines
drivers/media/media-entity.c +2
-0+} +EXPORT_SYMBOL_GPL (media_remove_intf_link);include/media/media-entity.h +9
-0@@ -78,10 +78,12 @@ struct media_link {union {struct media_gobj *gobj0;struct media_pad *source; +struct media_interface *intf; };union {struct media_gobj *gobj1;struct media_pad *sink; +struct media_entity *entity; };struct media_link *reverse;/* Link in the reverse direction */ unsigned long flags;/* Link flags (MEDIA_LNK_FL_*) */ @@ -154,6 +156,7 @@ struct media_entity {* struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object +* @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g. * MEDIA_INTF_T_* @@ -161,6 +164,7 @@ struct media_entity {*/ struct media_interface {struct media_gobj graph_obj; +struct list_head links;u32 type;u32 flags; };@@ -283,6 +287,11 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, u32 major, u32 minor, gfp_t gfp_flags);void media_devnode_remove (struct media_intf_devnode *devnode); +struct media_link *media_create_intf_link (struct media_entity *entity, +struct media_interface *intf, +u32 flags); +void media_remove_intf_link (struct media_link *link); + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
PATCH v8 24/55 media-entity: add a helper function to create interface
In reply to Mauro Carvalho ChehabAs we'll be adding other interface types in the future, put the common interface create code on a separate function.
drivers/media/media-entity.c +14 -9
@@ -851,6 +851,18 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad)EXPORT_SYMBOL_GPL (media_entity_remote_pad); +static void media_interface_init (struct media_device *mdev, +struct media_interface *intf, +u32 gobj_type, +u32 intf_type,u32 flags) +{ + intf->type = intf_type; + intf->flags = flags; +INIT_LIST_HEAD (&intf->links); + +media_gobj_init (mdev, gobj_type, &intf->graph_obj); +} +/* Functions related to the media interface via device nodes */ struct media_intf_devnode *media_devnode_create(struct media_device *mdev,
@@ -859,23 +871,16 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, gfp_t gfp_flags) {struct media_intf_devnode *devnode; -struct media_interface *intf; devnode =kzalloc (sizeof (*devnode), gfp_flags);if (!devnode)return NULL ; - intf = &devnode->intf; - - intf->type = type; - intf->flags = flags; -INIT_LIST_HEAD (&intf->links); - devnode->major = major; devnode->minor = minor; -media_gobj_init (mdev,MEDIA_GRAPH_INTF_DEVNODE , - &devnode->intf.graph_obj); +media_interface_init (mdev, &devnode->intf,MEDIA_GRAPH_INTF_DEVNODE , + type, flags);return devnode; }
Signature · 1 line
2.4.3
Re: [PATCH v8 24/55] [media] media-entity: add a helper function to create interface
Quoted 5 lines · Mauro Carvalho Chehab
As we'll be adding other interface types in the future, put the common interface create code on a separate function.
Suggested-by Hans Verkuil <[email protected]>Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 51 lines
drivers/media/media-entity.c +14
-9@@ -851,6 +851,18 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad)EXPORT_SYMBOL_GPL (media_entity_remote_pad); +static void media_interface_init (struct media_device *mdev, +struct media_interface *intf, +u32 gobj_type, +u32 intf_type,u32 flags) +{ + intf->type = intf_type; + intf->flags = flags; +INIT_LIST_HEAD (&intf->links); + +media_gobj_init (mdev, gobj_type, &intf->graph_obj); +} +/* Functions related to the media interface via device nodes */ struct media_intf_devnode *media_devnode_create(struct media_device *mdev,@@ -859,23 +871,16 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, gfp_t gfp_flags) {struct media_intf_devnode *devnode; -struct media_interface *intf; devnode =kzalloc (sizeof (*devnode), gfp_flags);if (!devnode)return NULL ; - intf = &devnode->intf; - - intf->type = type; - intf->flags = flags; -INIT_LIST_HEAD (&intf->links); - devnode->major = major; devnode->minor = minor; -media_gobj_init (mdev,MEDIA_GRAPH_INTF_DEVNODE , - &devnode->intf.graph_obj); +media_interface_init (mdev, &devnode->intf,MEDIA_GRAPH_INTF_DEVNODE , + type, flags);return devnode; }
PATCH v8 25/55 dvbdev: add support for interfaces
In reply to Mauro Carvalho ChehabNow that the infrastruct for that is set, add support for interfaces.
Please notice that we're missing two links:
DVB FE intf -> tuner DVB demux intf -> dvr
Those should be added latter, after having the entire graph set. With the current infrastructure, those should be added at dvb_create_media_graph(), but it would also require some extra core changes, to allow the function to enumerate the interfaces.
drivers/media/dvb-core/dvbdev.c +78 -24
@@ -180,14 +180,36 @@ skip:return -ENFILE ; } -static void dvb_register_media_device (struct dvb_device *dvbdev, -int type,int minor) +static void dvb_create_media_entity (struct dvb_device *dvbdev, +int type,int minor) {#if defined(CONFIG_MEDIA_CONTROLLER_DVB )int ret =0 , npads; -if (!dvbdev->adapter->mdev) +switch (type) { +case DVB_DEVICE_FRONTEND : + npads =2 ; +break ; +case DVB_DEVICE_DEMUX : + npads =2 ; +break ; +case DVB_DEVICE_CA : + npads =2 ; +break ; +case DVB_DEVICE_NET : +/* +* We should be creating entities for the MPE/ULE +* decapsulation hardware (or software implementation). +* +* However, the number of for the MPE/ULE decaps may not be +* fixed. As we don't have yet dynamic support for PADs at +* the Media Controller, let's not create the decap +* entities yet. +*/ return ; +default : +return ; + } dvbdev->entity =kzalloc (sizeof (*dvbdev->entity),GFP_KERNEL );if (!dvbdev->entity)
@@ -197,19 +219,6 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, dvbdev->entity->info.dev.minor = minor; dvbdev->entity->name = dvbdev->name; -switch (type) { -case DVB_DEVICE_CA : -case DVB_DEVICE_DEMUX : -case DVB_DEVICE_FRONTEND : - npads =2 ; -break ; -case DVB_DEVICE_NET : - npads =0 ; -break ; -default : - npads =1 ; - } -if (npads) { dvbdev->pads =kcalloc (npads,sizeof (*dvbdev->pads),GFP_KERNEL );
@@ -230,18 +239,11 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ; -case DVB_DEVICE_DVR : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_DVR ; - dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; -break ;case DVB_DEVICE_CA : dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_CA ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ; -case DVB_DEVICE_NET : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_NET ; -break ;default :kfree (dvbdev->entity); dvbdev->entity =NULL ;
@@ -263,11 +265,63 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,return ; } -printk (KERN_DEBUG "%s: media device '%s' registered.\n" , +printk (KERN_DEBUG "%s: media entity '%s' registered.\n" , __func__, dvbdev->entity->name);#endif } +static void dvb_register_media_device (struct dvb_device *dvbdev, +int type,int minor) +{ +#if defined(CONFIG_MEDIA_CONTROLLER_DVB ) +u32 intf_type; + +if (!dvbdev->adapter->mdev) +return ; + +dvb_create_media_entity (dvbdev, type, minor); + +switch (type) { +case DVB_DEVICE_FRONTEND : + intf_type =MEDIA_INTF_T_DVB_FE ; +break ; +case DVB_DEVICE_DEMUX : + intf_type =MEDIA_INTF_T_DVB_DEMUX ; +break ; +case DVB_DEVICE_DVR : + intf_type =MEDIA_INTF_T_DVB_DVR ; +break ; +case DVB_DEVICE_CA : + intf_type =MEDIA_INTF_T_DVB_CA ; +break ; +case DVB_DEVICE_NET : + intf_type =MEDIA_INTF_T_DVB_NET ; +break ; +default : +return ; + } + + dvbdev->intf_devnode =media_devnode_create (dvbdev->adapter->mdev, + intf_type,0 , +DVB_MAJOR , minor, +GFP_KERNEL ); + +/* +* Create the "obvious" link, e. g. the ones that represent +* a direct association between an interface and an entity. +* Other links should be created elsewhere, like: +* DVB FE intf -> tuner +* DVB demux intf -> dvr +*/ + +if (!dvbdev->entity || !dvbdev->intf_devnode) +return ; + +media_create_intf_link (dvbdev->entity, &dvbdev->intf_devnode->intf,0 ); + +#endif +} +int dvb_register_device (struct dvb_adapter *adap,struct dvb_device **pdvbdev,const struct dvb_device *template,void *priv,int type) {
drivers/media/dvb-core/dvbdev.h +1 -0
@@ -149,6 +149,7 @@ struct dvb_device {/* Allocated and filled inside dvbdev.c */ struct media_entity *entity; +struct media_intf_devnode *intf_devnode;struct media_pad *pads;#endif
Signature · 1 line
2.4.3
Re: [PATCH v8 25/55] [media] dvbdev: add support for interfaces
Quoted 7 lines · Mauro Carvalho Chehab
Now that the infrastruct for that is set, add support for interfaces.
Please notice that we're missing two links:
DVB FE intf -> tuner DVB demux intf -> dvr
Quoted 7 lines
Those should be added latter, after having the entire graph set. With the current infrastructure, those should be added at
dvb_create_media_graph(), but it would also require some extra core changes, to allow the function to enumerate the interfaces.Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 162 lines
drivers/media/dvb-core/dvbdev.c +78
-24@@ -180,14 +180,36 @@ skip:return -ENFILE ; } -static void dvb_register_media_device (struct dvb_device *dvbdev, -int type,int minor) +static void dvb_create_media_entity (struct dvb_device *dvbdev, +int type,int minor) {#if defined(CONFIG_MEDIA_CONTROLLER_DVB )int ret =0 , npads; -if (!dvbdev->adapter->mdev) +switch (type) { +case DVB_DEVICE_FRONTEND : + npads =2 ; +break ; +case DVB_DEVICE_DEMUX : + npads =2 ; +break ; +case DVB_DEVICE_CA : + npads =2 ; +break ; +case DVB_DEVICE_NET : +/* +* We should be creating entities for the MPE/ULE +* decapsulation hardware (or software implementation). +* +* However, the number of for the MPE/ULE decaps may not be +* fixed. As we don't have yet dynamic support for PADs at +* the Media Controller, let's not create the decap +* entities yet. +*/ return ; +default : +return ; + } dvbdev->entity =kzalloc (sizeof (*dvbdev->entity),GFP_KERNEL );if (!dvbdev->entity)@@ -197,19 +219,6 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, dvbdev->entity->info.dev.minor = minor; dvbdev->entity->name = dvbdev->name; -switch (type) { -case DVB_DEVICE_CA : -case DVB_DEVICE_DEMUX : -case DVB_DEVICE_FRONTEND : - npads =2 ; -break ; -case DVB_DEVICE_NET : - npads =0 ; -break ; -default : - npads =1 ; - } -if (npads) { dvbdev->pads =kcalloc (npads,sizeof (*dvbdev->pads),GFP_KERNEL );@@ -230,18 +239,11 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ; -case DVB_DEVICE_DVR : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_DVR ; - dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; -break ;case DVB_DEVICE_CA : dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_CA ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ; -case DVB_DEVICE_NET : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_NET ; -break ;default :kfree (dvbdev->entity); dvbdev->entity =NULL ;@@ -263,11 +265,63 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,return ; } -printk (KERN_DEBUG "%s: media device '%s' registered.\n" , +printk (KERN_DEBUG "%s: media entity '%s' registered.\n" , __func__, dvbdev->entity->name);#endif } +static void dvb_register_media_device (struct dvb_device *dvbdev, +int type,int minor) +{ +#if defined(CONFIG_MEDIA_CONTROLLER_DVB ) +u32 intf_type; + +if (!dvbdev->adapter->mdev) +return ; + +dvb_create_media_entity (dvbdev, type, minor); + +switch (type) { +case DVB_DEVICE_FRONTEND : + intf_type =MEDIA_INTF_T_DVB_FE ; +break ; +case DVB_DEVICE_DEMUX : + intf_type =MEDIA_INTF_T_DVB_DEMUX ; +break ; +case DVB_DEVICE_DVR : + intf_type =MEDIA_INTF_T_DVB_DVR ; +break ; +case DVB_DEVICE_CA : + intf_type =MEDIA_INTF_T_DVB_CA ; +break ; +case DVB_DEVICE_NET : + intf_type =MEDIA_INTF_T_DVB_NET ; +break ; +default : +return ; + } + + dvbdev->intf_devnode =media_devnode_create (dvbdev->adapter->mdev, + intf_type,0 , +DVB_MAJOR , minor, +GFP_KERNEL ); + +/* +* Create the "obvious" link, e. g. the ones that represent +* a direct association between an interface and an entity. +* Other links should be created elsewhere, like: +* DVB FE intf -> tuner +* DVB demux intf -> dvr +*/ + +if (!dvbdev->entity || !dvbdev->intf_devnode) +return ; + +media_create_intf_link (dvbdev->entity, &dvbdev->intf_devnode->intf,0 ); + +#endif +} +int dvb_register_device (struct dvb_adapter *adap,struct dvb_device **pdvbdev,const struct dvb_device *template,void *priv,int type) {drivers/media/dvb-core/dvbdev.h +1
-0@@ -149,6 +149,7 @@ struct dvb_device {/* Allocated and filled inside dvbdev.c */ struct media_entity *entity; +struct media_intf_devnode *intf_devnode;struct media_pad *pads;#endif
PATCH v8 26/55 media: add a linked list to track interfaces by mdev
In reply to Mauro Carvalho ChehabThe media device should list the interface objects, so add a linked list for those interfaces in struct media_device.
drivers/media/media-device.c +1 -0
@@ -381,6 +381,7 @@ int __must_check __media_device_register(struct media_device *mdev,return -EINVAL ;INIT_LIST_HEAD (&mdev->entities); +INIT_LIST_HEAD (&mdev->interfaces);spin_lock_init (&mdev->lock);mutex_init (&mdev->graph_mutex);
drivers/media/media-entity.c +3 -0
@@ -861,6 +861,8 @@ static void media_interface_init(struct media_device *mdev,INIT_LIST_HEAD (&intf->links);media_gobj_init (mdev, gobj_type, &intf->graph_obj); + +list_add_tail (&intf->list, &mdev->interfaces); }/* Functions related to the media interface via device nodes */
@@ -889,6 +891,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create);void media_devnode_remove (struct media_intf_devnode *devnode) {media_gobj_remove (&devnode->intf.graph_obj); +list_del (&devnode->intf.list);kfree (devnode); }EXPORT_SYMBOL_GPL (media_devnode_remove);
include/media/media-device.h +2 -0
@@ -46,6 +46,7 @@ struct device;* @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities +* @interfaces: List of registered interfaces * @lock: Entities list lock * @graph_mutex: Entities graph operation lock * @link_notify: Link state change notification callback
@@ -77,6 +78,7 @@ struct media_device {u32 intf_devnode_id;struct list_head entities; +struct list_head interfaces;/* Protects the entities list */ spinlock_t lock;
include/media/media-entity.h +3 -0
@@ -156,6 +156,8 @@ struct media_entity {* struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object +* @list: Linked list used to find other interfaces that belong +* to the same media controller * @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g.
@@ -164,6 +166,7 @@ struct media_entity {*/ struct media_interface {struct media_gobj graph_obj; +struct list_head list;struct list_head links;u32 type;u32 flags;
Signature · 1 line
2.4.3
Re: [PATCH v8 26/55] [media] media: add a linked list to track interfaces by mdev
Quoted 4 lines · Mauro Carvalho Chehab
The media device should list the interface objects, so add a linked list for those interfaces in struct
media_device.Signed-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 76 lines
drivers/media/media-device.c +1
-0@@ -381,6 +381,7 @@ int __must_check __media_device_register(struct media_device *mdev,return -EINVAL ;INIT_LIST_HEAD (&mdev->entities); +INIT_LIST_HEAD (&mdev->interfaces);spin_lock_init (&mdev->lock);mutex_init (&mdev->graph_mutex);drivers/media/media-entity.c +3
-0@@ -861,6 +861,8 @@ static void media_interface_init(struct media_device *mdev,INIT_LIST_HEAD (&intf->links);media_gobj_init (mdev, gobj_type, &intf->graph_obj); + +list_add_tail (&intf->list, &mdev->interfaces); }/* Functions related to the media interface via device nodes */ @@ -889,6 +891,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create);void media_devnode_remove (struct media_intf_devnode *devnode) {media_gobj_remove (&devnode->intf.graph_obj); +list_del (&devnode->intf.list);kfree (devnode); }EXPORT_SYMBOL_GPL (media_devnode_remove);include/media/media-device.h +2
-0@@ -46,6 +46,7 @@ struct device;* @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities +* @interfaces: List of registered interfaces * @lock: Entities list lock * @graph_mutex: Entities graph operation lock * @link_notify: Link state change notification callback @@ -77,6 +78,7 @@ struct media_device {u32 intf_devnode_id;struct list_head entities; +struct list_head interfaces;/* Protects the entities list */ spinlock_t lock;include/media/media-entity.h +3
-0@@ -156,6 +156,8 @@ struct media_entity {* struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object +* @list: Linked list used to find other interfaces that belong +* to the same media controller * @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g. @@ -164,6 +166,7 @@ struct media_entity {*/ struct media_interface {struct media_gobj graph_obj; +struct list_head list;struct list_head links;u32 type;u32 flags;
PATCH v8 27/55 dvbdev: add support for indirect interface links
In reply to Mauro Carvalho ChehabSome interfaces indirectly control multiple entities. Add support for those.
drivers/media/dvb-core/dvbdev.c +13 -0
@@ -441,6 +441,7 @@ void dvb_create_media_graph(struct dvb_adapter *adap)struct media_device *mdev = adap->mdev;struct media_entity *entity, *tuner =NULL , *fe =NULL ;struct media_entity *demux =NULL , *dvr =NULL , *ca =NULL ; +struct media_interface *intf;if (!mdev)return ;
@@ -476,6 +477,18 @@ void dvb_create_media_graph(struct dvb_adapter *adap)if (demux && ca)media_create_pad_link (demux,1 , ca,0 ,MEDIA_LNK_FL_ENABLED ); + +/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ +list_for_each_entry (intf, &mdev->interfaces, list) { +if (intf->type ==MEDIA_INTF_T_DVB_CA && ca) +media_create_intf_link (ca, intf,0 ); +if (intf->type ==MEDIA_INTF_T_DVB_FE && tuner) +media_create_intf_link (tuner, intf,0 ); +if (intf->type ==MEDIA_INTF_T_DVB_DVR && demux) +media_create_intf_link (demux, intf,0 ); + } + + }EXPORT_SYMBOL_GPL (dvb_create_media_graph);#endif
Signature · 1 line
2.4.3
Re: [PATCH v8 27/55] [media] dvbdev: add support for indirect interface links
Quoted 23 lines · Mauro Carvalho Chehab
Some interfaces indirectly control multiple entities. Add support for those.
Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/dvb-core/dvbdev.c +3
-0@@ -441,6 +441,7 @@ void dvb_create_media_graph(struct dvb_adapter *adap)struct media_device *mdev = adap->mdev;struct media_entity *entity, *tuner =NULL , *fe =NULL ;struct media_entity *demux =NULL , *dvr =NULL , *ca =NULL ; +struct media_interface *intf;if (!mdev)return ;@@ -476,6 +477,18 @@ void dvb_create_media_graph(struct dvb_adapter *adap)if (demux && ca)media_create_pad_link (demux,1 , ca,0 ,MEDIA_LNK_FL_ENABLED ); + +/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */
drivers/media/dvb-core/dvbdev.c void dvb_create_media_graph(struct dvb_adapter *adap) · line 491
Quoted 10 lines
drivers/media/dvb-core/dvbdev.c +10
-0+list_for_each_entry (intf, &mdev->interfaces, list) { +if (intf->type ==MEDIA_INTF_T_DVB_CA && ca) +media_create_intf_link (ca, intf,0 ); +if (intf->type ==MEDIA_INTF_T_DVB_FE && tuner) +media_create_intf_link (tuner, intf,0 ); +if (intf->type ==MEDIA_INTF_T_DVB_DVR && demux) +media_create_intf_link (demux, intf,0 ); + } + +
Spurious newlines.
After removing you can add my:
Quoted 4 lines
drivers/media/dvb-core/dvbdev.c +0
-0}EXPORT_SYMBOL_GPL (dvb_create_media_graph);#endif
PATCH v8 28/55 uapi/media.h: Fix entity namespace
In reply to Mauro Carvalho ChehabNow that interfaces got created, we need to fix the entity namespace.
So, let's create a consistent new namespace and add backward compatibility macros to keep the old namespace preserved.
drivers/media/dvb-core/dvbdev.c +13 -13
@@ -230,17 +230,17 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,switch (type) {case DVB_DEVICE_FRONTEND : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_FE ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_DEMOD ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;case DVB_DEVICE_DEMUX : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_DEMUX ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_DEMUX ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;case DVB_DEVICE_CA : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_CA ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_CA ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;
@@ -439,7 +439,7 @@ EXPORT_SYMBOL(dvb_unregister_device);void dvb_create_media_graph (struct dvb_adapter *adap) {struct media_device *mdev = adap->mdev; -struct media_entity *entity, *tuner =NULL , *fe =NULL ; +struct media_entity *entity, *tuner =NULL , *demod =NULL ;struct media_entity *demux =NULL , *dvr =NULL , *ca =NULL ;struct media_interface *intf;
@@ -451,26 +451,26 @@ void dvb_create_media_graph(struct dvb_adapter *adap)case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : tuner = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_FE : - fe = entity; +case MEDIA_ENT_T_DVB_DEMOD : + demod = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_DEMUX : +case MEDIA_ENT_T_DVB_DEMUX : demux = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_DVR : +case MEDIA_ENT_T_DVB_TSOUT : dvr = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_CA : +case MEDIA_ENT_T_DVB_CA : ca = entity;break ; } } -if (tuner && fe) -media_create_pad_link (tuner,0 , fe,0 ,0 ); +if (tuner && demod) +media_create_pad_link (tuner,0 , demod,0 ,0 ); -if (fe && demux) -media_create_pad_link (fe,1 , demux,0 ,MEDIA_LNK_FL_ENABLED ); +if (demod && demux) +media_create_pad_link (demod,1 , demux,0 ,MEDIA_LNK_FL_ENABLED );if (demux && dvr)media_create_pad_link (demux,1 , dvr,0 ,MEDIA_LNK_FL_ENABLED );
include/uapi/linux/media.h +58 -18
89 lines not on this page · raw message
Signature · 1 line
2.4.3
Re: [PATCH v8 28/55] [media] uapi/media.h: Fix entity namespace
Quoted 87 lines · Mauro Carvalho Chehab
Now that interfaces got created, we need to fix the entity namespace.
So, let's create a consistent new namespace and add backward compatibility macros to keep the old namespace preserved.
Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/dvb-core/dvbdev.c +13
-13@@ -230,17 +230,17 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,switch (type) {case DVB_DEVICE_FRONTEND : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_FE ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_DEMOD ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;case DVB_DEVICE_DEMUX : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_DEMUX ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_DEMUX ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;case DVB_DEVICE_CA : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_CA ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_CA ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;@@ -439,7 +439,7 @@ EXPORT_SYMBOL(dvb_unregister_device);void dvb_create_media_graph (struct dvb_adapter *adap) {struct media_device *mdev = adap->mdev; -struct media_entity *entity, *tuner =NULL , *fe =NULL ; +struct media_entity *entity, *tuner =NULL , *demod =NULL ;struct media_entity *demux =NULL , *dvr =NULL , *ca =NULL ;struct media_interface *intf;@@ -451,26 +451,26 @@ void dvb_create_media_graph(struct dvb_adapter *adap)case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : tuner = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_FE : - fe = entity; +case MEDIA_ENT_T_DVB_DEMOD : + demod = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_DEMUX : +case MEDIA_ENT_T_DVB_DEMUX : demux = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_DVR : +case MEDIA_ENT_T_DVB_TSOUT : dvr = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_CA : +case MEDIA_ENT_T_DVB_CA : ca = entity;break ; } } -if (tuner && fe) -media_create_pad_link (tuner,0 , fe,0 ,0 ); +if (tuner && demod) +media_create_pad_link (tuner,0 , demod,0 ,0 ); -if (fe && demux) -media_create_pad_link (fe,1 , demux,0 ,MEDIA_LNK_FL_ENABLED ); +if (demod && demux) +media_create_pad_link (demod,1 , demux,0 ,MEDIA_LNK_FL_ENABLED );if (demux && dvr)media_create_pad_link (demux,1 , dvr,0 ,MEDIA_LNK_FL_ENABLED );include/uapi/linux/media.h +1
-0@@ -42,31 +42,71 @@ struct media_device_info {#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) +/*
include/uapi/linux/media.h struct media_device_info { · line 55
Quoted 10 lines
include/uapi/linux/media.h +10
-0+* Base numbers for entity types +* +* Please notice that the huge gap of 16 bits for each base is overkill! +* 8 bits is more than enough to avoid starving entity types for each +* subsystem. +* +* However, It is kept this way just to avoid binary breakages with the +* namespace provided on legacy versions of this header. +*/ +#define MEDIA_ENT_T_DVB_BASE 0x00000001
I would change this to 0x00000000, see follow-up comment later for why.
Quoted 11 lines
include/uapi/linux/media.h +11
-0+#define MEDIA_ENT_T_V4L2_BASE 0x00010000 +#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 + +/* +* V4L2 entities - Those are used for DMA (mmap/DMABUF) and +* read()/write() data I/O associated with the V4L2 devnodes. +*/ +#define MEDIA_ENT_T_V4L2_VIDEO (MEDIA_ENT_T_V4L2_BASE + 1) +/* +* Please notice that numbers between MEDIA_ENT_T_V4L2_BASE + 2 and +* MEDIA_ENT_T_V4L2_BASE + 4 can't be used, as those values used
include/uapi/linux/media.h struct media_device_info { · line 76
Quoted 10 lines
include/uapi/linux/media.h +10
-0+* to be declared for FB, ALSA and DVB entities. +* As those values were never actually used in practice, we're just +* adding them as backward compatibility macros and keeping the +* numberspace clean here. This way, we avoid breaking compilation, +* in the case of having some userspace application using the old +* symbols. +*/ +#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) +/* for TX radio, as RX is done via either ALSA or wire */ +#define MEDIA_ENT_T_V4L2_RADIO (MEDIA_ENT_T_V4L2_BASE + 6)
But TX is also done via either ALSA or wire. This shouldn't be needed.
include/uapi/linux/media.h struct media_device_info { · line 77
Quoted 1 line
include/uapi/linux/media.h +1
-0+#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 7)
How about MEDIA_ENT_T_DVB_IO_* and MEDIA_ENT_T_V4L2_IO_* to indicate that this entity deals with data I/O?
Or, perhaps even better, MEDIA_ENT_T_IO_DVB_ and MEDIA_ENT_T_IO_V4L2_.
Entities should do something, and just saying 'V4L2_VIDEO' doesn't really convey that meaning. It is also very easy to confuse with INTF_T_V4L_* types. BTW, we should decide whether V4L2 or V4L is used here (interfaces now use V4L, entities V4L2). Since entities already use V4L2, I think the interface defines should use V4L2 as well.
include/uapi/linux/media.h struct media_device_info { · line 89
Quoted 12 lines
include/uapi/linux/media.h +12
-0+ +/* V4L2 Sub-device entities */ +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) +/* A converter of analogue video to its digital representation. */ +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 4) +/* Tuner entity is actually both V4L2 and DVB subdev */ +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 5) + +/* DVB entities */ +#define MEDIA_ENT_T_DVB_DEMOD (MEDIA_ENT_T_DVB_BASE)
After changing DVB_BASE to 0, change this to DVB_BASE + 1, and adjust the other DVB entity types accordingly.
This keeps the base defines consistent (i.e. the lower 16 bits are always 0).
It surprised me when reading this patch, so I'm probably not the only one.
Regards,
Hans
Quoted 42 lines
include/uapi/linux/media.h +13
-18+#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 1) +#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 2) +#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 3) +#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 4) + +/* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16#define MEDIA_ENT_TYPE_MASK 0x00ff0000#define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff -#define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT) -#define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1) +#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_T_V4L2_BASE +#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_T_V4L2_SUBDEV_BASE + +#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_T_V4L2_VIDEO +#define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2)#define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) -#define MEDIA_ENT_T_DEVNODE_DVB_FE (MEDIA_ENT_T_DEVNODE + 4) -#define MEDIA_ENT_T_DEVNODE_DVB_DEMUX (MEDIA_ENT_T_DEVNODE + 5) -#define MEDIA_ENT_T_DEVNODE_DVB_DVR (MEDIA_ENT_T_DEVNODE + 6) -#define MEDIA_ENT_T_DEVNODE_DVB_CA (MEDIA_ENT_T_DEVNODE + 7) -#define MEDIA_ENT_T_DEVNODE_DVB_NET (MEDIA_ENT_T_DEVNODE + 8) +#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) -/* Legacy symbol. Use it to avoid userspace compilation breakages */ -#define MEDIA_ENT_T_DEVNODE_DVB MEDIA_ENT_T_DEVNODE_DVB_FE - -#define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT) -#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1) -#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2) -#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3) -/* A converter of analogue video to its digital representation. */ -#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV + 4) - -#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV + 5) +/* Entity types */ #define MEDIA_ENT_FL_DEFAULT (1 << 0)
Re: [PATCH v8 28/55] [media] uapi/media.h: Fix entity namespace
Em Mon, 31 Aug 2015 13:17:08 +0200
Hans Verkuil <[email protected]> escreveu:
Quoted 116 lines · Mauro Carvalho Chehab
Quoted 87 lines
Now that interfaces got created, we need to fix the entity namespace.
So, let's create a consistent new namespace and add backward compatibility macros to keep the old namespace preserved.
Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/dvb-core/dvbdev.c +13
-13@@ -230,17 +230,17 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev,switch (type) {case DVB_DEVICE_FRONTEND : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_FE ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_DEMOD ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;case DVB_DEVICE_DEMUX : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_DEMUX ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_DEMUX ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;case DVB_DEVICE_CA : - dvbdev->entity->type =MEDIA_ENT_T_DEVNODE_DVB_CA ; + dvbdev->entity->type =MEDIA_ENT_T_DVB_CA ; dvbdev->pads[0 ].flags =MEDIA_PAD_FL_SINK ; dvbdev->pads[1 ].flags =MEDIA_PAD_FL_SOURCE ;break ;@@ -439,7 +439,7 @@ EXPORT_SYMBOL(dvb_unregister_device);void dvb_create_media_graph (struct dvb_adapter *adap) {struct media_device *mdev = adap->mdev; -struct media_entity *entity, *tuner =NULL , *fe =NULL ; +struct media_entity *entity, *tuner =NULL , *demod =NULL ;struct media_entity *demux =NULL , *dvr =NULL , *ca =NULL ;struct media_interface *intf;@@ -451,26 +451,26 @@ void dvb_create_media_graph(struct dvb_adapter *adap)case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : tuner = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_FE : - fe = entity; +case MEDIA_ENT_T_DVB_DEMOD : + demod = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_DEMUX : +case MEDIA_ENT_T_DVB_DEMUX : demux = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_DVR : +case MEDIA_ENT_T_DVB_TSOUT : dvr = entity;break ; -case MEDIA_ENT_T_DEVNODE_DVB_CA : +case MEDIA_ENT_T_DVB_CA : ca = entity;break ; } } -if (tuner && fe) -media_create_pad_link (tuner,0 , fe,0 ,0 ); +if (tuner && demod) +media_create_pad_link (tuner,0 , demod,0 ,0 ); -if (fe && demux) -media_create_pad_link (fe,1 , demux,0 ,MEDIA_LNK_FL_ENABLED ); +if (demod && demux) +media_create_pad_link (demod,1 , demux,0 ,MEDIA_LNK_FL_ENABLED );if (demux && dvr)media_create_pad_link (demux,1 , dvr,0 ,MEDIA_LNK_FL_ENABLED );include/uapi/linux/media.h +1
-0@@ -42,31 +42,71 @@ struct media_device_info {#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) +/* include/uapi/linux/media.h struct media_device_info { · line 55
Quoted 10 lines
include/uapi/linux/media.h +10
-0+* Base numbers for entity types +* +* Please notice that the huge gap of 16 bits for each base is overkill! +* 8 bits is more than enough to avoid starving entity types for each +* subsystem. +* +* However, It is kept this way just to avoid binary breakages with the +* namespace provided on legacy versions of this header. +*/ +#define MEDIA_ENT_T_DVB_BASE 0x00000001I would change this to
0x00000000, see follow-up comment later for why.Quoted 15 lines
include/uapi/linux/media.h +15
-0+#define MEDIA_ENT_T_V4L2_BASE 0x00010000 +#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 + +/* +* V4L2 entities - Those are used for DMA (mmap/DMABUF) and +* read()/write() data I/O associated with the V4L2 devnodes. +*/ +#define MEDIA_ENT_T_V4L2_VIDEO (MEDIA_ENT_T_V4L2_BASE + 1) +/* +* Please notice that numbers between MEDIA_ENT_T_V4L2_BASE + 2 and +* MEDIA_ENT_T_V4L2_BASE + 4 can't be used, as those values used +* to be declared for FB, ALSA and DVB entities. +* As those values were never actually used in practice, we're just +* adding them as backward compatibility macros and keeping the +* numberspace clean here. This way, we avoid breaking compilation,
Quoted 8 lines
include/uapi/linux/media.h struct media_device_info { · line 76
Quoted 6 lines
include/uapi/linux/media.h +6
-0+* in the case of having some userspace application using the old +* symbols. +*/ +#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) +/* for TX radio, as RX is done via either ALSA or wire */ +#define MEDIA_ENT_T_V4L2_RADIO (MEDIA_ENT_T_V4L2_BASE + 6)But TX is also done via either ALSA or wire. This shouldn't be needed.
OK. I'll drop it.
Quoted 7 lines
include/uapi/linux/media.h struct media_device_info { · line 77
Quoted 2 lines
include/uapi/linux/media.h +1
-0+#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 7)How about MEDIA_ENT_T_DVB_IO_* and MEDIA_ENT_T_V4L2_IO_* to indicate that this entity deals with data I/O?
Or, perhaps even better,
MEDIA_ENT_T_IO_DVB_andMEDIA_ENT_T_IO_V4L2_.
Works for me.
Quoted 6 lines
Entities should do something, and just saying '
V4L2_VIDEO' doesn't really convey that meaning. It is also very easy to confuse with INTF_T_V4L_* types. BTW, we should decide whether V4L2 or V4L is used here (interfaces now use V4L, entities V4L2). Since entities already use V4L2, I think the interface defines should use V4L2 as well.
Yes, agreed. We actually need to discuss a little more about namespacing and do some additional renaming stuff.
For example, calling a tuner entity as MEDIA_ENT_T_V4L2_SUBDEV_TUNER is wrong, because the tuner can be used only at the DVB side.
So, both V4L2 and SUBDEV prefixes there are wrong. Yet, this should be under the V4L2_SUBDEV range to avoid breaking userspace.
Quoted 17 lines
include/uapi/linux/media.h struct media_device_info { · line 89
Quoted 13 lines
include/uapi/linux/media.h +12
-0+ +/* V4L2 Sub-device entities */ +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) +/* A converter of analogue video to its digital representation. */ +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 4) +/* Tuner entity is actually both V4L2 and DVB subdev */ +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 5) + +/* DVB entities */ +#define MEDIA_ENT_T_DVB_DEMOD (MEDIA_ENT_T_DVB_BASE)After changing
DVB_BASEto 0, change this toDVB_BASE+ 1, and adjust the other DVB entity types accordingly.
Quoted 3 lines
This keeps the base defines consistent (i.e. the lower 16 bits are always 0).
It surprised me when reading this patch, so I'm probably not the only one.
This is another thing for discussion: keeping the MEDIA_ENT_T_foo_BASE unused opens space for API abuse.
There are several entities at OMAP3 driver, for example, that keeps entity->type undefined. So, they got whatever is the default at v4l2-device.c (before this series: MEDIA_ENT_T_V4L2_SUBDEV, after
that: MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN):
$ media-ctl --print-t|grep -B1 Unknown
- entity 1: OMAP3 ISP CCP2 (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
--
- entity 3: OMAP3 ISP CSI2a (2 pads, 2 links)
type V4L2 subdev subtype Unknown flags 0
--
- entity 5: OMAP3 ISP CCDC (3 pads, 8 links)
type V4L2 subdev subtype Unknown flags 0
--
- entity 7: OMAP3 ISP preview (2 pads, 4 links)
type V4L2 subdev subtype Unknown flags 0
--
- entity 10: OMAP3 ISP resizer (2 pads, 4 links)
type V4L2 subdev subtype Unknown flags 0
--
- entity 13: OMAP3 ISP AEWB (1 pad, 1 link)
type V4L2 subdev subtype Unknown flags 0
--
- entity 14: OMAP3 ISP AF (1 pad, 1 link)
type V4L2 subdev subtype Unknown flags 0
--
- entity 15: OMAP3 ISP histogram (1 pad, 1 link)
type V4L2 subdev subtype Unknown flags 0I guess all the above entities are processing units, so they should have, instead, some type like:
MEDIA_ENT_T_V4L2_SUBDEV_PROCESSING
Or, even some of the above would actually deserves to have an specific type, like:
MEDIA_ENT_T_V4L2_SUBDEV_HISTOGRAM MEDIA_ENT_T_V4L2_SUBDEV_RESIZER ...
Let's try to find some time to discuss the entities namespace on IRC during this week.
Regards,
Mauro
PATCH v8 29/55 replace all occurrences of MEDIA_ENT_T_DEVNODE_V4L
In reply to Mauro Carvalho ChehabNow that interfaces and entities are distinct, it makes no sense of keeping something named as MEDIA_ENT_T_DEVNODE.
This change was done with this script:
for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done
Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +1 -1
@@ -183,7 +183,7 @@ <entry>Unknown device node</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry> + <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry> <entry>V4L video, radio or vbi device node</entry> </row> <row>
drivers/media/platform/xilinx/xilinx-dma.c +1 -1
@@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,while ((entity =media_entity_graph_walk_next (&graph))) {struct xvip_dma *dma; -if (entity->type !=MEDIA_ENT_T_DEVNODE_V4L ) +if (entity->type !=MEDIA_ENT_T_V4L2_VIDEO )continue ; dma =to_xvip_dma (media_entity_to_video_device (entity));
drivers/media/v4l2-core/v4l2-dev.c +1 -1
@@ -912,7 +912,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr,/* Part 5: Register the entity. */ if (vdev->v4l2_dev->mdev && vdev->vfl_type !=VFL_TYPE_SUBDEV ) { - vdev->entity.type =MEDIA_ENT_T_DEVNODE_V4L ; + vdev->entity.type =MEDIA_ENT_T_V4L2_VIDEO ; vdev->entity.name = vdev->name; vdev->entity.info.dev.major =VIDEO_MAJOR ; vdev->entity.info.dev.minor = vdev->minor;
drivers/media/v4l2-core/v4l2-subdev.c +1 -1
@@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,return v4l2_subdev_call (sd, pad, get_fmt,NULL , fmt); } -WARN (pad->entity->type !=MEDIA_ENT_T_DEVNODE_V4L , +WARN (pad->entity->type !=MEDIA_ENT_T_V4L2_VIDEO ,"Driver bug! Wrong media entity type 0x%08x, entity %s\n" , pad->entity->type, pad->entity->name);
Signature · 1 line
2.4.3
PATCH v8 29/55 replace all occurrences of MEDIA_ENT_T_DEVNODE_V4L
Quoted 8 lines · Mauro Carvalho Chehab
Now that interfaces and entities are distinct, it makes no sense of keeping something named as
MEDIA_ENT_T_DEVNODE.This change was done with this script:
for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; doneSigned-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 54 lines
Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +1
-1@@ -183,7 +183,7 @@ <entry>Unknown device node</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry> + <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry> <entry>V4L video, radio or vbi device node</entry> </row> <row>drivers/media/platform/xilinx/xilinx-dma.c +1
-1@@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,while ((entity =media_entity_graph_walk_next (&graph))) {struct xvip_dma *dma; -if (entity->type !=MEDIA_ENT_T_DEVNODE_V4L ) +if (entity->type !=MEDIA_ENT_T_V4L2_VIDEO )continue ; dma =to_xvip_dma (media_entity_to_video_device (entity));drivers/media/v4l2-core/v4l2-dev.c +1
-1@@ -912,7 +912,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr,/* Part 5: Register the entity. */ if (vdev->v4l2_dev->mdev && vdev->vfl_type !=VFL_TYPE_SUBDEV ) { - vdev->entity.type =MEDIA_ENT_T_DEVNODE_V4L ; + vdev->entity.type =MEDIA_ENT_T_V4L2_VIDEO ; vdev->entity.name = vdev->name; vdev->entity.info.dev.major =VIDEO_MAJOR ; vdev->entity.info.dev.minor = vdev->minor;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,return v4l2_subdev_call (sd, pad, get_fmt,NULL , fmt); } -WARN (pad->entity->type !=MEDIA_ENT_T_DEVNODE_V4L , +WARN (pad->entity->type !=MEDIA_ENT_T_V4L2_VIDEO ,"Driver bug! Wrong media entity type 0x%08x, entity %s\n" , pad->entity->type, pad->entity->name);
PATCH v8 30/55 replace all occurrences of MEDIA_ENT_T_DEVNODE_DVB
In reply to Mauro Carvalho ChehabNow that interfaces and entities are distinct, it makes no sense of keeping something named as MEDIA_ENT_T_DEVNODE_DVB_foo.
Made via this script:
for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_DVB_,MEDIA_ENT_T_DVB_, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_DVR,MEDIA_ENT_T_DVB_TSOUT, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_FE,MEDIA_ENT_T_DVB_DEMOD, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_NET,MEDIA_ENT_T_DVB_DEMOD_NET_DECAP, <$i >a && mv a $i; done
Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +5 -5
@@ -195,23 +195,23 @@ <entry>ALSA card</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_FE</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry> <entry>DVB frontend devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DEMUX</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry> <entry>DVB demux devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DVR</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry> <entry>DVB DVR devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_CA</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry> <entry>DVB CAM devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_NET</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry> <entry>DVB network devnode</entry> </row> <row>
Signature · 1 line
2.4.3
Re: [PATCH v8 30/55] [media] replace all occurrences of MEDIA_ENT_T_DEVNODE_DVB
Quoted 10 lines · Mauro Carvalho Chehab
Now that interfaces and entities are distinct, it makes no sense of keeping something named as
MEDIA_ENT_T_DEVNODE_DVB_foo.Made via this script:
for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_DVB_,MEDIA_ENT_T_DVB_, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_DVR,MEDIA_ENT_T_DVB_TSOUT, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_FE,MEDIA_ENT_T_DVB_DEMOD, <$i >a && mv a $i; done for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DVB_NET,MEDIA_ENT_T_DVB_DEMOD_NET_DECAP, <$i >a && mv a $i; doneSigned-off-by Mauro Carvalho Chehab <[email protected]>
Quoted 35 lines
Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +5
-5@@ -195,23 +195,23 @@ <entry>ALSA card</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_FE</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry> <entry>DVB frontend devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DEMUX</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry> <entry>DVB demux devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_DVR</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry> <entry>DVB DVR devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_CA</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry> <entry>DVB CAM devnode</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_DVB_NET</constant></entry> + <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry> <entry>DVB network devnode</entry> </row> <row>
PATCH v8 31/55 media: add macros to check if subdev or V4L2 DMA
In reply to Mauro Carvalho ChehabAs we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA).
include/media/media-entity.h +33 -0
@@ -220,6 +220,39 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)return id; } +static inline bool is_media_entity_v4l2_io (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_VIDEO : +case MEDIA_ENT_T_V4L2_VBI : +case MEDIA_ENT_T_V4L2_SWRADIO : +return true; +default : +return false; + } +} + +static inline bool is_media_entity_v4l2_subdev (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR : +case MEDIA_ENT_T_V4L2_SUBDEV_FLASH : +case MEDIA_ENT_T_V4L2_SUBDEV_LENS : +case MEDIA_ENT_T_V4L2_SUBDEV_DECODER : +case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : +return true; + +default : +return false; + } +} +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16#define MEDIA_ENTITY_ENUM_MAX_ID 64
Signature · 1 line
2.4.3
Re: [PATCH v8 31/55] [media] media: add macros to check if subdev or V4L2 DMA
Quoted 4 lines · Mauro Carvalho Chehab
As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA).
This needs more discussion. The plan (as I understand it) is to have properties that describe the entity's functionalities.
The existing entity subtypes will exist only as backwards compat types, but in the future properties should be used to describe the functionalities.
This raises the question if we shouldn't use MEDIA_ENT_T_V4L2_SUBDEV to tell userspace that this is a subdev-controlled entity, and let userspace look at the properties to figure out what it is exactly?
It could be that this is a transitional patch, and this will be fixed later. If so, this should be mentioned in the commit message.
Regards,
Hans
Quoted 48 lines
Signed-off-by Mauro Carvalho Chehab <[email protected]>include/media/media-entity.h +33
-0@@ -220,6 +220,39 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)return id; } +static inline bool is_media_entity_v4l2_io (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_VIDEO : +case MEDIA_ENT_T_V4L2_VBI : +case MEDIA_ENT_T_V4L2_SWRADIO : +return true; +default : +return false; + } +} + +static inline bool is_media_entity_v4l2_subdev (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR : +case MEDIA_ENT_T_V4L2_SUBDEV_FLASH : +case MEDIA_ENT_T_V4L2_SUBDEV_LENS : +case MEDIA_ENT_T_V4L2_SUBDEV_DECODER : +case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : +return true; + +default : +return false; + } +} +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16#define MEDIA_ENTITY_ENUM_MAX_ID 64
Re: [PATCH v8 31/55] [media] media: add macros to check if subdev or V4L2 DMA
Quoted 12 lines · Hans Verkuil
Quoted 4 lines · Mauro Carvalho Chehab
As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA).
This needs more discussion. The plan (as I understand it) is to have properties that describe the entity's functionalities.
The existing entity subtypes will exist only as backwards compat types, but in the future properties should be used to describe the functionalities.
Quoted 6 lines
This raises the question if we shouldn't use
MEDIA_ENT_T_V4L2_SUBDEVto tell userspace that this is a subdev-controlled entity, and let userspace look at the properties to figure out what it is exactly?It could be that this is a transitional patch, and this will be fixed later. If so, this should be mentioned in the commit message.
FYI, I'm skipping patches that change the MEDIA_ENT_T_V4L2_SUBDEV usage until I understand the long-term plan for this define as discussed above.
Regards,
Hans
Re: [PATCH v8 31/55] [media] media: add macros to check if subdev or V4L2 DMA
In reply to Hans VerkuilEm Mon, 31 Aug 2015 13:31:32 +0200
Hans Verkuil <[email protected]> escreveu:
Quoted 12 lines · Mauro Carvalho Chehab
Quoted 4 lines
As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA).
This needs more discussion. The plan (as I understand it) is to have properties that describe the entity's functionalities.
The existing entity subtypes will exist only as backwards compat types, but in the future properties should be used to describe the functionalities.
Quoted 6 lines
This raises the question if we shouldn't use
MEDIA_ENT_T_V4L2_SUBDEVto tell userspace that this is a subdev-controlled entity, and let userspace look at the properties to figure out what it is exactly?It could be that this is a transitional patch, and this will be fixed later. If so, this should be mentioned in the commit message.
There are several different issues here:
1) drivers should not rely on type/subtype at MEDIA_ENT_T_*, as we need to get rid of it, as this got deprecated;
2) Keep backward compatibility.
3) the addition of properties;
The next patch on this series addresses (1) and (2), and this change is needed for them.
We can't tell if this is a transitional patch or not, as we don't have yet any idea about how (3) will be added. Maybe it will preserve entity->type. Maybe it will convert it into an array. Maybe it would do something different.
In any case, whatever the property patches will be doing, after this patch, it will need to touch only at the implementation of the two macros, not needing to touch at the drivers again.
What I can do is to tell at the description that this patch is in preparation for the removal of media type/subtype concept that will happen on the next patches, but this is what's described there already at:
"As we'll be removing entity subtypes from the Kernel,"
Perhaps I should let it clearer there.
Regards,
Mauro
Quoted 54 lines
Regards,
Hans
Quoted 48 lines
Signed-off-by Mauro Carvalho Chehab <[email protected]>include/media/media-entity.h +33
-0@@ -220,6 +220,39 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)return id; } +static inline bool is_media_entity_v4l2_io (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_VIDEO : +case MEDIA_ENT_T_V4L2_VBI : +case MEDIA_ENT_T_V4L2_SWRADIO : +return true; +default : +return false; + } +} + +static inline bool is_media_entity_v4l2_subdev (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR : +case MEDIA_ENT_T_V4L2_SUBDEV_FLASH : +case MEDIA_ENT_T_V4L2_SUBDEV_LENS : +case MEDIA_ENT_T_V4L2_SUBDEV_DECODER : +case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : +return true; + +default : +return false; + } +} +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16#define MEDIA_ENTITY_ENUM_MAX_ID 64
Re: [PATCH v8 31/55] [media] media: add macros to check if subdev or V4L2 DMA
Quoted 43 lines · Mauro Carvalho Chehab
Em Mon, 31 Aug 2015 13:31:32 +0200
Hans Verkuil <[email protected]> escreveu:Quoted 12 lines · Mauro Carvalho Chehab
Quoted 4 lines
As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA).
This needs more discussion. The plan (as I understand it) is to have properties that describe the entity's functionalities.
The existing entity subtypes will exist only as backwards compat types, but in the future properties should be used to describe the functionalities.
Quoted 6 lines
This raises the question if we shouldn't use
MEDIA_ENT_T_V4L2_SUBDEVto tell userspace that this is a subdev-controlled entity, and let userspace look at the properties to figure out what it is exactly?It could be that this is a transitional patch, and this will be fixed later. If so, this should be mentioned in the commit message.
There are several different issues here:
1) drivers should not rely on type/subtype at MEDIA_ENT_T_*, as we need to get rid of it, as this got deprecated;
2) Keep backward compatibility.
3) the addition of properties;
The next patch on this series addresses (1) and (2), and this change is needed for them.
We can't tell if this is a transitional patch or not, as we don't have yet any idea about how (3) will be added. Maybe it will preserve
entity->type. Maybe it will convert it into an array. Maybe it would do something different.In any case, whatever the property patches will be doing, after this patch, it will need to touch only at the implementation of the two macros, not needing to touch at the drivers again.
Quoted 7 lines
What I can do is to tell at the description that this patch is in preparation for the removal of media type/subtype concept that will happen on the next patches, but this is what's described there already at:
"As we'll be removing entity subtypes from the Kernel,"Perhaps I should let it clearer there.
Just mention this in the cover letter as part of the todo list.
As long as I know that this might change later depending on how properties are going to affect this, then that's OK and I can keep it in mind when I review.
Regards,
Hans
Quoted 58 lines
Regards,
MauroQuoted 54 lines
Regards,
Hans
Quoted 48 lines
Signed-off-by Mauro Carvalho Chehab <[email protected]>include/media/media-entity.h +33
-0@@ -220,6 +220,39 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)return id; } +static inline bool is_media_entity_v4l2_io (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_VIDEO : +case MEDIA_ENT_T_V4L2_VBI : +case MEDIA_ENT_T_V4L2_SWRADIO : +return true; +default : +return false; + } +} + +static inline bool is_media_entity_v4l2_subdev (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR : +case MEDIA_ENT_T_V4L2_SUBDEV_FLASH : +case MEDIA_ENT_T_V4L2_SUBDEV_LENS : +case MEDIA_ENT_T_V4L2_SUBDEV_DECODER : +case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : +return true; + +default : +return false; + } +} +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16#define MEDIA_ENTITY_ENUM_MAX_ID 64
PATCH v8 32/55 media: use macros to check for V4L2 subdev entities
In reply to Mauro Carvalho ChehabInstead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just AV_DMA or V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.
Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the AV_DMA stuff.
drivers/media/platform/exynos4-is/common.c +1 -2
@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);
drivers/media/platform/exynos4-is/fimc-capture.c +2 -3
@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */
@@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))
drivers/media/platform/exynos4-is/fimc-isp-video.c +1 -2
@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);
drivers/media/platform/exynos4-is/fimc-lite.c +4 -6
@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);
@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))
@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }
@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;
@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;
drivers/media/platform/exynos4-is/media-dev.c +3 -4
@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);
@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);
@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);
drivers/media/platform/omap3isp/isp.c +6 -8
@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }
@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {
@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)
@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;
@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;
@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;
drivers/media/platform/omap3isp/ispvideo.c +3 -4
@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)
@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));
@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);
drivers/media/platform/s3c-camif/camif-capture.c +1 -1
@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;
drivers/media/platform/vsp1/vsp1_video.c +4 -5
@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)
@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));
@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }
@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));
drivers/media/platform/xilinx/xilinx-dma.c +2 -4
@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)
@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;
drivers/media/v4l2-core/v4l2-subdev.c +1 -1
@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);
drivers/staging/media/davinci_vpfe/vpfe_video.c +3 -3
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );
@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );
drivers/staging/media/omap4iss/iss.c +6 -8
@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }
@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {
@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)
@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;
@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;
@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;
drivers/staging/media/omap4iss/iss_video.c +2 -3
@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)
@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; far_end =to_iss_video (media_entity_to_video_device (entity));
Signature · 1 line
2.4.3
PATCH v8 32/55 media: use macros to check for V4L2 subdev entities
Hi Mauro,
Quoted 436 lines · Mauro Carvalho Chehab
Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just
AV_DMAor V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the
AV_DMAstuff.Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/exynos4-is/common.c +1
-2@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-capture.c +2
-3@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */ @@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))drivers/media/platform/exynos4-is/fimc-isp-video.c +1
-2@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-lite.c +4
-6@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;drivers/media/platform/exynos4-is/media-dev.c +3
-4@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);drivers/media/platform/omap3isp/isp.c +6
-8@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/platform/omap3isp/ispvideo.c +3
-4@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);drivers/media/platform/s3c-camif/camif-capture.c +1
-1@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;drivers/media/platform/vsp1/vsp1_video.c +4
-5@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));drivers/media/platform/xilinx/xilinx-dma.c +2
-4@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);drivers/staging/media/davinci_vpfe/vpfe_video.c +3
-3@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );drivers/staging/media/omap4iss/iss.c +6
-8@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/staging/media/omap4iss/iss_video.c +1
-2@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)
drivers/staging/media/omap4iss/iss_video.c iss_video_far_end(struct iss_video *video) · line 222
Quoted 8 lines
drivers/staging/media/omap4iss/iss_video.c +1
-1@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; far_end =to_iss_video (media_entity_to_video_device (entity));
I finally got around to test these patches eventually, and after some debugging found this one. I think it's a good idea to have macros to determine whether an entity exposes a V4L2 sub-device interface but it should be more robust than is_media_entity_v4l2_subdev() right now is.
Incorrect result can have consequences from a pipeline start failure (due to a failure in link validation) to memory corruption as struct media_entity pointer is assumed to be a pointer to a field of another struct.
How about assigning that in V4L2 sub-device / video device registration, for example?
Signature · 4 lines
Regards, Sakari Ailus e-mail: sakari.ailus at iki.fi XMPP: sailus at retiisi.org.uk
PATCH v8 32/55 media: use macros to check for V4L2 subdev entities
Em Mon, 12 Oct 2015 00:07:52 +0300
Sakari Ailus <[email protected]> escreveu:
Quoted 446 lines
Hi Mauro,
Quoted 443 lines · Mauro Carvalho Chehab
Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just
AV_DMAor V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the
AV_DMAstuff.Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/exynos4-is/common.c +1
-2@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-capture.c +2
-3@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */ @@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))drivers/media/platform/exynos4-is/fimc-isp-video.c +1
-2@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-lite.c +4
-6@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;drivers/media/platform/exynos4-is/media-dev.c +3
-4@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);drivers/media/platform/omap3isp/isp.c +6
-8@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/platform/omap3isp/ispvideo.c +3
-4@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);drivers/media/platform/s3c-camif/camif-capture.c +1
-1@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;drivers/media/platform/vsp1/vsp1_video.c +4
-5@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));drivers/media/platform/xilinx/xilinx-dma.c +2
-4@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);drivers/staging/media/davinci_vpfe/vpfe_video.c +3
-3@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );drivers/staging/media/omap4iss/iss.c +6
-8@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/staging/media/omap4iss/iss_video.c +2
-3@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ;
Quoted 6 lines
drivers/staging/media/omap4iss/iss_video.c iss_video_far_end(struct iss_video *video) · line 222
Quoted 1 line
drivers/staging/media/omap4iss/iss_video.c +0
-0far_end =to_iss_video (media_entity_to_video_device (entity));I finally got around to test these patches eventually, and after some debugging found this one. I think it's a good idea to have macros to determine whether an entity exposes a V4L2 sub-device interface but it should be more robust than
is_media_entity_v4l2_subdev()right now is.
Hmm... Not sure what you're meaning... the V4L2 sub-device interface is actually a separate graph object (interfaces). Those macros work at the entities, not at the interface objects.
Quoted 3 lines
Incorrect result can have consequences from a pipeline start failure (due to a failure in link validation) to memory corruption as struct
media_entitypointer is assumed to be a pointer to a field of another struct.
Yes, an incorrect result would cause pipeline failures.
Quoted 2 lines
How about assigning that in V4L2 sub-device / video device registration, for example?
What do you mean? Could you give an example to make it clearer?
Regards,
Mauro
PATCH v8 32/55 media: use macros to check for V4L2 subdev entities
Hi Mauro,
Quoted 456 lines · Mauro Carvalho Chehab
Em Mon, 12 Oct 2015 00:07:52 +0300
Sakari Ailus <[email protected]> escreveu:Quoted 446 lines
Hi Mauro,
Quoted 443 lines · Mauro Carvalho Chehab
Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just
AV_DMAor V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the
AV_DMAstuff.Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/exynos4-is/common.c +1
-2@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-capture.c +2
-3@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */ @@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))drivers/media/platform/exynos4-is/fimc-isp-video.c +1
-2@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-lite.c +4
-6@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;drivers/media/platform/exynos4-is/media-dev.c +3
-4@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);drivers/media/platform/omap3isp/isp.c +6
-8@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/platform/omap3isp/ispvideo.c +3
-4@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);drivers/media/platform/s3c-camif/camif-capture.c +1
-1@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;drivers/media/platform/vsp1/vsp1_video.c +4
-5@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));drivers/media/platform/xilinx/xilinx-dma.c +2
-4@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);drivers/staging/media/davinci_vpfe/vpfe_video.c +3
-3@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );drivers/staging/media/omap4iss/iss.c +6
-8@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/staging/media/omap4iss/iss_video.c +2
-3@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ;Quoted 6 lines
drivers/staging/media/omap4iss/iss_video.c iss_video_far_end(struct iss_video *video) · line 222
Quoted 1 line
drivers/staging/media/omap4iss/iss_video.c +0
-0far_end =to_iss_video (media_entity_to_video_device (entity));I finally got around to test these patches eventually, and after some debugging found this one. I think it's a good idea to have macros to determine whether an entity exposes a V4L2 sub-device interface but it should be more robust than
is_media_entity_v4l2_subdev()right now is.
Quoted 3 lines
Hmm... Not sure what you're meaning... the V4L2 sub-device interface is actually a separate graph object (interfaces). Those macros work at the entities, not at the interface objects.
is_media_entity_v4l2_subdev() will produce wrong results for a large part of V4L2 sub-devices with these patches applied.
I checked again the original implementation, and it seems to be based only on the type as well, albeit that's a range, not a set of different functions.
I suppose this will change at some point in the future: the interface indeed should not be determined by the function of the entity. At least it needs to be fixed now until the rework. I'll submit a patch for that.
Signature · 4 lines
Regards, Sakari Ailus e-mail: sakari.ailus at iki.fi XMPP: sailus at retiisi.org.uk
PATCH v8 32/55 media: use macros to check for V4L2 subdev entities
Em Mon, 12 Oct 2015 18:35:05 +0300
Sakari Ailus <[email protected]> escreveu:
Quoted 463 lines
Hi Mauro,
Quoted 456 lines · Mauro Carvalho Chehab
Em Mon, 12 Oct 2015 00:07:52 +0300
Sakari Ailus <[email protected]> escreveu:Quoted 446 lines
Hi Mauro,
Quoted 443 lines · Mauro Carvalho Chehab
Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just
AV_DMAor V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the
AV_DMAstuff.Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/exynos4-is/common.c +1
-2@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-capture.c +2
-3@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */ @@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))drivers/media/platform/exynos4-is/fimc-isp-video.c +1
-2@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-lite.c +4
-6@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;drivers/media/platform/exynos4-is/media-dev.c +3
-4@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);drivers/media/platform/omap3isp/isp.c +6
-8@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/platform/omap3isp/ispvideo.c +3
-4@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);drivers/media/platform/s3c-camif/camif-capture.c +1
-1@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;drivers/media/platform/vsp1/vsp1_video.c +4
-5@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));drivers/media/platform/xilinx/xilinx-dma.c +2
-4@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);drivers/staging/media/davinci_vpfe/vpfe_video.c +3
-3@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );drivers/staging/media/omap4iss/iss.c +6
-8@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/staging/media/omap4iss/iss_video.c +2
-3@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ;Quoted 6 lines
drivers/staging/media/omap4iss/iss_video.c iss_video_far_end(struct iss_video *video) · line 222
Quoted 1 line
drivers/staging/media/omap4iss/iss_video.c +0
-0far_end =to_iss_video (media_entity_to_video_device (entity));I finally got around to test these patches eventually, and after some debugging found this one. I think it's a good idea to have macros to determine whether an entity exposes a V4L2 sub-device interface but it should be more robust than
is_media_entity_v4l2_subdev()right now is.Quoted 3 lines
Hmm... Not sure what you're meaning... the V4L2 sub-device interface is actually a separate graph object (interfaces). Those macros work at the entities, not at the interface objects.
Quoted 6 lines
is_media_entity_v4l2_subdev()will produce wrong results for a large part of V4L2 sub-devices with these patches applied.I checked again the original implementation, and it seems to be based only on the type as well, albeit that's a range, not a set of different functions.
Yes. As we're getting rid of ranges for subdevs, we need to change the implementation. Your patch does the job by recognizing the "unknown" subdevs.
Quoted 4 lines
I suppose this will change at some point in the future: the interface indeed should not be determined by the function of the entity. At least it needs to be fixed now until the rework. I'll submit a patch for that.
Thanks!
Mauro
Re: [PATCH v8 32/55] [media] media: use macros to check for V4L2 subdev entities
In reply to Sakari AilusEm Mon, 12 Oct 2015 18:35:05 +0300
Sakari Ailus <[email protected]> escreveu:
Quoted 466 lines
Hi Mauro,
Quoted 456 lines · Mauro Carvalho Chehab
Em Mon, 12 Oct 2015 00:07:52 +0300
Sakari Ailus <[email protected]> escreveu:Quoted 446 lines
Hi Mauro,
Quoted 443 lines · Mauro Carvalho Chehab
Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just
AV_DMAor V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the
AV_DMAstuff.Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/exynos4-is/common.c +1
-2@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-capture.c +2
-3@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */ @@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))drivers/media/platform/exynos4-is/fimc-isp-video.c +1
-2@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-lite.c +4
-6@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;drivers/media/platform/exynos4-is/media-dev.c +3
-4@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);drivers/media/platform/omap3isp/isp.c +6
-8@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/platform/omap3isp/ispvideo.c +3
-4@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);drivers/media/platform/s3c-camif/camif-capture.c +1
-1@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;drivers/media/platform/vsp1/vsp1_video.c +4
-5@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));drivers/media/platform/xilinx/xilinx-dma.c +2
-4@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);drivers/staging/media/davinci_vpfe/vpfe_video.c +3
-3@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );drivers/staging/media/omap4iss/iss.c +6
-8@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/staging/media/omap4iss/iss_video.c +2
-3@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ;Quoted 6 lines
drivers/staging/media/omap4iss/iss_video.c iss_video_far_end(struct iss_video *video) · line 222
Quoted 1 line
drivers/staging/media/omap4iss/iss_video.c +0
-0far_end =to_iss_video (media_entity_to_video_device (entity));I finally got around to test these patches eventually, and after some debugging found this one. I think it's a good idea to have macros to determine whether an entity exposes a V4L2 sub-device interface but it should be more robust than
is_media_entity_v4l2_subdev()right now is.Quoted 3 lines
Hmm... Not sure what you're meaning... the V4L2 sub-device interface is actually a separate graph object (interfaces). Those macros work at the entities, not at the interface objects.
is_media_entity_v4l2_subdev()will produce wrong results for a large part of V4L2 sub-devices with these patches applied.
Quoted 7 lines
I checked again the original implementation, and it seems to be based only on the type as well, albeit that's a range, not a set of different functions.
I suppose this will change at some point in the future: the interface indeed should not be determined by the function of the entity. At least it needs to be fixed now until the rework. I'll submit a patch for that.
I'm folding this small fixup to this patch. It should fix the issues with the unknown subdev types.
This is fixed on some latter patches in this series, adding MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, but let's avoid breaking bisectability here.
include/media/media-entity.h +1 -0
@@ -241,6 +241,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity)return false;switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_BASE :case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR :case MEDIA_ENT_T_V4L2_SUBDEV_FLASH :case MEDIA_ENT_T_V4L2_SUBDEV_LENS :
Quoted 1 line
Mauro Carvalho Chehab
Acked-by Hans VerkuilRe: [PATCH v8 32/55] [media] media: use macros to check for V4L2 subdev entities
Em Tue, 8 Dec 2015 13:57:55 -0200
Mauro Carvalho Chehab <[email protected]> escreveu:
Quoted 489 lines
Em Mon, 12 Oct 2015 18:35:05 +0300
Sakari Ailus <[email protected]> escreveu:Quoted 466 lines
Hi Mauro,
Quoted 456 lines · Mauro Carvalho Chehab
Em Mon, 12 Oct 2015 00:07:52 +0300
Sakari Ailus <[email protected]> escreveu:Quoted 446 lines
Hi Mauro,
Quoted 443 lines · Mauro Carvalho Chehab
Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just
AV_DMAor V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the
AV_DMAstuff.Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/exynos4-is/common.c +1
-2@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-capture.c +2
-3@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */ @@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))drivers/media/platform/exynos4-is/fimc-isp-video.c +1
-2@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-lite.c +4
-6@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;drivers/media/platform/exynos4-is/media-dev.c +3
-4@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);drivers/media/platform/omap3isp/isp.c +6
-8@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/platform/omap3isp/ispvideo.c +3
-4@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);drivers/media/platform/s3c-camif/camif-capture.c +1
-1@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;drivers/media/platform/vsp1/vsp1_video.c +4
-5@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));drivers/media/platform/xilinx/xilinx-dma.c +2
-4@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);drivers/staging/media/davinci_vpfe/vpfe_video.c +3
-3@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );drivers/staging/media/omap4iss/iss.c +6
-8@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/staging/media/omap4iss/iss_video.c +2
-3@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ;Quoted 6 lines
drivers/staging/media/omap4iss/iss_video.c iss_video_far_end(struct iss_video *video) · line 222
Quoted 1 line
drivers/staging/media/omap4iss/iss_video.c +0
-0far_end =to_iss_video (media_entity_to_video_device (entity));I finally got around to test these patches eventually, and after some debugging found this one. I think it's a good idea to have macros to determine whether an entity exposes a V4L2 sub-device interface but it should be more robust than
is_media_entity_v4l2_subdev()right now is.Quoted 3 lines
Hmm... Not sure what you're meaning... the V4L2 sub-device interface is actually a separate graph object (interfaces). Those macros work at the entities, not at the interface objects.
is_media_entity_v4l2_subdev()will produce wrong results for a large part of V4L2 sub-devices with these patches applied.Quoted 7 lines
I checked again the original implementation, and it seems to be based only on the type as well, albeit that's a range, not a set of different functions.
I suppose this will change at some point in the future: the interface indeed should not be determined by the function of the entity. At least it needs to be fixed now until the rework. I'll submit a patch for that.
I'm folding this small fixup to this patch. It should fix the issues with the unknown subdev types.
This is fixed on some latter patches in this series, adding
MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, but let's avoid breaking bisectability here.include/media/media-entity.h +0
-0
include/media/media-entity.h static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) · line 247
Quoted 7 lines
include/media/media-entity.h +1
-0@@ -241,6 +241,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity)return false;switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_BASE :case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR :case MEDIA_ENT_T_V4L2_SUBDEV_FLASH :case MEDIA_ENT_T_V4L2_SUBDEV_LENS :
Actually, due to some comments for the patch:
s5c73m3: fix subdev type
And a few others, I'm actually adding MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN definition on this patchset.
The new version of this patch is:
Quoted 1 line
From
a1eb0e612166edf3bb07d9c699ad3264069d36d5Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <[email protected]>
Date: Fri, 21 Aug 2015 12:17:40 -0300
Subject: [PATCH] [media] media: add macros to check if subdev or V4L2 DMA
As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA).
Drivers that create entities that don't belong to any defined subdev category should use MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN.
include/media/media-entity.h +34 -0
@@ -220,6 +220,40 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)return id; } +static inline bool is_media_entity_v4l2_io (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_VIDEO : +case MEDIA_ENT_T_V4L2_VBI : +case MEDIA_ENT_T_V4L2_SWRADIO : +return true; +default : +return false; + } +} + +static inline bool is_media_entity_v4l2_subdev (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_BASE : +case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR : +case MEDIA_ENT_T_V4L2_SUBDEV_FLASH : +case MEDIA_ENT_T_V4L2_SUBDEV_LENS : +case MEDIA_ENT_T_V4L2_SUBDEV_DECODER : +case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : +return true; + +default : +return false; + } +} +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16#define MEDIA_ENTITY_ENUM_MAX_ID 64
include/uapi/linux/media.h +3 -0
@@ -75,6 +75,9 @@ struct media_device_info {#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6)/* V4L2 Sub-device entities */ + +#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1)#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2)#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3)
Mauro Carvalho Chehab
Acked-by Hans VerkuilRe: [PATCH v8 32/55] [media] media: use macros to check for V4L2 subdev entities
Em Tue, 8 Dec 2015 15:05:51 -0200
Mauro Carvalho Chehab <[email protected]> escreveu:
Quoted 503 lines
Em Tue, 8 Dec 2015 13:57:55 -0200
Mauro Carvalho Chehab <[email protected]> escreveu:Quoted 489 lines
Em Mon, 12 Oct 2015 18:35:05 +0300
Sakari Ailus <[email protected]> escreveu:Quoted 466 lines
Hi Mauro,
Quoted 456 lines · Mauro Carvalho Chehab
Em Mon, 12 Oct 2015 00:07:52 +0300
Sakari Ailus <[email protected]> escreveu:Quoted 446 lines
Hi Mauro,
Quoted 443 lines · Mauro Carvalho Chehab
Instead of relying on media subtype, use the new macros to detect if an entity is a subdev or an A/V DMA entity.
Please note that most drivers assume that there's just
AV_DMAor V4L2 subdevs. This is not true anymore, as we've added MC support for DVB, and there are plans to add support for ALSA and FB/DRM too.Ok, on the current pipelines supported by those drivers, just V4L stuff are there, but, assuming that some day a pipeline that also works with other subsystems will ever added, it is better to add explicit checks for the
AV_DMAstuff.Signed-off-by Mauro Carvalho Chehab <[email protected]>drivers/media/platform/exynos4-is/common.c +1
-2@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)while (pad->flags &MEDIA_PAD_FL_SINK ) {/* source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-capture.c +2
-3@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) } } -if (src_pad ==NULL || -media_entity_type (src_pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!src_pad || !is_media_entity_v4l2_subdev (src_pad->entity))break ;/* Don't call FIMC subdev operation to avoid nested locking */ @@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,struct fimc_vid_cap *vc = &fimc->vid_cap;struct v4l2_subdev *sensor; -if (media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (remote->entity))return -EINVAL ;if (WARN_ON (fimc ==NULL ))drivers/media/platform/exynos4-is/fimc-isp-video.c +1
-2@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);drivers/media/platform/exynos4-is/fimc-lite.c +4
-6@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc) }/* Retrieve format at the source pad */ pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity, {struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (entity);struct fimc_lite *fimc =v4l2_get_subdevdata (sd); -unsigned int remote_ent_type =media_entity_type (remote->entity);int ret =0 ;if (WARN_ON (fimc ==NULL ))@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,switch (local->index) {case FLITE_SD_PAD_SINK : -if (remote_ent_type !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (!is_media_entity_v4l2_subdev (remote->entity)) { ret = -EINVAL ;break ; }@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_DMA :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_DEVNODE ) +else if (is_media_entity_v4l2_io (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_DMA );else ret = -EINVAL ;@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,case FLITE_SD_PAD_SOURCE_ISP :if (!(flags &MEDIA_LNK_FL_ENABLED ))atomic_set (&fimc->out_path,FIMC_IO_NONE ); -else if (remote_ent_type ==MEDIA_ENT_T_V4L2_SUBDEV ) +else if (is_media_entity_v4l2_subdev (remote->entity))atomic_set (&fimc->out_path,FIMC_IO_ISP );else ret = -EINVAL ;drivers/media/platform/exynos4-is/media-dev.c +3
-4@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,break ; } -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; sd =media_entity_to_v4l2_subdev (pad->entity);@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; ret =__fimc_md_modify_pipeline (entity, enable);@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)media_entity_graph_walk_start (&graph, entity_err);while ((entity_err =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity_err) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity_err))continue ;__fimc_md_modify_pipeline (entity_err, !enable);drivers/media/platform/omap3isp/isp.c +6
-8@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)struct v4l2_subdev *subdev;int ret; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =isp_pipeline_pm_power_one (entity, change);if (!ret)@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))isp_pipeline_pm_power_one (first, -change);return ret;@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/platform/omap3isp/ispvideo.c +3
-4@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ; __video =to_isp_video (media_entity_to_video_device (entity));@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,return -EINVAL ; } -if (media_entity_type (source) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (source))return 0 ; pipe->external =media_entity_to_v4l2_subdev (source);drivers/media/platform/s3c-camif/camif-capture.c +1
-1@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)/* Retrieve format at the sensor subdev source pad */ pad =media_entity_remote_pad (&camif->pads[0 ]); -if (!pad ||media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; src_fmt.pad = pad->index;drivers/media/platform/vsp1/vsp1_video.c +4
-5@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,return -EPIPE ;/* We've reached a video node, that shouldn't have happened. */ -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))return -EPIPE ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,struct vsp1_rwpf *rwpf;struct vsp1_entity *e; -if (media_entity_type (entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) { +if (is_media_entity_v4l2_io (entity)) { pipe->num_video++;continue ; }@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, pad =media_entity_remote_pad (&input->pads[RWPF_PAD_SOURCE ]);while (pad) { -if (media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!is_media_entity_v4l2_subdev (pad->entity))break ; entity =to_vsp1_entity (media_entity_to_v4l2_subdev (pad->entity));drivers/media/platform/xilinx/xilinx-dma.c +2
-4@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)struct media_pad *remote; remote =media_entity_remote_pad (local); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/media/v4l2-core/v4l2-subdev.c +1
-1@@ -526,7 +526,7 @@ static int v4l2_subdev_link_validate_get_format(struct media_pad *pad, struct v4l2_subdev_format *fmt) { - if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { + if (is_media_entity_v4l2_subdev(pad->entity)) { struct v4l2_subdev *sd =media_entity_to_v4l2_subdev (pad->entity);drivers/staging/media/davinci_vpfe/vpfe_video.c +3
-3@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)while ((entity =media_entity_graph_walk_next (&graph))) {if (entity == &video->video_dev.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) + if ((!is_media_entity_v4l2_io(remote->entity))continue ; far_end =to_vpfe_video (media_entity_to_video_device (entity));if (far_end->type ==V4L2_BUF_TYPE_VIDEO_OUTPUT )@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) + if !is_media_entity_v4l2_subdev(entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,1 );@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_subdev (entity))continue ; subdev =media_entity_to_v4l2_subdev (entity); ret =v4l2_subdev_call (subdev, video, s_stream,0 );drivers/staging/media/omap4iss/iss.c +6
-8@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)media_entity_graph_walk_start (&graph, entity);while ((entity =media_entity_graph_walk_next (&graph))) { -if (media_entity_type (entity) ==MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_io (entity)) use += entity->use_count; }@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change) {struct v4l2_subdev *subdev; - subdev =media_entity_type (entity) ==MEDIA_ENT_T_V4L2_SUBDEV + subdev =is_media_entity_v4l2_subdev (entity) ?media_entity_to_v4l2_subdev (entity) :NULL ;if (entity->use_count ==0 && change >0 && subdev !=NULL ) {@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)media_entity_graph_walk_start (&graph, entity);while (!ret && (entity =media_entity_graph_walk_next (&graph))) -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (entity)) ret =iss_pipeline_pm_power_one (entity, change);if (!ret)@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)while ((first =media_entity_graph_walk_next (&graph)) && first != entity) -if (media_entity_type (first) !=MEDIA_ENT_T_DEVNODE ) +if (is_media_entity_v4l2_subdev (first))iss_pipeline_pm_power_one (first, -change);return ret;@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,break ; pad =media_entity_remote_pad (pad); -if (pad ==NULL || -media_entity_type (pad->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!pad || !is_media_entity_v4l2_subdev (pad->entity))break ; entity = pad->entity;drivers/staging/media/omap4iss/iss_video.c +2
-3@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) remote =media_entity_remote_pad (&video->pad); -if (remote ==NULL || -media_entity_type (remote->entity) !=MEDIA_ENT_T_V4L2_SUBDEV ) +if (!remote || !is_media_entity_v4l2_subdev (remote->entity))return NULL ;if (pad)@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)if (entity == &video->video.entity)continue ; -if (media_entity_type (entity) !=MEDIA_ENT_T_DEVNODE ) +if (!is_media_entity_v4l2_io (entity))continue ;Quoted 6 lines
drivers/staging/media/omap4iss/iss_video.c iss_video_far_end(struct iss_video *video) · line 222
Quoted 1 line
drivers/staging/media/omap4iss/iss_video.c +0
-0far_end =to_iss_video (media_entity_to_video_device (entity));I finally got around to test these patches eventually, and after some debugging found this one. I think it's a good idea to have macros to determine whether an entity exposes a V4L2 sub-device interface but it should be more robust than
is_media_entity_v4l2_subdev()right now is.Quoted 3 lines
Hmm... Not sure what you're meaning... the V4L2 sub-device interface is actually a separate graph object (interfaces). Those macros work at the entities, not at the interface objects.
is_media_entity_v4l2_subdev()will produce wrong results for a large part of V4L2 sub-devices with these patches applied.Quoted 7 lines
I checked again the original implementation, and it seems to be based only on the type as well, albeit that's a range, not a set of different functions.
I suppose this will change at some point in the future: the interface indeed should not be determined by the function of the entity. At least it needs to be fixed now until the rework. I'll submit a patch for that.
I'm folding this small fixup to this patch. It should fix the issues with the unknown subdev types.
This is fixed on some latter patches in this series, adding
MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, but let's avoid breaking bisectability here.include/media/media-entity.h +0
-0include/media/media-entity.h static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) · line 247
Quoted 7 lines
include/media/media-entity.h +1
-0@@ -241,6 +241,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity)return false;switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_BASE :case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR :case MEDIA_ENT_T_V4L2_SUBDEV_FLASH :case MEDIA_ENT_T_V4L2_SUBDEV_LENS :Actually, due to some comments for the patch:
s5c73m3: fix subdev type
Quoted 4 lines
And a few others, I'm actually adding
MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWNdefinition on this patchset.The new version of this patch is:
Sorry, wrong version. The right one is:
Quoted 1 line
From
5b7692b1bed4edf4a19b94d1883c21eb98754214Mon Sep 17 00:00:00 2001
From: Mauro Carvalho Chehab <[email protected]>
Date: Fri, 21 Aug 2015 12:17:40 -0300
Subject: [PATCH] [media] media: add macros to check if subdev or V4L2 DMA
As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA).
Drivers that create entities that don't belong to any defined subdev category should use MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN.
include/media/media-entity.h +34 -0
@@ -220,6 +220,40 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id)return id; } +static inline bool is_media_entity_v4l2_io (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_VIDEO : +case MEDIA_ENT_T_V4L2_VBI : +case MEDIA_ENT_T_V4L2_SWRADIO : +return true; +default : +return false; + } +} + +static inline bool is_media_entity_v4l2_subdev (struct media_entity *entity) +{ +if (!entity) +return false; + +switch (entity->type) { +case MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN : +case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR : +case MEDIA_ENT_T_V4L2_SUBDEV_FLASH : +case MEDIA_ENT_T_V4L2_SUBDEV_LENS : +case MEDIA_ENT_T_V4L2_SUBDEV_DECODER : +case MEDIA_ENT_T_V4L2_SUBDEV_TUNER : +return true; + +default : +return false; + } +} +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16#define MEDIA_ENTITY_ENUM_MAX_ID 64
include/uapi/linux/media.h +3 -0
@@ -75,6 +75,9 @@ struct media_device_info {#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6)/* V4L2 Sub-device entities */ + +#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1)#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2)#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3)
PATCH 1/1 media: Correctly determine whether an entity is a sub-device
In reply to Mauro Carvalho ChehabIf the function of an entity is not one of the pre-defined ones, it is not correctly recognised as a V4L2 sub-device.
--- include/media/media-entity.h | 1 + 1 file changed, 1 insertion(+)
include/media/media-entity.h +1 -0
@@ -328,6 +328,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity)case MEDIA_ENT_F_LENS :case MEDIA_ENT_F_ATV_DECODER :case MEDIA_ENT_F_TUNER : +case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN :return true;default :
Signature · 1 line
2.1.4
PATCH 1/1 media: Correctly determine whether an entity is a sub-device
Em Mon, 12 Oct 2015 18:38:23 +0300
Sakari Ailus <[email protected]> escreveu:
Quoted 13 lines
If the function of an entity is not one of the pre-defined ones, it is not correctly recognised as a V4L2 sub-device.
Signed-off-by Sakari Ailus <[email protected]>--- include/media/media-entity.h | 1 + 1 file changed, 1 insertion(+)include/media/media-entity.h +0
-0
include/media/media-entity.h static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) · line 332
Quoted 5 lines
include/media/media-entity.h +1
-0@@ -328,6 +328,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity)case MEDIA_ENT_F_LENS :case MEDIA_ENT_F_ATV_DECODER :case MEDIA_ENT_F_TUNER : +case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN :return true;
OK.
Quoted 2 lines
include/media/media-entity.h +0
-0default :