As requested by Sakari and Hans, I'm re-sending the entire 83 patch series that were already sent to the media ML.
NOTE: as agreed on IRC, after getting the ack for those patches, eventually adding newer fixups where needed, we should add this to the media-controller topic branch of our devel tree.
Before merging this on the "master" branch, we'll:
1) add a patch series that Sakari is working to allow not using the entity_id for the graph traversal;
2) add a patch converting MC next gen to use a single range, as agreed on IRC;
3) add a patch increasing the maximum number of objects, in order for the graph traversal to work with DVB drivers;
4) get ALSA maintainer's acks for the ALSA changes (on this series and on Shuah's series);
5) add Shuah ALSA patches.
I'll do the above work after getting the acks for the patches already sent.
Javier Martinez Canillas (13): [media] staging: omap4iss: get entity ID using media_entity_id() [media] omap3isp: get entity ID using media_entity_id() [media] media: use entity.graph_obj.mdev instead of .parent [media] media: remove media entity .parent field [media] omap3isp: separate links creation from entities init [media] omap3isp: create links after all subdevs have been bound [media] staging: omap4iss: separate links creation from entities init [media] v4l: vsp1: create pad links after subdev registration [media] v4l: vsp1: separate links creation from entities init [media] uvcvideo: create pad links after subdev registration [media] smiapp: create pad links after subdev registration [media] media-entity: init pads on entity init if was registered before media: don't try to empty links list in media_entity_cleanup()
Mauro Carvalho Chehab (70): [media] media: create a macro to get entity ID [media] media: add a common struct to be embed on media graph objects [media] media: use media_gobj inside entities [media] media: use media_gobj inside pads [media] media: use media_gobj inside links [media] media: add messages when media device gets (un)registered [media] media: add a debug message to warn about gobj creation/removal [media] media: rename the function that create pad links [media] uapi/media.h: Declare interface types for V4L2 and DVB [media] media: add functions to allow creating interfaces [media] uapi/media.h: Declare interface types for ALSA [media] media: Don't accept early-created links [media] media: convert links from array to list [media] media: make add link more generic [media] media: make media_link more generic to handle interace links [media] media: make link debug printk more generic [media] media: add support to link interfaces and entities [media] media-entity: add a helper function to create interface [media] dvbdev: add support for interfaces [media] media: add a linked list to track interfaces by mdev [media] dvbdev: add support for indirect interface links [media] uapi/media.h: Fix entity namespace [media] replace all occurrences of MEDIA_ENT_T_DEVNODE_V4L [media] replace all occurrences of MEDIA_ENT_T_DEVNODE_DVB [media] media: add macros to check if subdev or V4L2 DMA [media] media: use macros to check for V4L2 subdev entities [media] omap3/omap4/davinci: get rid of MEDIA_ENT_T_V4L2_SUBDEV abuse [media] s5c73m3: fix subdev type [media] s5k5baf: fix subdev type [media] davinci_vbpe: stop MEDIA_ENT_T_V4L2_SUBDEV abuse [media] omap4iss: stop MEDIA_ENT_T_V4L2_SUBDEV abuse [media] v4l2-subdev: use MEDIA_ENT_T_UNKNOWN for new subdevs [media] media controller: get rid of entity subtype on Kernel [media] media.h: don't use legacy entity macros at Kernel [media] DocBook: update descriptions for the media controller entities [media] dvb: modify core to implement interfaces/entities at MC new gen [media] media: report if a pad is sink or source at debug msg [media] uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl [media] media: Use a macro to interate between all interfaces [media] media: move mdev list init to gobj [media] media-device: add pads and links to media_device [media] media_device: add a topology version field [media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl [media] media-entity: unregister entity links [media] remove interface links at media_entity_unregister() [media] media-device: remove interfaces and interface links [media] au0828: unregister MC at the end [media] v4l2-core: create MC interfaces for devnodes [media] media-entity.h: document all the structs [media] tuner-core: add an input pad [media] au0828: add support for the connectors [media] au0828: Create connector links [media] media-device: supress backlinks at G_TOPOLOGY ioctl [media] media-controller: enable all interface links at init [media] media.h: create connector entities for hybrid TV devices [media] dvbdev: returns error if graph object creation fails [media] dvb core: must check dvb_create_media_graph() [media] media-entity: enforce check of interface and links creation [media] cx231xx: enforce check for graph creation [media] au0828:: enforce check for graph creation [media] media-entity: must check media_create_pad_link() [media] media-entity.h: rename entity.type to entity.function [media] media-device: export the entity function via new ioctl [media] uapi/media.h: Rename entities types to functions [media] DocBook: update entities documentation [media] dvbdev: move indirect links on dvr/demux to a separate function [media] dvbdev: Don't create indirect links [media] media_entity: remove gfp_flags argument [media] media-device: use unsigned ints on some places [media] media-entity.c: get rid of var length arrays
.../DocBook/media/v4l/media-ioc-enum-entities.xml | 67 +-- Documentation/media-framework.txt | 2 +- Documentation/video4linux/v4l2-framework.txt | 4 +- drivers/media/common/siano/smsdvb-main.c | 6 +- drivers/media/dvb-core/dmxdev.c | 4 +- drivers/media/dvb-core/dvb_ca_en50221.c | 2 +- drivers/media/dvb-core/dvb_frontend.c | 11 +- drivers/media/dvb-core/dvb_net.c | 2 +- drivers/media/dvb-core/dvbdev.c | 392 +++++++++++++---- drivers/media/dvb-core/dvbdev.h | 17 +- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/firewire/firedtv-ci.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/adv7180.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 8 +- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 8 +- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 22 +- drivers/media/i2c/tvp514x.c | 2 +- drivers/media/i2c/tvp7002.c | 2 +- drivers/media/media-device.c | 272 ++++++++++-- drivers/media/media-entity.c | 478 +++++++++++++++++---- drivers/media/pci/bt8xx/dst_ca.c | 3 +- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- drivers/media/pci/ngene/ngene-core.c | 2 +- drivers/media/pci/ttpci/av7110.c | 2 +- drivers/media/pci/ttpci/av7110_av.c | 4 +- drivers/media/pci/ttpci/av7110_ca.c | 2 +- drivers/media/platform/exynos4-is/common.c | 3 +- drivers/media/platform/exynos4-is/fimc-capture.c | 5 +- drivers/media/platform/exynos4-is/fimc-isp-video.c | 9 +- drivers/media/platform/exynos4-is/fimc-lite.c | 18 +- drivers/media/platform/exynos4-is/media-dev.c | 25 +- drivers/media/platform/exynos4-is/media-dev.h | 8 +- drivers/media/platform/omap3isp/isp.c | 202 +++++---- drivers/media/platform/omap3isp/ispccdc.c | 39 +- drivers/media/platform/omap3isp/ispccdc.h | 1 + drivers/media/platform/omap3isp/ispccp2.c | 35 +- drivers/media/platform/omap3isp/ispccp2.h | 1 + drivers/media/platform/omap3isp/ispcsi2.c | 33 +- drivers/media/platform/omap3isp/ispcsi2.h | 1 + drivers/media/platform/omap3isp/isppreview.c | 48 ++- drivers/media/platform/omap3isp/isppreview.h | 1 + drivers/media/platform/omap3isp/ispresizer.c | 46 +- drivers/media/platform/omap3isp/ispresizer.h | 1 + drivers/media/platform/omap3isp/ispvideo.c | 17 +- drivers/media/platform/s3c-camif/camif-capture.c | 2 +- drivers/media/platform/s3c-camif/camif-core.c | 4 +- drivers/media/platform/vsp1/vsp1_drv.c | 34 +- drivers/media/platform/vsp1/vsp1_rpf.c | 29 +- drivers/media/platform/vsp1/vsp1_rwpf.h | 5 + drivers/media/platform/vsp1/vsp1_video.c | 15 +- drivers/media/platform/vsp1/vsp1_wpf.c | 40 +- drivers/media/platform/xilinx/xilinx-dma.c | 10 +- drivers/media/platform/xilinx/xilinx-vipp.c | 4 +- drivers/media/usb/au0828/au0828-core.c | 98 ++++- drivers/media/usb/au0828/au0828-dvb.c | 8 +- drivers/media/usb/au0828/au0828-video.c | 84 +++- drivers/media/usb/au0828/au0828.h | 3 +- drivers/media/usb/cx231xx/cx231xx-cards.c | 46 +- drivers/media/usb/cx231xx/cx231xx-dvb.c | 6 +- drivers/media/usb/cx231xx/cx231xx-video.c | 10 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 4 +- drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 6 +- drivers/media/usb/uvc/uvc_entity.c | 25 +- drivers/media/v4l2-core/tuner-core.c | 10 +- drivers/media/v4l2-core/v4l2-dev.c | 112 ++++- drivers/media/v4l2-core/v4l2-device.c | 16 +- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 8 +- drivers/staging/media/davinci_vpfe/dm365_ipipe.c | 9 +- drivers/staging/media/davinci_vpfe/dm365_ipipeif.c | 15 +- drivers/staging/media/davinci_vpfe/dm365_isif.c | 15 +- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 33 +- .../staging/media/davinci_vpfe/vpfe_mc_capture.c | 10 +- drivers/staging/media/davinci_vpfe/vpfe_video.c | 17 +- drivers/staging/media/omap4iss/iss.c | 123 ++++-- drivers/staging/media/omap4iss/iss_csi2.c | 46 +- drivers/staging/media/omap4iss/iss_csi2.h | 1 + drivers/staging/media/omap4iss/iss_ipipe.c | 9 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 42 +- drivers/staging/media/omap4iss/iss_ipipeif.h | 1 + drivers/staging/media/omap4iss/iss_resizer.c | 40 +- drivers/staging/media/omap4iss/iss_resizer.h | 1 + drivers/staging/media/omap4iss/iss_video.c | 9 +- include/media/media-device.h | 34 +- include/media/media-entity.h | 322 ++++++++++++-- include/media/tuner.h | 8 + include/media/v4l2-dev.h | 1 + include/uapi/linux/media.h | 214 ++++++++- 99 files changed, 2535 insertions(+), 831 deletions(-)
Instead of accessing directly entity.id, let's create a macro, as this field will be moved into a common struct later on.
Change-Id: Iabc90a9f28ade856571d245dcfd27cde002c7d20 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 8 ++++---- drivers/media/media-entity.c | 8 ++++---- drivers/media/platform/vsp1/vsp1_video.c | 4 ++-- include/media/media-entity.h | 5 +++++ 4 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index c55ab5029323..e429605ca2c3 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -77,8 +77,8 @@ static struct media_entity *find_entity(struct media_device *mdev, u32 id) spin_lock(&mdev->lock);
media_device_for_each_entity(entity, mdev) { - if ((entity->id == id && !next) || - (entity->id > id && next)) { + if (((media_entity_id(entity) == id) && !next) || + ((media_entity_id(entity) > id) && next)) { spin_unlock(&mdev->lock); return entity; } @@ -104,7 +104,7 @@ static long media_device_enum_entities(struct media_device *mdev, if (ent == NULL) return -EINVAL;
- u_ent.id = ent->id; + u_ent.id = media_entity_id(ent); if (ent->name) strlcpy(u_ent.name, ent->name, sizeof(u_ent.name)); u_ent.type = ent->type; @@ -122,7 +122,7 @@ static long media_device_enum_entities(struct media_device *mdev, static void media_device_kpad_to_upad(const struct media_pad *kpad, struct media_pad_desc *upad) { - upad->entity = kpad->entity->id; + upad->entity = media_entity_id(kpad->entity); upad->index = kpad->index; upad->flags = kpad->flags; } diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 949e5f92cbdc..cb0ac4e0dfa5 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -140,10 +140,10 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, graph->stack[graph->top].entity = NULL; bitmap_zero(graph->entities, MEDIA_ENTITY_ENUM_MAX_ID);
- if (WARN_ON(entity->id >= MEDIA_ENTITY_ENUM_MAX_ID)) + if (WARN_ON(media_entity_id(entity) >= MEDIA_ENTITY_ENUM_MAX_ID)) return;
- __set_bit(entity->id, graph->entities); + __set_bit(media_entity_id(entity), graph->entities); stack_push(graph, entity); } EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); @@ -184,11 +184,11 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
/* Get the entity in the other end of the link . */ next = media_entity_other(entity, link); - if (WARN_ON(next->id >= MEDIA_ENTITY_ENUM_MAX_ID)) + if (WARN_ON(media_entity_id(next) >= MEDIA_ENTITY_ENUM_MAX_ID)) return NULL;
/* Has the entity already been visited? */ - if (__test_and_set_bit(next->id, graph->entities)) { + if (__test_and_set_bit(media_entity_id(next), graph->entities)) { link_top(graph)++; continue; } diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 17f08973f835..debe4e539df6 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -352,10 +352,10 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe, break;
/* Ensure the branch has no loop. */ - if (entities & (1 << entity->subdev.entity.id)) + if (entities & (1 << media_entity_id(&entity->subdev.entity))) return -EPIPE;
- entities |= 1 << entity->subdev.entity.id; + entities |= 1 << media_entity_id(&entity->subdev.entity);
/* UDS can't be chained. */ if (entity->type == VSP1_ENTITY_UDS) { diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 8b21a4d920d9..0a66fc225559 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -113,6 +113,11 @@ static inline u32 media_entity_subtype(struct media_entity *entity) return entity->type & MEDIA_ENT_SUBTYPE_MASK; }
+static inline u32 media_entity_id(struct media_entity *entity) +{ + return entity->id; +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64
From: Javier Martinez Canillas javier@osg.samsung.com
Assessing media_entity ID should now use media_entity_id() macro to obtain the entity ID, as a next patch will remove the .id field from struct media_entity .
So, get rid of it, otherwise the omap4iss driver will fail to build.
Change-Id: I2b16d4503fe550dce2539e596505365061866978 Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/staging/media/omap4iss/iss.c | 2 +- drivers/staging/media/omap4iss/iss_video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 9bfb725b9986..e54a7afd31de 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -607,7 +607,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe, * crashed. Mark it as such, the ISS will be reset when * applications will release it. */ - iss->crashed |= 1U << subdev->entity.id; + iss->crashed |= 1U << media_entity_id(&subdev->entity); failure = -ETIMEDOUT; } } diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index bae67742706f..25e9e7a6b99d 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -784,7 +784,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) entity = &video->video.entity; media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) - pipe->entities |= 1 << entity->id; + pipe->entities |= 1 << media_entity_id(entity);
/* Verify that the currently configured format matches the output of * the connected subdev.
From: Javier Martinez Canillas javier@osg.samsung.com
Assessing media_entity ID should now use media_entity_id() macro to obtain the entity ID, as a next patch will remove the .id field from struct media_entity .
So, get rid of it, otherwise the omap3isp driver will fail to build.
Change-Id: I1f0b97105f06a41384949df8ab9318dbc5f48ce6 Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/platform/omap3isp/isp.c | 7 +++++-- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispvideo.c | 8 +++++--- 3 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 56e683b19a73..e08183f9d0f7 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -975,6 +975,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) struct v4l2_subdev *subdev; int failure = 0; int ret; + u32 id;
/* * We need to stop all the modules after CCDC first or they'll @@ -1027,8 +1028,10 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) if (ret) { dev_info(isp->dev, "Unable to stop %s\n", subdev->name); isp->stop_failure = true; - if (subdev == &isp->isp_prev.subdev) - isp->crashed |= 1U << subdev->entity.id; + if (subdev == &isp->isp_prev.subdev) { + id = media_entity_id(&subdev->entity); + isp->crashed |= 1U << id; + } failure = -ETIMEDOUT; } } diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 3b10304b580b..d96e3be5e252 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -1608,7 +1608,7 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc) /* Wait for the CCDC to become idle. */ if (ccdc_sbl_wait_idle(ccdc, 1000)) { dev_info(isp->dev, "CCDC won't become idle!\n"); - isp->crashed |= 1U << ccdc->subdev.entity.id; + isp->crashed |= 1U << media_entity_id(&ccdc->subdev.entity); omap3isp_pipeline_cancel_stream(pipe); return 0; } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 3094572f8897..6c89dc40df85 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -235,7 +235,7 @@ static int isp_video_get_graph_data(struct isp_video *video, while ((entity = media_entity_graph_walk_next(&graph))) { struct isp_video *__video;
- pipe->entities |= 1 << entity->id; + pipe->entities |= 1 << media_entity_id(entity);
if (far_end != NULL) continue; @@ -891,6 +891,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video, struct v4l2_ext_control ctrl; unsigned int i; int ret; + u32 id;
/* Memory-to-memory pipelines have no external subdev. */ if (pipe->input != NULL) @@ -898,7 +899,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
for (i = 0; i < ARRAY_SIZE(ents); i++) { /* Is the entity part of the pipeline? */ - if (!(pipe->entities & (1 << ents[i]->id))) + if (!(pipe->entities & (1 << media_entity_id(ents[i])))) continue;
/* ISP entities have always sink pad == 0. Find source. */ @@ -950,7 +951,8 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
pipe->external_rate = ctrl.value64;
- if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) { + id = media_entity_id(&isp->isp_ccdc.subdev.entity); + if (pipe->entities & (1 << id)) { unsigned int rate = UINT_MAX; /* * Check that maximum allowed CCDC pixel rate isn't
Due to the MC API proposed changes, we'll need to have an unique object ID for all graph objects, and have some shared fields that will be common on all media graph objects.
Right now, the only common object is the object ID, but other fields will be added later on.
Change-Id: Ieb4470a173004c2b67a240e6fe2b7e6a8c02ad52 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-entity.c | 32 +++++++++++++++++++++++ include/media/media-entity.h | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index cb0ac4e0dfa5..4834172bf6f8 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -27,6 +27,38 @@ #include <media/media-device.h>
/** + * media_gobj_init - Initialize a graph object + * + * @mdev: Pointer to the media_device that contains the object + * @type: Type of the object + * @gobj: Pointer to the object + * + * This routine initializes the embedded struct media_gobj inside a + * media graph object. It is called automatically if media_*_create() + * calls are used. However, if the object (entity, link, pad, interface) + * is embedded on some other object, this function should be called before + * registering the object at the media controller. + */ +void media_gobj_init(struct media_device *mdev, + enum media_gobj_type type, + struct media_gobj *gobj) +{ + /* For now, nothing to do */ +} + +/** + * media_gobj_remove - Stop using a graph object on a media device + * + * @graph_obj: Pointer to the object + * + * This should be called at media_device_unregister_*() routines + */ +void media_gobj_remove(struct media_gobj *gobj) +{ + /* For now, nothing to do */ +} + +/** * media_entity_init - Initialize a media entity * * @num_pads: Total number of sink and source pads. diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 0a66fc225559..b1854239a476 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -28,6 +28,39 @@ #include <linux/list.h> #include <linux/media.h>
+/* Enums used internally at the media controller to represent graphs */ + +/** + * enum media_gobj_type - type of a graph object + * + */ +enum media_gobj_type { + /* FIXME: add the types here, as we embed media_gobj */ + MEDIA_GRAPH_NONE +}; + +#define MEDIA_BITS_PER_TYPE 8 +#define MEDIA_BITS_PER_LOCAL_ID (32 - MEDIA_BITS_PER_TYPE) +#define MEDIA_LOCAL_ID_MASK GENMASK(MEDIA_BITS_PER_LOCAL_ID - 1, 0) + +/* Structs to represent the objects that belong to a media graph */ + +/** + * struct media_gobj - Define a graph 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"). + * + * All objects on the media graph should have this struct embedded + */ +struct media_gobj { + u32 id; +}; + + struct media_pipeline { };
@@ -118,6 +151,26 @@ static inline u32 media_entity_id(struct media_entity *entity) return entity->id; }
+static inline enum media_gobj_type media_type(struct media_gobj *gobj) +{ + return gobj->id >> MEDIA_BITS_PER_LOCAL_ID; +} + +static inline u32 media_localid(struct media_gobj *gobj) +{ + return gobj->id & MEDIA_LOCAL_ID_MASK; +} + +static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) +{ + u32 id; + + id = type << MEDIA_BITS_PER_LOCAL_ID; + id |= local_id & MEDIA_LOCAL_ID_MASK; + + return id; +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64
@@ -131,6 +184,14 @@ struct media_entity_graph { int top; };
+#define gobj_to_entity(gobj) \ + container_of(gobj, struct media_entity, graph_obj) + +void media_gobj_init(struct media_device *mdev, + enum media_gobj_type type, + struct media_gobj *gobj); +void media_gobj_remove(struct media_gobj *gobj); + int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity);
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:53PM -0300, Mauro Carvalho Chehab wrote:
Due to the MC API proposed changes, we'll need to have an unique object ID for all graph objects, and have some shared fields that will be common on all media graph objects.
Right now, the only common object is the object ID, but other fields will be added later on.
Change-Id: Ieb4470a173004c2b67a240e6fe2b7e6a8c02ad52 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-entity.c | 32 +++++++++++++++++++++++ include/media/media-entity.h | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index cb0ac4e0dfa5..4834172bf6f8 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -27,6 +27,38 @@ #include <media/media-device.h>
/**
- media_gobj_init - Initialize a graph object
- @mdev: Pointer to the media_device that contains the object
- @type: Type of the object
- @gobj: Pointer to the object
- This routine initializes the embedded struct media_gobj inside a
- media graph object. It is called automatically if media_*_create()
- calls are used. However, if the object (entity, link, pad, interface)
- is embedded on some other object, this function should be called before
- registering the object at the media controller.
- */
+void media_gobj_init(struct media_device *mdev,
enum media_gobj_type type,
struct media_gobj *gobj)
+{
media_gobj_init() does a number of things very soon, including adding the graph object to the media device's relevant list of objects.
I think I'd call this media_gobj_register() instead, since this function not only changes the internal state of this object, but also the media device itself.
- /* For now, nothing to do */
+}
+/**
- media_gobj_remove - Stop using a graph object on a media device
- @graph_obj: Pointer to the object
- This should be called at media_device_unregister_*() routines
- */
+void media_gobj_remove(struct media_gobj *gobj) +{
- /* For now, nothing to do */
+}
And media_gobj_unregister() here.
+/**
- media_entity_init - Initialize a media entity
- @num_pads: Total number of sink and source pads.
Em Mon, 12 Oct 2015 22:49:05 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:53PM -0300, Mauro Carvalho Chehab wrote:
Due to the MC API proposed changes, we'll need to have an unique object ID for all graph objects, and have some shared fields that will be common on all media graph objects.
Right now, the only common object is the object ID, but other fields will be added later on.
Change-Id: Ieb4470a173004c2b67a240e6fe2b7e6a8c02ad52 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-entity.c | 32 +++++++++++++++++++++++ include/media/media-entity.h | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index cb0ac4e0dfa5..4834172bf6f8 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -27,6 +27,38 @@ #include <media/media-device.h>
/**
- media_gobj_init - Initialize a graph object
- @mdev: Pointer to the media_device that contains the object
- @type: Type of the object
- @gobj: Pointer to the object
- This routine initializes the embedded struct media_gobj inside a
- media graph object. It is called automatically if media_*_create()
- calls are used. However, if the object (entity, link, pad, interface)
- is embedded on some other object, this function should be called before
- registering the object at the media controller.
- */
+void media_gobj_init(struct media_device *mdev,
enum media_gobj_type type,
struct media_gobj *gobj)
+{
media_gobj_init() does a number of things very soon, including adding the graph object to the media device's relevant list of objects.
I think I'd call this media_gobj_register() instead, since this function not only changes the internal state of this object, but also the media device itself.
- /* For now, nothing to do */
+}
+/**
- media_gobj_remove - Stop using a graph object on a media device
- @graph_obj: Pointer to the object
- This should be called at media_device_unregister_*() routines
- */
+void media_gobj_remove(struct media_gobj *gobj) +{
- /* For now, nothing to do */
+}
And media_gobj_unregister() here.
Agreed. I'll add a patch at the end of the series changing those.
Regards, Mauro
As entities are graph objects, let's embed media_gobj on it. That ensures an unique ID for entities that can be global along the entire media controller.
For now, we'll keep the already existing entity ID. Such field need to be dropped at some point, but for now, let's not do this, to avoid needing to review all drivers and the userspace apps.
Change-Id: I53ce49660c9ea3b6c28779b5aa0f56211e00ef4b Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 8 +++----- drivers/media/media-entity.c | 7 ++++++- include/media/media-device.h | 3 ++- include/media/media-entity.h | 9 ++++----- 4 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index e429605ca2c3..81d6a130efef 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -379,7 +379,6 @@ int __must_check __media_device_register(struct media_device *mdev, if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0)) return -EINVAL;
- mdev->entity_id = 1; INIT_LIST_HEAD(&mdev->entities); spin_lock_init(&mdev->lock); mutex_init(&mdev->graph_mutex); @@ -433,10 +432,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, entity->parent = mdev;
spin_lock(&mdev->lock); - if (entity->id == 0) - entity->id = mdev->entity_id++; - else - mdev->entity_id = max(entity->id + 1, mdev->entity_id); + /* Initialize media_gobj embedded at the entity */ + media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities); spin_unlock(&mdev->lock);
@@ -459,6 +456,7 @@ void media_device_unregister_entity(struct media_entity *entity) return;
spin_lock(&mdev->lock); + media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock); entity->parent = NULL; diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 4834172bf6f8..888cb88e19bf 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -43,7 +43,12 @@ void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj) { - /* For now, nothing to do */ + /* Create a per-type unique object ID */ + switch (type) { + case MEDIA_GRAPH_ENTITY: + gobj->id = media_gobj_gen_id(type, ++mdev->entity_id); + break; + } }
/** diff --git a/include/media/media-device.h b/include/media/media-device.h index a44f18fdf321..f6deef6e5820 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -41,7 +41,7 @@ struct device; * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision * @driver_version: Device driver version - * @entity_id: ID of the next entity to be registered + * @entity_id: Unique ID used on the last entity registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -69,6 +69,7 @@ struct media_device { u32 driver_version;
u32 entity_id; + struct list_head entities;
/* Protects the entities list */ diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b1854239a476..bb74b5883cbb 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -33,10 +33,10 @@ /** * enum media_gobj_type - type of a graph object * + * @MEDIA_GRAPH_ENTITY: Identify a media entity */ enum media_gobj_type { - /* FIXME: add the types here, as we embed media_gobj */ - MEDIA_GRAPH_NONE + MEDIA_GRAPH_ENTITY, };
#define MEDIA_BITS_PER_TYPE 8 @@ -94,10 +94,9 @@ struct media_entity_operations { };
struct media_entity { + struct media_gobj graph_obj; struct list_head list; struct media_device *parent; /* Media device this entity belongs to*/ - u32 id; /* Entity ID, unique in the parent media - * device context */ const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */ @@ -148,7 +147,7 @@ static inline u32 media_entity_subtype(struct media_entity *entity)
static inline u32 media_entity_id(struct media_entity *entity) { - return entity->id; + return entity->graph_obj.id; }
static inline enum media_gobj_type media_type(struct media_gobj *gobj)
PADs also need unique object IDs that won't conflict with the entity object IDs.
The pad objects are currently created via media_entity_init() and, once created, never change.
While this will likely change in the future in order to support dynamic changes, for now we'll keep PADs as arrays and initialize the media_gobj embedded structs when registering the entity.
Change-Id: I9db7bcd2f66dd38343fe045b9fa43426d318830d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 11 +++++++++++ drivers/media/media-entity.c | 3 +++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 19 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 81d6a130efef..3bdda16584fe 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -427,6 +427,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { + int i; + /* Warn if we apparently re-register an entity */ WARN_ON(entity->parent != NULL); entity->parent = mdev; @@ -435,6 +437,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, /* Initialize media_gobj embedded at the entity */ media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities); + + /* Initialize objects at the pads */ + for (i = 0; i < entity->num_pads; i++) + media_gobj_init(mdev, MEDIA_GRAPH_PAD, + &entity->pads[i].graph_obj); + spin_unlock(&mdev->lock);
return 0; @@ -450,12 +458,15 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); */ void media_device_unregister_entity(struct media_entity *entity) { + int i; struct media_device *mdev = entity->parent;
if (mdev == NULL) return;
spin_lock(&mdev->lock); + for (i = 0; i < entity->num_pads; i++) + media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 888cb88e19bf..377c6655c5d0 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -48,6 +48,9 @@ void media_gobj_init(struct media_device *mdev, case MEDIA_GRAPH_ENTITY: gobj->id = media_gobj_gen_id(type, ++mdev->entity_id); break; + case MEDIA_GRAPH_PAD: + gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); + break; } }
diff --git a/include/media/media-device.h b/include/media/media-device.h index f6deef6e5820..9493721f630e 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -42,6 +42,7 @@ struct device; * @hw_revision: Hardware device revision * @driver_version: Device driver version * @entity_id: Unique ID used on the last entity registered + * @pad_id: Unique ID used on the last pad registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -69,6 +70,7 @@ struct media_device { u32 driver_version;
u32 entity_id; + u32 pad_id;
struct list_head entities;
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index bb74b5883cbb..ce4c654486d6 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -34,9 +34,11 @@ * enum media_gobj_type - type of a graph object * * @MEDIA_GRAPH_ENTITY: Identify a media entity + * @MEDIA_GRAPH_PAD: Identify a media pad */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, + MEDIA_GRAPH_PAD, };
#define MEDIA_BITS_PER_TYPE 8 @@ -72,6 +74,7 @@ struct media_link { };
struct media_pad { + struct media_gobj graph_obj; 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_*) */
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:55PM -0300, Mauro Carvalho Chehab wrote:
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 81d6a130efef..3bdda16584fe 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -427,6 +427,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) {
- int i;
i should be unsigned, not signed.
- /* Warn if we apparently re-register an entity */ WARN_ON(entity->parent != NULL); entity->parent = mdev;
@@ -435,6 +437,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, /* Initialize media_gobj embedded at the entity */ media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities);
/* Initialize objects at the pads */
for (i = 0; i < entity->num_pads; i++)
media_gobj_init(mdev, MEDIA_GRAPH_PAD,
&entity->pads[i].graph_obj);
spin_unlock(&mdev->lock);
return 0;
@@ -450,12 +458,15 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); */ void media_device_unregister_entity(struct media_entity *entity) {
- int i;
Same here. Also it's a good practice to arrange loop and temporary variables as last.
struct media_device *mdev = entity->parent;
if (mdev == NULL) return;
spin_lock(&mdev->lock);
- for (i = 0; i < entity->num_pads; i++)
media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock);media_gobj_remove(&entity->pads[i].graph_obj);
Em Mon, 12 Oct 2015 22:35:21 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:55PM -0300, Mauro Carvalho Chehab wrote:
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 81d6a130efef..3bdda16584fe 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -427,6 +427,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) {
- int i;
i should be unsigned, not signed.
I'm pretty sure you pointed that already and I fixed on a latter patch. It is at patch 80/83.
As I justified on that thread, rebasing a 83 patch series to touch at the 6th patch is risky, as it could cause breakages and badly solved conflicts. So, I really prefer not doing that, specially when it is a minor issue.
Regards, Mauro
- /* Warn if we apparently re-register an entity */ WARN_ON(entity->parent != NULL); entity->parent = mdev;
@@ -435,6 +437,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, /* Initialize media_gobj embedded at the entity */ media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); list_add_tail(&entity->list, &mdev->entities);
/* Initialize objects at the pads */
for (i = 0; i < entity->num_pads; i++)
media_gobj_init(mdev, MEDIA_GRAPH_PAD,
&entity->pads[i].graph_obj);
spin_unlock(&mdev->lock);
return 0;
@@ -450,12 +458,15 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); */ void media_device_unregister_entity(struct media_entity *entity) {
- int i;
Same here. Also it's a good practice to arrange loop and temporary variables as last.
struct media_device *mdev = entity->parent;
if (mdev == NULL) return;
spin_lock(&mdev->lock);
- for (i = 0; i < entity->num_pads; i++)
media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock);media_gobj_remove(&entity->pads[i].graph_obj);
Hi Mauro,
On Mon, Oct 12, 2015 at 08:43:14PM -0300, Mauro Carvalho Chehab wrote:
Em Mon, 12 Oct 2015 22:35:21 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:55PM -0300, Mauro Carvalho Chehab wrote:
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 81d6a130efef..3bdda16584fe 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -427,6 +427,8 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) {
- int i;
i should be unsigned, not signed.
I'm pretty sure you pointed that already and I fixed on a latter patch. It is at patch 80/83.
As I justified on that thread, rebasing a 83 patch series to touch at the 6th patch is risky, as it could cause breakages and badly solved conflicts. So, I really prefer not doing that, specially when it is a minor issue.
Oh. Indeed. I don't remember what I commented anymore back then and what not, but at least the comment was the same. ;) I'm fine with fixing this later on. So please ignore this comment.
Just like entities and pads, links also need to have unique Object IDs along a given media controller.
So, let's add a media_gobj inside it and initialize the object then a new link is created.
Change-Id: I38e773224d47a33158279dc7099635285493345b Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 9 +++++++++ drivers/media/media-entity.c | 9 +++++++++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 23 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 3bdda16584fe..065f6f08da37 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -438,6 +438,13 @@ 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, @@ -465,6 +472,8 @@ void media_device_unregister_entity(struct media_entity *entity) return;
spin_lock(&mdev->lock); + for (i = 0; i < entity->num_links; i++) + media_gobj_remove(&entity->links[i].graph_obj); for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 377c6655c5d0..36d725ec5f3d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -51,6 +51,9 @@ void media_gobj_init(struct media_device *mdev, case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); break; + case MEDIA_GRAPH_LINK: + gobj->id = media_gobj_gen_id(type, ++mdev->link_id); + break; } }
@@ -491,6 +494,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, link->sink = &sink->pads[sink_pad]; link->flags = flags;
+ /* Initialize graph object embedded at the new link */ + media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj); + /* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. */ @@ -504,6 +510,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags;
+ /* Initialize graph object embedded at the new link */ + media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj); + link->reverse = backlink; backlink->reverse = link;
diff --git a/include/media/media-device.h b/include/media/media-device.h index 9493721f630e..05414e351f8e 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -43,6 +43,7 @@ struct device; * @driver_version: Device driver version * @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 * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -71,6 +72,7 @@ struct media_device {
u32 entity_id; u32 pad_id; + u32 link_id;
struct list_head entities;
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ce4c654486d6..cd08a96bfbaa 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -35,10 +35,12 @@ * * @MEDIA_GRAPH_ENTITY: Identify a media entity * @MEDIA_GRAPH_PAD: Identify a media pad + * @MEDIA_GRAPH_LINK: Identify a media link */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, MEDIA_GRAPH_PAD, + MEDIA_GRAPH_LINK, };
#define MEDIA_BITS_PER_TYPE 8 @@ -67,6 +69,7 @@ struct media_pipeline { };
struct media_link { + struct media_gobj graph_obj; struct media_pad *source; /* Source pad */ struct media_pad *sink; /* Sink pad */ struct media_link *reverse; /* Link in the reverse direction */
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:56PM -0300, Mauro Carvalho Chehab wrote:
Just like entities and pads, links also need to have unique Object IDs along a given media controller.
So, let's add a media_gobj inside it and initialize the object then a new link is created.
Change-Id: I38e773224d47a33158279dc7099635285493345b Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 9 +++++++++ drivers/media/media-entity.c | 9 +++++++++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 23 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 3bdda16584fe..065f6f08da37 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -438,6 +438,13 @@ 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,
/* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD,&entity->links[i].graph_obj);
@@ -465,6 +472,8 @@ void media_device_unregister_entity(struct media_entity *entity) return;
spin_lock(&mdev->lock);
- for (i = 0; i < entity->num_links; i++)
for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj);media_gobj_remove(&entity->links[i].graph_obj);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 377c6655c5d0..36d725ec5f3d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -51,6 +51,9 @@ void media_gobj_init(struct media_device *mdev, case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); break;
- case MEDIA_GRAPH_LINK:
gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
}break;
}
@@ -491,6 +494,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, link->sink = &sink->pads[sink_pad]; link->flags = flags;
- /* Initialize graph object embedded at the new link */
- media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj);
- /* Create the backlink. Backlinks are used to help graph traversal and
*/
- are not reported to userspace.
@@ -504,6 +510,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags;
- /* Initialize graph object embedded at the new link */
- media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj);
When you eventually remove the link, does the link graph object get released as well? I couldn't find that.
- link->reverse = backlink; backlink->reverse = link;
Em Mon, 12 Oct 2015 22:51:07 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:56PM -0300, Mauro Carvalho Chehab wrote:
Just like entities and pads, links also need to have unique Object IDs along a given media controller.
So, let's add a media_gobj inside it and initialize the object then a new link is created.
Change-Id: I38e773224d47a33158279dc7099635285493345b Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 9 +++++++++ drivers/media/media-entity.c | 9 +++++++++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 23 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 3bdda16584fe..065f6f08da37 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -438,6 +438,13 @@ 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,
/* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++) media_gobj_init(mdev, MEDIA_GRAPH_PAD,&entity->links[i].graph_obj);
@@ -465,6 +472,8 @@ void media_device_unregister_entity(struct media_entity *entity) return;
spin_lock(&mdev->lock);
- for (i = 0; i < entity->num_links; i++)
for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj);media_gobj_remove(&entity->links[i].graph_obj);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 377c6655c5d0..36d725ec5f3d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -51,6 +51,9 @@ void media_gobj_init(struct media_device *mdev, case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); break;
- case MEDIA_GRAPH_LINK:
gobj->id = media_gobj_gen_id(type, ++mdev->link_id);
}break;
}
@@ -491,6 +494,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, link->sink = &sink->pads[sink_pad]; link->flags = flags;
- /* Initialize graph object embedded at the new link */
- media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj);
- /* Create the backlink. Backlinks are used to help graph traversal and
*/
- are not reported to userspace.
@@ -504,6 +510,9 @@ media_entity_create_link(struct media_entity *source, u16 source_pad, backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags;
- /* Initialize graph object embedded at the new link */
- media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj);
When you eventually remove the link, does the link graph object get released as well? I couldn't find that.
Yes, it is removed. I'm pretty sure I checked it. That's btw one of the reasons why I added the debug message at media_gobj_init() and media_gobj_remove(): to check if the init and remove logic were matching.
Regards, Mauro
We can only free the media device after being sure that no graph object is used.
In order to help tracking it, let's add debug messages that will print when the media controller gets registered or unregistered.
Change-Id: Iceba1fdaa5d4dd1cde725a49a38d93cc05eac3ef Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 065f6f08da37..0f3844470147 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -359,6 +359,7 @@ static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
static void media_device_release(struct media_devnode *mdev) { + dev_dbg(mdev->parent, "Media device released\n"); }
/** @@ -397,6 +398,8 @@ int __must_check __media_device_register(struct media_device *mdev, return ret; }
+ dev_dbg(mdev->dev, "Media device registered\n"); + return 0; } EXPORT_SYMBOL_GPL(__media_device_register); @@ -416,6 +419,8 @@ void media_device_unregister(struct media_device *mdev)
device_remove_file(&mdev->devnode.dev, &dev_attr_model); media_devnode_unregister(&mdev->devnode); + + dev_dbg(mdev->dev, "Media device unregistered\n"); } EXPORT_SYMBOL_GPL(media_device_unregister);
Hi Mauro,
On Mon, Oct 12, 2015 at 01:42:57PM -0300, Mauro Carvalho Chehab wrote:
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 065f6f08da37..0f3844470147 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -359,6 +359,7 @@ static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
static void media_device_release(struct media_devnode *mdev) {
- dev_dbg(mdev->parent, "Media device released\n");
Lone variables of struct media_devnode are typically called devnode; I got confused about this. Not a big deal but I'd change it. Up to you.
It helps to check if the media controller is doing the right thing with the object creation and removal.
No extra code/data will be produced if DEBUG or CONFIG_DYNAMIC_DEBUG is not enabled.
Change-Id: I2b059347bd82e7e73772403fc93dcbfb47330f5f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-entity.c | 68 +++++++++++++++++++++++++++++++++++++++++++- include/media/media-entity.h | 7 +++++ 2 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 36d725ec5f3d..6d515e149d7f 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -27,6 +27,69 @@ #include <media/media-device.h>
/** + * dev_dbg_obj - Prints in debug mode a change on some object + * + * @event_name: Name of the event to report. Could be __func__ + * @gobj: Pointer to the object + * + * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it + * won't produce any code. + */ +static inline const char *gobj_type(enum media_gobj_type type) +{ + switch (type) { + case MEDIA_GRAPH_ENTITY: + return "entity"; + case MEDIA_GRAPH_PAD: + return "pad"; + case MEDIA_GRAPH_LINK: + return "link"; + default: + return "unknown"; + } +} + +static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) +{ +#if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG) + switch (media_type(gobj)) { + case MEDIA_GRAPH_ENTITY: + dev_dbg(gobj->mdev->dev, + "%s: id 0x%08x entity#%d: '%s'\n", + event_name, gobj->id, media_localid(gobj), + gobj_to_entity(gobj)->name); + break; + case MEDIA_GRAPH_LINK: + { + 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", + 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), + + link->sink->entity->name, + gobj_type(media_type(&link->sink->graph_obj)), + media_localid(&link->sink->graph_obj)); + break; + } + case MEDIA_GRAPH_PAD: + { + struct media_pad *pad = gobj_to_pad(gobj); + + dev_dbg(gobj->mdev->dev, + "%s: id 0x%08x pad#%d: '%s':%d\n", + event_name, gobj->id, media_localid(gobj), + pad->entity->name, pad->index); + } + } +#endif +} + +/** * media_gobj_init - Initialize a graph object * * @mdev: Pointer to the media_device that contains the object @@ -43,6 +106,8 @@ void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj) { + gobj->mdev = mdev; + /* Create a per-type unique object ID */ switch (type) { case MEDIA_GRAPH_ENTITY: @@ -55,6 +120,7 @@ void media_gobj_init(struct media_device *mdev, gobj->id = media_gobj_gen_id(type, ++mdev->link_id); break; } + dev_dbg_obj(__func__, gobj); }
/** @@ -66,7 +132,7 @@ void media_gobj_init(struct media_device *mdev, */ void media_gobj_remove(struct media_gobj *gobj) { - /* For now, nothing to do */ + dev_dbg_obj(__func__, gobj); }
/** diff --git a/include/media/media-entity.h b/include/media/media-entity.h index cd08a96bfbaa..af6646ddf6db 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -61,6 +61,7 @@ enum media_gobj_type { * All objects on the media graph should have this struct embedded */ struct media_gobj { + struct media_device *mdev; u32 id; };
@@ -192,6 +193,12 @@ struct media_entity_graph { #define gobj_to_entity(gobj) \ container_of(gobj, struct media_entity, graph_obj)
+#define gobj_to_pad(gobj) \ + container_of(gobj, struct media_pad, graph_obj) + +#define gobj_to_link(gobj) \ + container_of(gobj, struct media_link, graph_obj) + void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj);
With the new API, a link can be either between two PADs or between an interface and an entity. So, we need to use a better name for the function that create links between two pads.
So, rename the such function to media_create_pad_link().
No functional changes.
This patch was created via this shell script: for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done
Change-Id: I179ad58def3a1f4a22c1121aeb71f4bad3c8e772 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- Documentation/media-framework.txt | 2 +- drivers/media/dvb-core/dvbdev.c | 8 ++++---- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- drivers/media/i2c/s5k5baf.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 4 ++-- drivers/media/media-entity.c | 4 ++-- drivers/media/platform/exynos4-is/media-dev.c | 16 ++++++++-------- drivers/media/platform/omap3isp/isp.c | 18 +++++++++--------- drivers/media/platform/omap3isp/ispccdc.c | 2 +- drivers/media/platform/omap3isp/ispccp2.c | 2 +- drivers/media/platform/omap3isp/ispcsi2.c | 2 +- drivers/media/platform/omap3isp/isppreview.c | 4 ++-- drivers/media/platform/omap3isp/ispresizer.c | 4 ++-- drivers/media/platform/s3c-camif/camif-core.c | 4 ++-- drivers/media/platform/vsp1/vsp1_drv.c | 4 ++-- drivers/media/platform/vsp1/vsp1_rpf.c | 2 +- drivers/media/platform/vsp1/vsp1_wpf.c | 2 +- drivers/media/platform/xilinx/xilinx-vipp.c | 4 ++-- drivers/media/usb/au0828/au0828-core.c | 6 +++--- drivers/media/usb/cx231xx/cx231xx-cards.c | 6 +++--- drivers/media/usb/uvc/uvc_entity.c | 2 +- drivers/staging/media/davinci_vpfe/dm365_ipipeif.c | 2 +- drivers/staging/media/davinci_vpfe/dm365_isif.c | 2 +- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 8 ++++---- drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c | 10 +++++----- drivers/staging/media/omap4iss/iss.c | 12 ++++++------ drivers/staging/media/omap4iss/iss_csi2.c | 2 +- drivers/staging/media/omap4iss/iss_ipipeif.c | 2 +- drivers/staging/media/omap4iss/iss_resizer.c | 2 +- include/media/media-entity.h | 2 +- 30 files changed, 72 insertions(+), 72 deletions(-)
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt index 6903b2503577..b424de6c3bb3 100644 --- a/Documentation/media-framework.txt +++ b/Documentation/media-framework.txt @@ -199,7 +199,7 @@ pre-allocated and grows dynamically as needed.
Drivers create links by calling
- media_entity_create_link(struct media_entity *source, u16 source_pad, + media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags);
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 2fdcbb5f000a..65f59f2124b4 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap) }
if (tuner && fe) - media_entity_create_link(tuner, 0, fe, 0, 0); + media_create_pad_link(tuner, 0, fe, 0, 0);
if (fe && demux) - media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED); + media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
if (demux && dvr) - media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED); + media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
if (demux && ca) - media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); + media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); } EXPORT_SYMBOL_GPL(dvb_create_media_graph); #endif diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 6d167428727d..c81bfbfea32f 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd) return ret; }
- ret = media_entity_create_link(&state->sensor_sd.entity, + ret = media_create_pad_link(&state->sensor_sd.entity, S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
- ret = media_entity_create_link(&state->sensor_sd.entity, + ret = media_create_pad_link(&state->sensor_sd.entity, S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 30a9ca62e034..d3bff30bcb6f 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd) v4l2_err(sd, "failed to register subdev %s\n", state->cis_sd.name); else - ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS, + ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS, &state->sd.entity, PAD_CIS, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 308613ea0aed..5aa49eb393a9 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) return rval; }
- rval = media_entity_create_link(&this->sd.entity, + rval = media_create_pad_link(&this->sd.entity, this->source_pad, &last->sd.entity, last->sink_pad, @@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) MEDIA_LNK_FL_IMMUTABLE); if (rval) { dev_err(&client->dev, - "media_entity_create_link failed\n"); + "media_create_pad_link failed\n"); return rval; }
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 6d515e149d7f..35e52cd1fc5a 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -542,7 +542,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity) }
int -media_entity_create_link(struct media_entity *source, u16 source_pad, +media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) { struct media_link *link; @@ -586,7 +586,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
return 0; } -EXPORT_SYMBOL_GPL(media_entity_create_link); +EXPORT_SYMBOL_GPL(media_create_pad_link);
void __media_entity_remove_links(struct media_entity *entity) { diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 4f5586a4cbff..3ba76940eef5 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
sink = &fmd->fimc[i]->vid_cap.subdev.entity; - ret = media_entity_create_link(source, pad, sink, + ret = media_create_pad_link(source, pad, sink, FIMC_SD_PAD_SINK_CAM, flags); if (ret) return ret; @@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, continue;
sink = &fmd->fimc_lite[i]->subdev.entity; - ret = media_entity_create_link(source, pad, sink, + ret = media_create_pad_link(source, pad, sink, FLITE_SD_PAD_SINK, 0); if (ret) return ret; @@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd) source = &fimc->subdev.entity; sink = &fimc->ve.vdev.entity; /* FIMC-LITE's subdev and video node */ - ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA, + ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA, sink, 0, 0); if (ret) break; /* Link from FIMC-LITE to IS-ISP subdev */ sink = &fmd->fimc_is->isp.subdev.entity; - ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP, + ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP, sink, 0, 0); if (ret) break; @@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
/* Link from FIMC-IS-ISP subdev to FIMC */ sink = &fmd->fimc[i]->vid_cap.subdev.entity; - ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO, + ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO, sink, FIMC_SD_PAD_SINK_FIFO, 0); if (ret) return ret; @@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd) if (sink->num_pads == 0) return 0;
- return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA, + return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA, sink, 0, 0); }
@@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) return -EINVAL;
pad = sensor->entity.num_pads - 1; - ret = media_entity_create_link(&sensor->entity, pad, + ret = media_create_pad_link(&sensor->entity, pad, &csis->entity, CSIS_PAD_SINK, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); @@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) source = &fmd->fimc[i]->vid_cap.subdev.entity; sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
- ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, + ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE, sink, 0, flags); if (ret) break; diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index e08183f9d0f7..6351f35b0a65 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1865,7 +1865,7 @@ static int isp_link_entity( return -EINVAL; }
- return media_entity_create_link(entity, i, input, pad, flags); + return media_create_pad_link(entity, i, input, pad, flags); }
static int isp_register_entities(struct isp_device *isp) @@ -2004,51 +2004,51 @@ static int isp_initialize_modules(struct isp_device *isp) }
/* Connect the submodules. */ - ret = media_entity_create_link( + 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_entity_create_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_entity_create_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_entity_create_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_entity_create_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_entity_create_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_entity_create_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_entity_create_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); diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index d96e3be5e252..27555e4f4aa8 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc) goto error_video;
/* Connect the CCDC subdev to the video node. */ - ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, + 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; diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index e1b5f5bea541..b215eb5049d6 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2) goto error_video;
/* Connect the video node to the ccp2 subdev. */ - ret = media_entity_create_link(&ccp2->video_in.video.entity, 0, + ret = media_create_pad_link(&ccp2->video_in.video.entity, 0, &ccp2->subdev.entity, CCP2_PAD_SINK, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 6fff92f0813a..fcefc1e74881 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2) goto error_video;
/* Connect the CSI2 subdev to the video node. */ - ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, + ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, &csi2->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index b440c6342ca4..ad38d20c7770 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev) goto error_video_out;
/* Connect the video nodes to the previewer subdev. */ - ret = media_entity_create_link(&prev->video_in.video.entity, 0, + 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_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE, + ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE, &prev->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 3deb1ec4a973..b48ad4d4b834 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1756,12 +1756,12 @@ 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_entity_create_link(&res->video_in.video.entity, 0, + 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_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE, + ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE, &res->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index f47b332f0418..3e33c60be004 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif) { int i, ret;
- ret = media_entity_create_link(&camif->sensor.sd->entity, 0, + ret = media_create_pad_link(&camif->sensor.sd->entity, 0, &camif->subdev.entity, CAMIF_SD_PAD_SINK, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); @@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif) return ret;
for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) { - ret = media_entity_create_link(&camif->subdev.entity, i, + ret = media_create_pad_link(&camif->subdev.entity, i, &camif->vp[i - 1].vdev.entity, 0, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 4e61886384e3..9cd94a76a9ed 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink) if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK)) continue;
- ret = media_entity_create_link(&source->subdev.entity, + ret = media_create_pad_link(&source->subdev.entity, source->source_pad, entity, pad, flags); if (ret < 0) @@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) }
if (vsp1->pdata.features & VSP1_HAS_LIF) { - ret = media_entity_create_link( + ret = media_create_pad_link( &vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE, &vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0); if (ret < 0) diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 3294529a3108..b60a528a8fe8 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) rpf->entity.video = video;
/* Connect the video device to the RPF. */ - ret = media_entity_create_link(&rpf->video.video.entity, 0, + ret = media_create_pad_link(&rpf->video.video.entity, 0, &rpf->entity.subdev.entity, RWPF_PAD_SINK, MEDIA_LNK_FL_ENABLED | diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index 1d2b3a2f1573..d39aa4b8aea1 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0) flags |= MEDIA_LNK_FL_IMMUTABLE;
- ret = media_entity_create_link(&wpf->entity.subdev.entity, + ret = media_create_pad_link(&wpf->entity.subdev.entity, RWPF_PAD_SOURCE, &wpf->video.video.entity, 0, flags); if (ret < 0) diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index 7b7cb9c28d2c..79d4be7ce9a5 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev, local->name, local_pad->index, remote->name, remote_pad->index);
- ret = media_entity_create_link(local, local_pad->index, + ret = media_create_pad_link(local, local_pad->index, remote, remote_pad->index, link_flags); if (ret < 0) { @@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev) source->name, source_pad->index, sink->name, sink_pad->index);
- ret = media_entity_create_link(source, source_pad->index, + ret = media_create_pad_link(source, source_pad->index, sink, sink_pad->index, link_flags); if (ret < 0) { diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 0378a2c99ebb..a55eb524ea21 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -260,13 +260,13 @@ static void au0828_create_media_graph(struct au0828_dev *dev) return;
if (tuner) - media_entity_create_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, 0, decoder, 0, MEDIA_LNK_FL_ENABLED); if (dev->vdev.entity.links) - media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, + media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); if (dev->vbi_dev.entity.links) - media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, + media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED); #endif } diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 4a117a58c39a..3b5c9ae39ad3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) return;
if (tuner) - media_entity_create_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, 0, decoder, 0, MEDIA_LNK_FL_ENABLED); - media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, + media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); - media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, + media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED); #endif } diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 245445491516..429e428ccd93 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, continue;
remote_pad = remote->num_pads - 1; - ret = media_entity_create_link(source, remote_pad, + ret = media_create_pad_link(source, remote_pad, sink, i, flags); if (ret < 0) return ret; diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index 8fb676186898..d96bdaaae50e 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif, ipipeif->video_in.vpfe_dev = vpfe_dev;
flags = 0; - ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0, + ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0, &ipipeif->subdev.entity, 0, flags); if (ret < 0) goto fail; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index b1f01adfa7c8..df77288b0ec0 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif, isif->video_out.vpfe_dev = vpfe_dev; flags = 0; /* connect isif to video node */ - ret = media_entity_create_link(&isif->subdev.entity, 1, + ret = media_create_pad_link(&isif->subdev.entity, 1, &isif->video_out.video_dev.entity, 0, flags); if (ret < 0) diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index 692789aa22f4..ae942de3a23d 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1831,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer, resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
/* create link between Resizer Crop----> Resizer A*/ - ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1, + ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1, &resizer->resizer_a.subdev.entity, 0, flags); if (ret < 0) goto out_create_link;
/* create link between Resizer Crop----> Resizer B*/ - ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2, + ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2, &resizer->resizer_b.subdev.entity, 0, flags); if (ret < 0) goto out_create_link;
/* create link between Resizer A ----> video out */ - ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1, + ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1, &resizer->resizer_a.video_out.video_dev.entity, 0, flags); if (ret < 0) goto out_create_link;
/* create link between Resizer B ----> video out */ - ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1, + ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1, &resizer->resizer_b.video_out.video_dev.entity, 0, flags); if (ret < 0) goto out_create_link; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c index 57426199ad7a..08c8a5f967d3 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c @@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev) /* if entity has no pads (ex: amplifier), cant establish link */ if (vpfe_dev->sd[i]->entity.num_pads) { - ret = media_entity_create_link(&vpfe_dev->sd[i]->entity, + ret = media_create_pad_link(&vpfe_dev->sd[i]->entity, 0, &vpfe_dev->vpfe_isif.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register; }
- ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1, + ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1, &vpfe_dev->vpfe_ipipeif.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register;
- ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, + ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, &vpfe_dev->vpfe_ipipe.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register;
- ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity, + ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity, 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity, 0, flags); if (ret < 0) goto out_resizer_register;
- ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, + ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity, 0, flags); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index e54a7afd31de..7226553ceb2f 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss) goto done; }
- ret = media_entity_create_link(&sensor->entity, 0, input, pad, + ret = media_create_pad_link(&sensor->entity, 0, input, pad, flags); if (ret < 0) goto done; @@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss) }
/* Connect the submodules. */ - ret = media_entity_create_link( + ret = media_create_pad_link( &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); if (ret < 0) goto error_link;
- ret = media_entity_create_link( + ret = media_create_pad_link( &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); if (ret < 0) goto error_link;
- ret = media_entity_create_link( + ret = media_create_pad_link( &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); if (ret < 0) goto error_link;
- ret = media_entity_create_link( + ret = media_create_pad_link( &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); if (ret < 0) goto error_link;
- ret = media_entity_create_link( + ret = media_create_pad_link( &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index e936cfc218cb..6b4dcbfa9425 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) goto error_video;
/* Connect the CSI2 subdev to the video node. */ - ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, + ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, &csi2->video_out.video.entity, 0, 0); if (ret < 0) goto error_link; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index be5f80d7b5dc..44c432ef2ac5 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif) return ret;
/* Connect the IPIPEIF subdev to the video node. */ - ret = media_entity_create_link(&ipipeif->subdev.entity, + ret = media_create_pad_link(&ipipeif->subdev.entity, IPIPEIF_PAD_SOURCE_ISIF_SF, &ipipeif->video_out.video.entity, 0, 0); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index 91e724085dba..b659e465cb56 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -806,7 +806,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer) return ret;
/* Connect the RESIZER subdev to the video node. */ - ret = media_entity_create_link(&resizer->subdev.entity, + ret = media_create_pad_link(&resizer->subdev.entity, RESIZER_PAD_SOURCE_MEM, &resizer->video_out.video.entity, 0, 0); if (ret < 0) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index af6646ddf6db..e0e4b014ce62 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -208,7 +208,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity);
-int media_entity_create_link(struct media_entity *source, u16 source_pad, +int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); void media_entity_remove_links(struct media_entity *entity);
From: Javier Martinez Canillas javier@osg.samsung.com
The struct media_entity has a .parent field that stores a pointer to the parent struct media_device. But recently a media_gobj was embedded into the entities and since struct media_gojb already has a pointer to a struct media_device in the .mdev field, the .parent field becomes redundant and can be removed.
This patch replaces all the usage of .parent by .graph_obj.mdev so that field will become unused and can be removed on a later patch.
No functional changes.
The transformation was made using the following coccinelle spatch:
@@ struct media_entity *me; @@
- me->parent + me->graph_obj.mdev
@@ struct media_entity *link; @@
- link->source->entity->parent + link->source->entity->graph_obj.mdev
@@ struct exynos_video_entity *ve; @@
- ve->vdev.entity.parent + ve->vdev.entity.graph_obj.mdev
Change-Id: I7f2b87f2fe040f7a829c1bdca55d657110f2aa64 Suggested-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 8 ++--- drivers/media/media-entity.c | 34 ++++++++++++---------- drivers/media/platform/exynos4-is/fimc-isp-video.c | 6 ++-- drivers/media/platform/exynos4-is/fimc-lite.c | 8 ++--- drivers/media/platform/exynos4-is/media-dev.c | 2 +- drivers/media/platform/exynos4-is/media-dev.h | 8 ++--- drivers/media/platform/omap3isp/isp.c | 4 +-- drivers/media/platform/omap3isp/ispvideo.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/staging/media/davinci_vpfe/vpfe_video.c | 6 ++-- drivers/staging/media/omap4iss/iss.c | 4 +-- drivers/staging/media/omap4iss/iss_video.c | 2 +- 13 files changed, 45 insertions(+), 43 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0f3844470147..138b18416460 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,8 +435,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, int i;
/* Warn if we apparently re-register an entity */ - WARN_ON(entity->parent != NULL); - entity->parent = mdev; + WARN_ON(entity->graph_obj.mdev != NULL); + entity->graph_obj.mdev = mdev;
spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ @@ -471,7 +471,7 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); void media_device_unregister_entity(struct media_entity *entity) { int i; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev;
if (mdev == NULL) return; @@ -484,7 +484,7 @@ void media_device_unregister_entity(struct media_entity *entity) media_gobj_remove(&entity->graph_obj); list_del(&entity->list); spin_unlock(&mdev->lock); - entity->parent = NULL; + entity->graph_obj.mdev = NULL; } EXPORT_SYMBOL_GPL(media_device_unregister_entity);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 35e52cd1fc5a..a23c93369a04 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -332,7 +332,7 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe) { - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct media_entity_graph graph; struct media_entity *entity_err = entity; int ret; @@ -387,7 +387,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
ret = entity->ops->link_validate(link); if (ret < 0 && ret != -ENOIOCTLCMD) { - dev_dbg(entity->parent->dev, + dev_dbg(entity->graph_obj.mdev->dev, "link validation failed for "%s":%u -> "%s":%u, error %d\n", link->source->entity->name, link->source->index, @@ -401,7 +401,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
if (!bitmap_full(active, entity->num_pads)) { ret = -EPIPE; - dev_dbg(entity->parent->dev, + dev_dbg(entity->graph_obj.mdev->dev, ""%s":%u must be connected by an enabled link\n", entity->name, (unsigned)find_first_zero_bit( @@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start); */ void media_entity_pipeline_stop(struct media_entity *entity) { - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct media_entity_graph graph;
mutex_lock(&mdev->graph_mutex); @@ -490,8 +490,8 @@ struct media_entity *media_entity_get(struct media_entity *entity) if (entity == NULL) return NULL;
- if (entity->parent->dev && - !try_module_get(entity->parent->dev->driver->owner)) + if (entity->graph_obj.mdev->dev && + !try_module_get(entity->graph_obj.mdev->dev->driver->owner)) return NULL;
return entity; @@ -511,8 +511,8 @@ void media_entity_put(struct media_entity *entity) if (entity == NULL) return;
- if (entity->parent->dev) - module_put(entity->parent->dev->driver->owner); + if (entity->graph_obj.mdev->dev) + module_put(entity->graph_obj.mdev->dev->driver->owner); } EXPORT_SYMBOL_GPL(media_entity_put);
@@ -561,7 +561,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, link->flags = flags;
/* Initialize graph object embedded at the new link */ - media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj); + media_gobj_init(source->graph_obj.mdev, MEDIA_GRAPH_LINK, + &link->graph_obj);
/* Create the backlink. Backlinks are used to help graph traversal and * are not reported to userspace. @@ -577,7 +578,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->flags = flags;
/* Initialize graph object embedded at the new link */ - media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj); + media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, + &backlink->graph_obj);
link->reverse = backlink; backlink->reverse = link; @@ -629,12 +631,12 @@ EXPORT_SYMBOL_GPL(__media_entity_remove_links); void media_entity_remove_links(struct media_entity *entity) { /* Do nothing if the entity is not registered. */ - if (entity->parent == NULL) + if (entity->graph_obj.mdev == NULL) return;
- mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex); __media_entity_remove_links(entity); - mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_entity_remove_links);
@@ -703,7 +705,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) (source->stream_count || sink->stream_count)) return -EBUSY;
- mdev = source->parent; + mdev = source->graph_obj.mdev;
if (mdev->link_notify) { ret = mdev->link_notify(link, flags, @@ -724,9 +726,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags) { int ret;
- mutex_lock(&link->source->entity->parent->graph_mutex); + mutex_lock(&link->source->entity->graph_obj.mdev->graph_mutex); ret = __media_entity_setup_link(link, flags); - mutex_unlock(&link->source->entity->parent->graph_mutex); + mutex_unlock(&link->source->entity->graph_obj.mdev->graph_mutex);
return ret; } diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index b7dc5ac66e36..3d9ccbf5f10f 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -288,7 +288,7 @@ static int isp_video_open(struct file *file) goto rel_fh;
if (v4l2_fh_is_singular_file(file)) { - mutex_lock(&me->parent->graph_mutex); + mutex_lock(&me->graph_obj.mdev->graph_mutex);
ret = fimc_pipeline_call(ve, open, me, true);
@@ -296,7 +296,7 @@ static int isp_video_open(struct file *file) if (ret == 0) me->use_count++;
- mutex_unlock(&me->parent->graph_mutex); + mutex_unlock(&me->graph_obj.mdev->graph_mutex); } if (!ret) goto unlock; @@ -312,7 +312,7 @@ static int isp_video_release(struct file *file) struct fimc_isp *isp = video_drvdata(file); struct fimc_is_video *ivc = &isp->video_capture; struct media_entity *entity = &ivc->ve.vdev.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev;
mutex_lock(&isp->video_lock);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index e8f707d1729b..b2607da4ad14 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -500,7 +500,7 @@ static int fimc_lite_open(struct file *file) atomic_read(&fimc->out_path) != FIMC_IO_DMA) goto unlock;
- mutex_lock(&me->parent->graph_mutex); + mutex_lock(&me->graph_obj.mdev->graph_mutex);
ret = fimc_pipeline_call(&fimc->ve, open, me, true);
@@ -508,7 +508,7 @@ static int fimc_lite_open(struct file *file) if (ret == 0) me->use_count++;
- mutex_unlock(&me->parent->graph_mutex); + mutex_unlock(&me->graph_obj.mdev->graph_mutex);
if (!ret) { fimc_lite_clear_event_counters(fimc); @@ -541,9 +541,9 @@ static int fimc_lite_release(struct file *file) fimc_pipeline_call(&fimc->ve, close); clear_bit(ST_FLITE_IN_USE, &fimc->state);
- mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex); entity->use_count--; - mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex); }
_vb2_fop_release(file, NULL); diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 3ba76940eef5..92dbade2fffc 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1046,7 +1046,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable) return ret; }
-/* Locking: called with entity->parent->graph_mutex mutex held. */ +/* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) { struct media_entity *entity_err = entity; diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h index 03214541f149..9a69913b31cb 100644 --- a/drivers/media/platform/exynos4-is/media-dev.h +++ b/drivers/media/platform/exynos4-is/media-dev.h @@ -164,8 +164,8 @@ struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me) { - return me->parent == NULL ? NULL : - container_of(me->parent, struct fimc_md, media_dev); + return me->graph_obj.mdev == NULL ? NULL : + container_of(me->graph_obj.mdev, struct fimc_md, media_dev); }
static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n) @@ -175,12 +175,12 @@ static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
static inline void fimc_md_graph_lock(struct exynos_video_entity *ve) { - mutex_lock(&ve->vdev.entity.parent->graph_mutex); + mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex); }
static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve) { - mutex_unlock(&ve->vdev.entity.parent->graph_mutex); + mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex); }
int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 6351f35b0a65..aa13b17d19a0 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -787,7 +787,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) int change = use ? 1 : -1; int ret;
- mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex);
/* Apply use count to node. */ entity->use_count += change; @@ -798,7 +798,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) if (ret < 0) entity->use_count -= change;
- mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
return ret; } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 6c89dc40df85..4c367352b1f7 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -226,7 +226,7 @@ static int isp_video_get_graph_data(struct isp_video *video, { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct isp_video *far_end = NULL;
mutex_lock(&mdev->graph_mutex); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index debe4e539df6..1f94c1a54e00 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -409,7 +409,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe, { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; unsigned int i; int ret;
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index f7f9aa353a55..92e8116dc28f 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -181,7 +181,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, { struct media_entity_graph graph; struct media_entity *entity = &start->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; unsigned int num_inputs = 0; unsigned int num_outputs = 0;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 61a8d5beff58..92573fa852a9 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -130,7 +130,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video, static void vpfe_prepare_pipeline(struct vpfe_video_device *video) { struct media_entity *entity = &video->video_dev.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct vpfe_pipeline *pipe = &video->pipe; struct vpfe_video_device *far_end = NULL; struct media_entity_graph graph; @@ -288,7 +288,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) else entity = &pipe->inputs[0]->video_dev.entity;
- mdev = entity->parent; + mdev = entity->graph_obj.mdev; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity); while ((entity = media_entity_graph_walk_next(&graph))) { @@ -328,7 +328,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe) else entity = &pipe->inputs[0]->video_dev.entity;
- mdev = entity->parent; + mdev = entity->graph_obj.mdev; mutex_lock(&mdev->graph_mutex); media_entity_graph_walk_start(&graph, entity);
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 7226553ceb2f..40591963b42b 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -494,7 +494,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) int change = use ? 1 : -1; int ret;
- mutex_lock(&entity->parent->graph_mutex); + mutex_lock(&entity->graph_obj.mdev->graph_mutex);
/* Apply use count to node. */ entity->use_count += change; @@ -505,7 +505,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) if (ret < 0) entity->use_count -= change;
- mutex_unlock(&entity->parent->graph_mutex); + mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
return ret; } diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 25e9e7a6b99d..45a3f2d778fc 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -207,7 +207,7 @@ iss_video_far_end(struct iss_video *video) { struct media_entity_graph graph; struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->parent; + struct media_device *mdev = entity->graph_obj.mdev; struct iss_video *far_end = NULL;
mutex_lock(&mdev->graph_mutex);
From: Javier Martinez Canillas javier@osg.samsung.com
Now that the struct media_entity .parent field is unused, it can be safely removed. Since all the previous users were converted to use the .mdev field from the embedded struct media_gobj instead.
Change-Id: I807db5a5a0bf9c38cea3d5b517e2c75e23d968ce Suggested-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/media/media-entity.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e0e4b014ce62..239c4ec30ef6 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -103,7 +103,6 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; struct list_head list; - struct media_device *parent; /* Media device this entity belongs to*/ const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */
Declare the interface types that will be used by the new G_TOPOLOGY ioctl that will be defined latter on.
For now, we need those types, as they'll be used on the internal structs associated with the new media_interface graph object defined on the next patch.
Change-Id: Ie2db9d0b6487c5da70cfa522967f7b0c380d2ba5 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- include/uapi/linux/media.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 4e816be3de39..3ad3d6be293f 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -167,6 +167,27 @@ struct media_links_enum { __u32 reserved[4]; };
+/* Interface type ranges */ + +#define MEDIA_INTF_T_DVB_BASE 0x00000100 +#define MEDIA_INTF_T_V4L_BASE 0x00000200 + +/* Interface types */ + +#define MEDIA_INTF_T_DVB_FE (MEDIA_INTF_T_DVB_BASE) +#define MEDIA_INTF_T_DVB_DEMUX (MEDIA_INTF_T_DVB_BASE + 1) +#define MEDIA_INTF_T_DVB_DVR (MEDIA_INTF_T_DVB_BASE + 2) +#define MEDIA_INTF_T_DVB_CA (MEDIA_INTF_T_DVB_BASE + 3) +#define MEDIA_INTF_T_DVB_NET (MEDIA_INTF_T_DVB_BASE + 4) + +#define MEDIA_INTF_T_V4L_VIDEO (MEDIA_INTF_T_V4L_BASE) +#define MEDIA_INTF_T_V4L_VBI (MEDIA_INTF_T_V4L_BASE + 1) +#define MEDIA_INTF_T_V4L_RADIO (MEDIA_INTF_T_V4L_BASE + 2) +#define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) +#define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) + +/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */ + #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum)
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Declare the interface types that will be used by the new G_TOPOLOGY ioctl that will be defined latter on.
typo: latter -> later.
Hans
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.
Change-Id: I0c0cb096e74d829ebd342dbaa54413524ea3b2ae Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-entity.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 48 +++++++++++++++++++++++++ 3 files changed, 133 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a23c93369a04..dc679dfe8ade 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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) +{ + 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; + + 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); diff --git a/include/media/media-device.h b/include/media/media-device.h index 05414e351f8e..3b14394d5701 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -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 * @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;
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 239c4ec30ef6..7df8836f4eef 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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)
+#define gobj_to_link(gobj) \ + container_of(gobj, struct media_link, graph_obj) + +#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)
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
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.
Change-Id: I0c0cb096e74d829ebd342dbaa54413524ea3b2ae Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
Regards,
Hans
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:03PM -0300, Mauro Carvalho Chehab wrote:
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.
Change-Id: I0c0cb096e74d829ebd342dbaa54413524ea3b2ae Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-entity.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 48 +++++++++++++++++++++++++ 3 files changed, 133 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a23c93369a04..dc679dfe8ade 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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:
default: return "unknown"; }return "intf-devnode";
}
+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);
} dev_dbg_obj(__func__, gobj);break;
} @@ -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)
+{
- 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;
- 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); diff --git a/include/media/media-device.h b/include/media/media-device.h index 05414e351f8e..3b14394d5701 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -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
- @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;
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 239c4ec30ef6..7df8836f4eef 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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)
+#define gobj_to_link(gobj) \
container_of(gobj, struct media_link, graph_obj)
+#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)
I'm beginning to feel we should probably reconsider the names of the headers and what goes to which. What do you think? I'm totally fine postponing that after the patchset, though.
Do we have a to-do list of some kind btw.?
Em Thu, 29 Oct 2015 11:49:46 +0200 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:03PM -0300, Mauro Carvalho Chehab wrote:
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.
Change-Id: I0c0cb096e74d829ebd342dbaa54413524ea3b2ae Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-entity.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 48 +++++++++++++++++++++++++ 3 files changed, 133 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a23c93369a04..dc679dfe8ade 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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:
default: return "unknown"; }return "intf-devnode";
}
+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);
} dev_dbg_obj(__func__, gobj);break;
} @@ -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)
+{
- 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;
- 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); diff --git a/include/media/media-device.h b/include/media/media-device.h index 05414e351f8e..3b14394d5701 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -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
- @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;
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 239c4ec30ef6..7df8836f4eef 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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)
+#define gobj_to_link(gobj) \
container_of(gobj, struct media_link, graph_obj)
+#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)
I'm beginning to feel we should probably reconsider the names of the headers and what goes to which. What do you think? I'm totally fine postponing that after the patchset, though.
I agree: "media-entity.[ch]" actually a bad name, as it actually has functions for all graph types. Perhaps this could be renamed to "media-graph.[ch]", and maybe "media-device.[ch]" to "media-ioctl.[ch]", eventually moving some functions between those files/headers.
I would do this on some latter patch series.
Do we have a to-do list of some kind btw.?
Yes, I started writing one during version 8.3. I'm pretty sure that it is not complete.
Also, some items were already accomplished. For example, I merged Javier's patches on version 8.4. I'll double check the TODO list next week, after getting Laurent's review.
I'm enclosing what I wrote on that time.
Regards, Mauro
-----------------
TODO for next Kernel version (goal: Kernel version 4.4): =========================================================
- Add Javier's fixup patches with fixes for some platform drivers and uvc;
- Find entities that belong to V4L2 or DVB via the interfaces, in order to enable/disable the inteface links when the device gets busy;
TODO for a next versions: =========================
- Remove unused fields from media_entity (like major, minor, revision, group_id, num_links, num_backlinks, num_pads)
- dynamic entity/interface/link creation and removal;
- SETUP_LINK_V2 with dynamic support;
- dynamic pad creation and removal (needed?);
- multiple function per entity support;
- indirect interface links support;
- MC properties API.
Userspace: ==========
- Create a library with v2 API;
- Use the v2 API library on qv4l2/libdvbv5/xawtv/libv4l;
- Add the libudev/libsysfs logic at mc_nextgen_test to convert a devnode major/minor into a /dev/* name;
Other Nice things =================
- Rename media_entity_init() to media_entity_create_pads() - Rename media_graph_init() to media_graph_register()
Declare the interface types to be used on alsa for the new G_TOPOLOGY ioctl.
Change-Id: I0e8f893a64cdcc058523eea340b9edabc6b5ef33 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-entity.c | 12 ++++++++++++ include/uapi/linux/media.h | 8 ++++++++ 2 files changed, 20 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index dc679dfe8ade..27fce6224972 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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"; } diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3ad3d6be293f..aca828709bad 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -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)
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:04PM -0300, Mauro Carvalho Chehab wrote:
Declare the interface types to be used on alsa for the new G_TOPOLOGY ioctl.
Change-Id: I0e8f893a64cdcc058523eea340b9edabc6b5ef33 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-entity.c | 12 ++++++++++++ include/uapi/linux/media.h | 8 ++++++++ 2 files changed, 20 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index dc679dfe8ade..27fce6224972 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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:
default: return "unknown-intf"; }return "hwdep";
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3ad3d6be293f..aca828709bad 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -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)
Perhaps an entirely silly question, but do we have an ack for these from the ALSA folks?
I remember the last time we didn't. :-) Albeit these look more plausible this time, but back then I didn't know much ALSA either.
Em Mon, 12 Oct 2015 22:53:37 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:04PM -0300, Mauro Carvalho Chehab wrote:
Declare the interface types to be used on alsa for the new G_TOPOLOGY ioctl.
Change-Id: I0e8f893a64cdcc058523eea340b9edabc6b5ef33 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-entity.c | 12 ++++++++++++ include/uapi/linux/media.h | 8 ++++++++ 2 files changed, 20 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index dc679dfe8ade..27fce6224972 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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:
default: return "unknown-intf"; }return "hwdep";
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3ad3d6be293f..aca828709bad 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -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)
Perhaps an entirely silly question, but do we have an ack for these from the ALSA folks?
I remember the last time we didn't. :-) Albeit these look more plausible this time, but back then I didn't know much ALSA either.
No. This is at the TODO list I added at patch 00/83 ;)
I want us to first ack/review the /83 patches. After that, my idea is to apply the patches at the topic branch and ask ALSA people to review this one, together with Shuah's patch series, merging them back at "master" only after doing everything listed on patch 00/83.
Regards, Mauro
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Declare the interface types to be used on alsa for the new G_TOPOLOGY ioctl.
Change-Id: I0e8f893a64cdcc058523eea340b9edabc6b5ef33 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-entity.c | 12 ++++++++++++ include/uapi/linux/media.h | 8 ++++++++ 2 files changed, 20 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index dc679dfe8ade..27fce6224972 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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:
default: return "unknown-intf"; }return "hwdep";
Same question as Sakari: I thought the plan was to postpone adding the alsa types and add this as a separate patch series?
Anyway, for the patch:
Acked-by: Hans Verkuil hans.verkuil@cisco.com
But I really prefer this as a separate patch series, or at least something that's added at the end of this patch series instead of in the middle.
It certainly can't go in without an Ack from the alsa guys as well.
Regards,
Hans
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3ad3d6be293f..aca828709bad 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -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)
From: Javier Martinez Canillas javier@osg.samsung.com
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.
Suggested-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com
Series-to: linux-kernel@vger.kernel.org Series-cc: Mauro Carvalho Chehab mchehab@osg.samsung.com Series-cc: linux-media@vger.kernel.org Series-cc: Shuah Khan shuahkh@osg.samsung.com Series-cc: Laurent Pinchart laurent.pinchart@ideasonboard.com
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/linux-media@vger.kernel.org/msg91528.html [1]: https://lkml.org/lkml/2015/8/24/649
Best regards, Javier END
Change-Id: I44abb9b67d6378cbd54ba4e0673a5d6d5721fc77 --- 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(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index aa13b17d19a0..b8f6f81d2db2 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -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;
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 27555e4f4aa8..9a811f5741fa 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -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. */ diff --git a/drivers/media/platform/omap3isp/ispccdc.h b/drivers/media/platform/omap3isp/ispccdc.h index 3440a7097940..2128203ef6fb 100644 --- a/drivers/media/platform/omap3isp/ispccdc.h +++ b/drivers/media/platform/omap3isp/ispccdc.h @@ -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); diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index b215eb5049d6..6ec7d104ab75 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -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 */ diff --git a/drivers/media/platform/omap3isp/ispccp2.h b/drivers/media/platform/omap3isp/ispccp2.h index 4662bffa79e3..fb74bc67878b 100644 --- a/drivers/media/platform/omap3isp/ispccp2.h +++ b/drivers/media/platform/omap3isp/ispccp2.h @@ -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); diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index fcefc1e74881..0fb057a74f69 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -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) diff --git a/drivers/media/platform/omap3isp/ispcsi2.h b/drivers/media/platform/omap3isp/ispcsi2.h index 453ed62fe394..452ee239c7d7 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.h +++ b/drivers/media/platform/omap3isp/ispcsi2.h @@ -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, diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index ad38d20c7770..6986d2f65c19 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -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; diff --git a/drivers/media/platform/omap3isp/isppreview.h b/drivers/media/platform/omap3isp/isppreview.h index 16fdc03a3d43..f3593b7cecc7 100644 --- a/drivers/media/platform/omap3isp/isppreview.h +++ b/drivers/media/platform/omap3isp/isppreview.h @@ -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, diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index b48ad4d4b834..249af7f524f9 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -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; diff --git a/drivers/media/platform/omap3isp/ispresizer.h b/drivers/media/platform/omap3isp/ispresizer.h index 5414542912e2..8b9fdcdab73d 100644 --- a/drivers/media/platform/omap3isp/ispresizer.h +++ b/drivers/media/platform/omap3isp/ispresizer.h @@ -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,
From: Javier Martinez Canillas javier@osg.samsung.com
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.
Change-Id: Ieeee2da9c812906435e70109aeff4fc748ca84b8 Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/media/platform/omap3isp/isp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index b8f6f81d2db2..69e7733d36cd 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -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); }
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:06PM -0300, Mauro Carvalho Chehab wrote:
From: Javier Martinez Canillas javier@osg.samsung.com
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.
Change-Id: Ieeee2da9c812906435e70109aeff4fc748ca84b8 Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com
drivers/media/platform/omap3isp/isp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index b8f6f81d2db2..69e7733d36cd 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
/* Only try to link entities whose interface was set on bound */
if (sd->host_priv) {
bus = (struct isp_bus_cfg *)sd->host_priv;
struct isp_bus_cfg *bus = sd->host_priv;
And you can drop "bus" from the beginning of the function.
Perhaps not a big deal, but I think it's cleaner this way.
ret = isp_link_entity(isp, &sd->entity, bus->interface);
if (ret < 0)
return ret;
}
}
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
}
Em Mon, 12 Oct 2015 23:12:41 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:06PM -0300, Mauro Carvalho Chehab wrote:
From: Javier Martinez Canillas javier@osg.samsung.com
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.
Change-Id: Ieeee2da9c812906435e70109aeff4fc748ca84b8 Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com
drivers/media/platform/omap3isp/isp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index b8f6f81d2db2..69e7733d36cd 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
/* Only try to link entities whose interface was set on bound */
if (sd->host_priv) {
bus = (struct isp_bus_cfg *)sd->host_priv;
struct isp_bus_cfg *bus = sd->host_priv;
And you can drop "bus" from the beginning of the function.
Perhaps not a big deal, but I think it's cleaner this way.
I actually prefer to allocate the local vars only once at the function :)
Ok, if the compiler optimizer is good enough, this won't make any difference, but, if the optimizer is not that good, at least on archs with not many registers like x86, allocating local vars inside loops may create extra code.
ret = isp_link_entity(isp, &sd->entity, bus->interface);
if (ret < 0)
return ret;
}
}
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
}
Hi Mauro,
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote:
Em Mon, 12 Oct 2015 23:12:41 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:06PM -0300, Mauro Carvalho Chehab wrote:
From: Javier Martinez Canillas javier@osg.samsung.com
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.
Change-Id: Ieeee2da9c812906435e70109aeff4fc748ca84b8 Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com
drivers/media/platform/omap3isp/isp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index b8f6f81d2db2..69e7733d36cd 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
/* Only try to link entities whose interface was set on bound */
if (sd->host_priv) {
bus = (struct isp_bus_cfg *)sd->host_priv;
struct isp_bus_cfg *bus = sd->host_priv;
And you can drop "bus" from the beginning of the function.
Perhaps not a big deal, but I think it's cleaner this way.
I actually prefer to allocate the local vars only once at the function :)
Ok, if the compiler optimizer is good enough, this won't make any difference, but, if the optimizer is not that good, at least on archs with not many registers like x86, allocating local vars inside loops may create extra code.
I'm more worried about accidentally using the variables when they're not supposed to. I don't think there's much risk of that here though. Cc Javier.
Hello,
On 10/14/2015 12:09 PM, Sakari Ailus wrote:
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote:
Sakari Ailus sakari.ailus@iki.fi escreveu:
[snip]
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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
Yes, the local variable is not needed but usually I prefer to use a variable when two levels of indirection are needed since I think that makes the code easier to read.
I don't have a strong opinion though so I don't mind if is dropped.
/* Only try to link entities whose interface was set on bound */
if (sd->host_priv) {
bus = (struct isp_bus_cfg *)sd->host_priv;
struct isp_bus_cfg *bus = sd->host_priv;
And you can drop "bus" from the beginning of the function.
Perhaps not a big deal, but I think it's cleaner this way.
I actually prefer to allocate the local vars only once at the function :)
Ok, if the compiler optimizer is good enough, this won't make any difference, but, if the optimizer is not that good, at least on archs with not many registers like x86, allocating local vars inside loops may create extra code.
I'm more worried about accidentally using the variables when they're not supposed to. I don't think there's much risk of that here though. Cc Javier.
I thought that declaring all local variables at the beginning of the function was a convention but from a quick look at CodingStyle I found nothing so I agree with declaring the variable as locally as possible.
Best regards,
On Wed, Oct 14, 2015 at 12:56:54PM +0200, Javier Martinez Canillas wrote:
Hello,
On 10/14/2015 12:09 PM, Sakari Ailus wrote:
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote:
Sakari Ailus sakari.ailus@iki.fi escreveu:
[snip]
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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
Yes, the local variable is not needed but usually I prefer to use a variable when two levels of indirection are needed since I think that makes the code easier to read.
I don't have a strong opinion though so I don't mind if is dropped.
Later on we have:
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
At least consistency should be maintained, whichever choice we make here. :-)
Feel free to resubmit, but I can do that as well.
Hello Sakari,
On 10/14/2015 01:01 PM, Sakari Ailus wrote:
On Wed, Oct 14, 2015 at 12:56:54PM +0200, Javier Martinez Canillas wrote:
Hello,
On 10/14/2015 12:09 PM, Sakari Ailus wrote:
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote:
Sakari Ailus sakari.ailus@iki.fi escreveu:
[snip]
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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
Yes, the local variable is not needed but usually I prefer to use a variable when two levels of indirection are needed since I think that makes the code easier to read.
I don't have a strong opinion though so I don't mind if is dropped.
Later on we have:
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
At least consistency should be maintained, whichever choice we make here. :-)
That's true, sorry about that.
Feel free to resubmit, but I can do that as well.
I prefer to wait for Mauro's opinion since maybe he would prefer to have that changed on top of the series to avoid having him to do a rebase due a new version of $SUBJECT being resubmit.
Best regards,
Em Wed, 14 Oct 2015 13:07:21 +0200 Javier Martinez Canillas javier@osg.samsung.com escreveu:
Hello Sakari,
On 10/14/2015 01:01 PM, Sakari Ailus wrote:
On Wed, Oct 14, 2015 at 12:56:54PM +0200, Javier Martinez Canillas wrote:
Hello,
On 10/14/2015 12:09 PM, Sakari Ailus wrote:
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote:
Sakari Ailus sakari.ailus@iki.fi escreveu:
[snip]
> > 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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
Yes, the local variable is not needed but usually I prefer to use a variable when two levels of indirection are needed since I think that makes the code easier to read.
I don't have a strong opinion though so I don't mind if is dropped.
Later on we have:
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
At least consistency should be maintained, whichever choice we make here. :-)
That's true, sorry about that.
Feel free to resubmit, but I can do that as well.
I prefer to wait for Mauro's opinion since maybe he would prefer to have that changed on top of the series to avoid having him to do a rebase due a new version of $SUBJECT being resubmit.
I prefer a latter patch doing such cleanups.
Best regards,
Mauro Carvalho Chehab wrote:
Em Wed, 14 Oct 2015 13:07:21 +0200 Javier Martinez Canillas javier@osg.samsung.com escreveu:
Hello Sakari,
On 10/14/2015 01:01 PM, Sakari Ailus wrote:
On Wed, Oct 14, 2015 at 12:56:54PM +0200, Javier Martinez Canillas wrote:
Hello,
On 10/14/2015 12:09 PM, Sakari Ailus wrote:
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote:
Sakari Ailus sakari.ailus@iki.fi escreveu:
[snip]
>> >> 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) { > > list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) { > > And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
Yes, the local variable is not needed but usually I prefer to use a variable when two levels of indirection are needed since I think that makes the code easier to read.
I don't have a strong opinion though so I don't mind if is dropped.
Later on we have:
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
At least consistency should be maintained, whichever choice we make here. :-)
That's true, sorry about that.
Feel free to resubmit, but I can do that as well.
I prefer to wait for Mauro's opinion since maybe he would prefer to have that changed on top of the series to avoid having him to do a rebase due a new version of $SUBJECT being resubmit.
I prefer a latter patch doing such cleanups.
Well... I don't see rebasing as risky as you do so I'd simply fix the patch that would need to be fixed, but I'm ok with fixing that later once this series is eventually in. But when? Could you reply my other comments on patch 49, "uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl"?
Also, naming is one of the things that are difficult to get right, yet it is still important (patch 28, "media: add support to link interfaces and entities").
Em Thu, 15 Oct 2015 00:39:32 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Mauro Carvalho Chehab wrote:
Em Wed, 14 Oct 2015 13:07:21 +0200 Javier Martinez Canillas javier@osg.samsung.com escreveu:
Hello Sakari,
On 10/14/2015 01:01 PM, Sakari Ailus wrote:
On Wed, Oct 14, 2015 at 12:56:54PM +0200, Javier Martinez Canillas wrote:
Hello,
On 10/14/2015 12:09 PM, Sakari Ailus wrote:
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote: > Sakari Ailus sakari.ailus@iki.fi escreveu:
[snip]
>>> >>> 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) { >> >> list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) { >> >> And you can drop local v4l2_dev. > > This is Javier's patch, but I agree that this can be simplified. >
Yes, the local variable is not needed but usually I prefer to use a variable when two levels of indirection are needed since I think that makes the code easier to read.
I don't have a strong opinion though so I don't mind if is dropped.
Later on we have:
return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
At least consistency should be maintained, whichever choice we make here. :-)
That's true, sorry about that.
Feel free to resubmit, but I can do that as well.
I prefer to wait for Mauro's opinion since maybe he would prefer to have that changed on top of the series to avoid having him to do a rebase due a new version of $SUBJECT being resubmit.
I prefer a latter patch doing such cleanups.
Well... I don't see rebasing as risky as you do so I'd simply fix the patch that would need to be fixed, but I'm ok with fixing that later once this series is eventually in.
It is, specially with renames, as all patches touching the code nearby will be broken, and will require manual rework and compilation retest.
But when?
After the 83 patches, before merging at linux_tree "master" branch.
Could you reply my other comments on patch 49, "uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl"?
Just replied.
Also, naming is one of the things that are difficult to get right, yet it is still important (patch 28, "media: add support to link interfaces and entities").
Yes, no doubt that naming is important, but it is something that can be changed anytime as needed, as a rename patch won't break anything, nor change the functionality, except for patches that might be relying on it. As Shuah made some some ALSA patches on the top of this 83 patch series, we should first merge the existing stuff and then apply whatever renaming patches we think it is needed, in order to avoid uneeded rework.
Regards, Mauro
Em Wed, 14 Oct 2015 12:56:54 +0200 Javier Martinez Canillas javier@osg.samsung.com escreveu:
Hello,
On 10/14/2015 12:09 PM, Sakari Ailus wrote:
On Mon, Oct 12, 2015 at 08:52:43PM -0300, Mauro Carvalho Chehab wrote:
Sakari Ailus sakari.ailus@iki.fi escreveu:
[snip]
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) {
list_for_each_entry(sd, &isp->v4l2_dev.subdevs, list) {
And you can drop local v4l2_dev.
This is Javier's patch, but I agree that this can be simplified.
Yes, the local variable is not needed but usually I prefer to use a variable when two levels of indirection are needed since I think that makes the code easier to read.
I don't have a strong opinion though so I don't mind if is dropped.
/* Only try to link entities whose interface was set on bound */
if (sd->host_priv) {
bus = (struct isp_bus_cfg *)sd->host_priv;
struct isp_bus_cfg *bus = sd->host_priv;
And you can drop "bus" from the beginning of the function.
Perhaps not a big deal, but I think it's cleaner this way.
I actually prefer to allocate the local vars only once at the function :)
Ok, if the compiler optimizer is good enough, this won't make any difference, but, if the optimizer is not that good, at least on archs with not many registers like x86, allocating local vars inside loops may create extra code.
I'm more worried about accidentally using the variables when they're not supposed to.
I see your point but gcc (or sparse/smatch) warns when a local var is overriden by some other var. So, I don't thing we should be worried about those risks on general case, as we'll get this before sending the patches upstream, as I always run with V=1 and we also check sparse/smatch to check for such warnings.
I don't think there's much risk of that here though. Cc Javier.
Yeah, I don't see any risk on this code. So, I would prefer to create those loop vars outside the loop, to be sure that the compiler won't be doing the wrong thing.
I thought that declaring all local variables at the beginning of the function was a convention but from a quick look at CodingStyle I found nothing so I agree with declaring the variable as locally as possible.
Best regards,
From: Javier Martinez Canillas javier@osg.samsung.com
The omap4iss 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.
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/staging/media/omap4iss/iss.c | 101 ++++++++++++++++++--------- drivers/staging/media/omap4iss/iss_csi2.c | 35 +++++++--- drivers/staging/media/omap4iss/iss_csi2.h | 1 + drivers/staging/media/omap4iss/iss_ipipeif.c | 29 ++++---- drivers/staging/media/omap4iss/iss_ipipeif.h | 1 + drivers/staging/media/omap4iss/iss_resizer.c | 29 ++++---- drivers/staging/media/omap4iss/iss_resizer.h | 1 + 7 files changed, 132 insertions(+), 65 deletions(-)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 40591963b42b..8e6a375b0f6c 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -1274,6 +1274,68 @@ done: return ret; }
+/* + * iss_create_pads_links() - Pads links creation for the subdevices + * @iss : Pointer to ISS device + * + * return negative error code or zero on success + */ +static int iss_create_pads_links(struct iss_device *iss) +{ + int ret; + + ret = omap4iss_csi2_create_pads_links(iss); + if (ret < 0) { + dev_err(iss->dev, "CSI2 pads links creation failed\n"); + return ret; + } + + ret = omap4iss_ipipeif_create_pads_links(iss); + if (ret < 0) { + dev_err(iss->dev, "ISP IPIPEIF pads links creation failed\n"); + return ret; + } + + ret = omap4iss_resizer_create_pads_links(iss); + if (ret < 0) { + dev_err(iss->dev, "ISP RESIZER pads links creation failed\n"); + return ret; + } + + /* Connect the submodules. */ + ret = media_create_pad_link( + &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, + &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, + &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); + if (ret < 0) + return ret; + + ret = media_create_pad_link( + &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, + &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); + if (ret < 0) + return ret; + + return 0; +}; + static void iss_cleanup_modules(struct iss_device *iss) { omap4iss_csi2_cleanup(iss); @@ -1316,41 +1378,8 @@ static int iss_initialize_modules(struct iss_device *iss) goto error_resizer; }
- /* Connect the submodules. */ - ret = media_create_pad_link( - &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE, - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE, - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, - &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP, - &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0); - if (ret < 0) - goto error_link; - - ret = media_create_pad_link( - &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP, - &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0); - if (ret < 0) - goto error_link; - return 0;
-error_link: - omap4iss_resizer_cleanup(iss); error_resizer: omap4iss_ipipe_cleanup(iss); error_ipipe: @@ -1463,10 +1492,16 @@ static int iss_probe(struct platform_device *pdev) if (ret < 0) goto error_modules;
+ ret = iss_create_pads_links(iss); + if (ret < 0) + goto error_entities; + omap4iss_put(iss);
return 0;
+error_entities: + iss_unregister_entities(iss); error_modules: iss_cleanup_modules(iss); error_iss: diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 6b4dcbfa9425..341489864da5 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1290,16 +1290,8 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname) 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: - omap4iss_video_cleanup(&csi2->video_out); error_video: media_entity_cleanup(&csi2->subdev.entity); return ret; @@ -1342,6 +1334,33 @@ int omap4iss_csi2_init(struct iss_device *iss) }
/* + * omap4iss_csi2_create_pads_links() - CSI2 pads links creation + * @iss: Pointer to ISS device + * + * return negative error code or zero on success + */ +int omap4iss_csi2_create_pads_links(struct iss_device *iss) +{ + struct iss_csi2_device *csi2a = &iss->csi2a; + struct iss_csi2_device *csi2b = &iss->csi2b; + int ret; + + /* Connect the CSI2a subdev to the video node. */ + ret = media_create_pad_link(&csi2a->subdev.entity, CSI2_PAD_SOURCE, + &csi2a->video_out.video.entity, 0, 0); + if (ret < 0) + return ret; + + /* Connect the CSI2b subdev to the video node. */ + ret = media_create_pad_link(&csi2b->subdev.entity, CSI2_PAD_SOURCE, + &csi2b->video_out.video.entity, 0, 0); + if (ret < 0) + return ret; + + return 0; +} + +/* * omap4iss_csi2_cleanup - Routine for module driver cleanup */ void omap4iss_csi2_cleanup(struct iss_device *iss) diff --git a/drivers/staging/media/omap4iss/iss_csi2.h b/drivers/staging/media/omap4iss/iss_csi2.h index 3b37978a3bdf..ad9a02d2a576 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.h +++ b/drivers/staging/media/omap4iss/iss_csi2.h @@ -151,6 +151,7 @@ struct iss_csi2_device { void omap4iss_csi2_isr(struct iss_csi2_device *csi2); int omap4iss_csi2_reset(struct iss_csi2_device *csi2); int omap4iss_csi2_init(struct iss_device *iss); +int omap4iss_csi2_create_pads_links(struct iss_device *iss); void omap4iss_csi2_cleanup(struct iss_device *iss); void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2); int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2, diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 44c432ef2ac5..1c447cec4d3f 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -757,18 +757,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif) ipipeif->video_out.bpl_zero_padding = 1; ipipeif->video_out.bpl_max = 0x1ffe0;
- ret = omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF"); - if (ret < 0) - return ret; - - /* Connect the IPIPEIF subdev to the video node. */ - ret = media_create_pad_link(&ipipeif->subdev.entity, - IPIPEIF_PAD_SOURCE_ISIF_SF, - &ipipeif->video_out.video.entity, 0, 0); - if (ret < 0) - return ret; - - return 0; + return omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF"); }
void omap4iss_ipipeif_unregister_entities(struct iss_ipipeif_device *ipipeif) @@ -821,6 +810,22 @@ int omap4iss_ipipeif_init(struct iss_device *iss) }
/* + * omap4iss_ipipeif_create_pads_links() - IPIPEIF pads links creation + * @iss: Pointer to ISS device + * + * return negative error code or zero on success + */ +int omap4iss_ipipeif_create_pads_links(struct iss_device *iss) +{ + struct iss_ipipeif_device *ipipeif = &iss->ipipeif; + + /* Connect the IPIPEIF subdev to the video node. */ + return media_create_pad_link(&ipipeif->subdev.entity, + IPIPEIF_PAD_SOURCE_ISIF_SF, + &ipipeif->video_out.video.entity, 0, 0); +} + +/* * omap4iss_ipipeif_cleanup - IPIPEIF module cleanup. * @iss: Device pointer specific to the OMAP4 ISS. */ diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.h b/drivers/staging/media/omap4iss/iss_ipipeif.h index cbdccb982eee..28357a65ae97 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.h +++ b/drivers/staging/media/omap4iss/iss_ipipeif.h @@ -78,6 +78,7 @@ struct iss_ipipeif_device { struct iss_device;
int omap4iss_ipipeif_init(struct iss_device *iss); +int omap4iss_ipipeif_create_pads_links(struct iss_device *iss); void omap4iss_ipipeif_cleanup(struct iss_device *iss); int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif, struct v4l2_device *vdev); diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index b659e465cb56..65e4ae9c9f67 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -801,18 +801,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer) resizer->video_out.bpl_zero_padding = 1; resizer->video_out.bpl_max = 0x1ffe0;
- ret = omap4iss_video_init(&resizer->video_out, "ISP resizer a"); - if (ret < 0) - return ret; - - /* Connect the RESIZER subdev to the video node. */ - ret = media_create_pad_link(&resizer->subdev.entity, - RESIZER_PAD_SOURCE_MEM, - &resizer->video_out.video.entity, 0, 0); - if (ret < 0) - return ret; - - return 0; + return omap4iss_video_init(&resizer->video_out, "ISP resizer a"); }
void omap4iss_resizer_unregister_entities(struct iss_resizer_device *resizer) @@ -865,6 +854,22 @@ int omap4iss_resizer_init(struct iss_device *iss) }
/* + * omap4iss_resizer_create_pads_links() - RESIZER pads links creation + * @iss: Pointer to ISS device + * + * return negative error code or zero on success + */ +int omap4iss_resizer_create_pads_links(struct iss_device *iss) +{ + struct iss_resizer_device *resizer = &iss->resizer; + + /* Connect the RESIZER subdev to the video node. */ + return media_create_pad_link(&resizer->subdev.entity, + RESIZER_PAD_SOURCE_MEM, + &resizer->video_out.video.entity, 0, 0); +} + +/* * omap4iss_resizer_cleanup - RESIZER module cleanup. * @iss: Device pointer specific to the OMAP4 ISS. */ diff --git a/drivers/staging/media/omap4iss/iss_resizer.h b/drivers/staging/media/omap4iss/iss_resizer.h index 3727498b06a3..00ecc151e511 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.h +++ b/drivers/staging/media/omap4iss/iss_resizer.h @@ -61,6 +61,7 @@ struct iss_resizer_device { struct iss_device;
int omap4iss_resizer_init(struct iss_device *iss); +int omap4iss_resizer_create_pads_links(struct iss_device *iss); void omap4iss_resizer_cleanup(struct iss_device *iss); int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer, struct v4l2_device *vdev);
From: Javier Martinez Canillas javier@osg.samsung.com
The vsp1 driver creates the pads links before the media entities are registered with the media device. This doesn't work now that object IDs are used to create links so the media_device has to be set.
Move entities registration logic before pads links creation.
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/media/platform/vsp1/vsp1_drv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 9cd94a76a9ed..2aa427d3ff39 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -250,6 +250,14 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) list_add_tail(&wpf->entity.list_dev, &vsp1->entities); }
+ /* Register all subdevs. */ + list_for_each_entry(entity, &vsp1->entities, list_dev) { + ret = v4l2_device_register_subdev(&vsp1->v4l2_dev, + &entity->subdev); + if (ret < 0) + goto done; + } + /* Create links. */ list_for_each_entry(entity, &vsp1->entities, list_dev) { if (entity->type == VSP1_ENTITY_LIF || @@ -269,14 +277,6 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) return ret; }
- /* Register all subdevs. */ - list_for_each_entry(entity, &vsp1->entities, list_dev) { - ret = v4l2_device_register_subdev(&vsp1->v4l2_dev, - &entity->subdev); - if (ret < 0) - goto done; - } - ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
done:
From: Javier Martinez Canillas javier@osg.samsung.com
The vsp1 driver initializes the entities and creates the pads links before the entities are registered with the media device. This doesn't 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.
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/media/platform/vsp1/vsp1_drv.c | 14 ++++++++++-- drivers/media/platform/vsp1/vsp1_rpf.c | 29 ++++++++++++++++-------- drivers/media/platform/vsp1/vsp1_rwpf.h | 5 +++++ drivers/media/platform/vsp1/vsp1_wpf.c | 40 ++++++++++++++++++++------------- 4 files changed, 62 insertions(+), 26 deletions(-)
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index 2aa427d3ff39..8f995d267646 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -260,9 +260,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
/* Create links. */ list_for_each_entry(entity, &vsp1->entities, list_dev) { - if (entity->type == VSP1_ENTITY_LIF || - entity->type == VSP1_ENTITY_RPF) + if (entity->type == VSP1_ENTITY_LIF) { + ret = vsp1_wpf_create_pads_links(vsp1, entity); + if (ret < 0) + goto done; + continue; + } + + if (entity->type == VSP1_ENTITY_RPF) { + ret = vsp1_rpf_create_pads_links(vsp1, entity); + if (ret < 0) + goto done; continue; + }
ret = vsp1_create_links(vsp1, entity); if (ret < 0) diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index b60a528a8fe8..38aebdf691b5 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -277,18 +277,29 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
rpf->entity.video = video;
- /* Connect the video device to the RPF. */ - ret = media_create_pad_link(&rpf->video.video.entity, 0, - &rpf->entity.subdev.entity, - RWPF_PAD_SINK, - MEDIA_LNK_FL_ENABLED | - MEDIA_LNK_FL_IMMUTABLE); - if (ret < 0) - goto error; - return rpf;
error: vsp1_entity_destroy(&rpf->entity); return ERR_PTR(ret); } + +/* + * vsp1_rpf_create_pads_links_create_pads_links() - RPF pads links creation + * @vsp1: Pointer to VSP1 device + * @entity: Pointer to VSP1 entity + * + * return negative error code or zero on success + */ +int vsp1_rpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity) +{ + struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); + + /* Connect the video device to the RPF. */ + return media_create_pad_link(&rpf->video.video.entity, 0, + &rpf->entity.subdev.entity, + RWPF_PAD_SINK, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); +} diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h index f452dce1a931..6638b3587369 100644 --- a/drivers/media/platform/vsp1/vsp1_rwpf.h +++ b/drivers/media/platform/vsp1/vsp1_rwpf.h @@ -50,6 +50,11 @@ static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev) struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index);
+int vsp1_rpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity); +int vsp1_wpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity); + int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code); diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index d39aa4b8aea1..1be363e4f741 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -220,7 +220,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) struct v4l2_subdev *subdev; struct vsp1_video *video; struct vsp1_rwpf *wpf; - unsigned int flags; int ret;
wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL); @@ -276,20 +275,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) goto error;
wpf->entity.video = video; - - /* Connect the video device to the WPF. All connections are immutable - * except for the WPF0 source link if a LIF is present. - */ - flags = MEDIA_LNK_FL_ENABLED; - if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0) - flags |= MEDIA_LNK_FL_IMMUTABLE; - - ret = media_create_pad_link(&wpf->entity.subdev.entity, - RWPF_PAD_SOURCE, - &wpf->video.video.entity, 0, flags); - if (ret < 0) - goto error; - wpf->entity.sink = &wpf->video.video.entity;
return wpf; @@ -298,3 +283,28 @@ error: vsp1_entity_destroy(&wpf->entity); return ERR_PTR(ret); } + +/* + * vsp1_wpf_create_pads_links_create_pads_links() - RPF pads links creation + * @vsp1: Pointer to VSP1 device + * @entity: Pointer to VSP1 entity + * + * return negative error code or zero on success + */ +int vsp1_wpf_create_pads_links(struct vsp1_device *vsp1, + struct vsp1_entity *entity) +{ + struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev); + unsigned int flags; + + /* Connect the video device to the WPF. All connections are immutable + * except for the WPF0 source link if a LIF is present. + */ + flags = MEDIA_LNK_FL_ENABLED; + if (!(vsp1->pdata.features & VSP1_HAS_LIF) || entity->index != 0) + flags |= MEDIA_LNK_FL_IMMUTABLE; + + return media_create_pad_link(&wpf->entity.subdev.entity, + RWPF_PAD_SOURCE, + &wpf->video.video.entity, 0, flags); +}
From: Javier Martinez Canillas javier@osg.samsung.com
The uvc driver creates the pads links before the media entity is registered with the media device. This doesn't work now that obj IDs are used to create links so the media_device has to be set.
Move entities registration logic before pads links creation.
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/media/usb/uvc/uvc_entity.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c index 429e428ccd93..7f82b65b238e 100644 --- a/drivers/media/usb/uvc/uvc_entity.c +++ b/drivers/media/usb/uvc/uvc_entity.c @@ -26,6 +26,15 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, struct uvc_entity *entity) { + if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) + return 0; + + return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); +} + +static int uvc_mc_create_pads_links(struct uvc_video_chain *chain, + struct uvc_entity *entity) +{ const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; struct media_entity *sink; unsigned int i; @@ -62,10 +71,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, return ret; }
- if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) - return 0; - - return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); + return 0; }
static struct v4l2_subdev_ops uvc_subdev_ops = { @@ -124,5 +130,14 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain) } }
+ list_for_each_entry(entity, &chain->entities, chain) { + ret = uvc_mc_create_pads_links(chain, entity); + if (ret < 0) { + uvc_printk(KERN_INFO, "Failed to create pads links for " + "entity %u\n", entity->id); + return ret; + } + } + return 0; }
From: Javier Martinez Canillas javier@osg.samsung.com
The smiapp driver creates the pads links before the media entity is registered with the media device. This doesn't work now that object IDs are used to create links so the media_device has to be set.
Move entity registration logic before pads links creation.
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/media/i2c/smiapp/smiapp-core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 5aa49eb393a9..938201789ebc 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2495,23 +2495,23 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor) return rval; }
- rval = media_create_pad_link(&this->sd.entity, - this->source_pad, - &last->sd.entity, - last->sink_pad, - MEDIA_LNK_FL_ENABLED | - MEDIA_LNK_FL_IMMUTABLE); + rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, + &this->sd); if (rval) { dev_err(&client->dev, - "media_create_pad_link failed\n"); + "v4l2_device_register_subdev failed\n"); return rval; }
- rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, - &this->sd); + rval = media_create_pad_link(&this->sd.entity, + this->source_pad, + &last->sd.entity, + last->sink_pad, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); if (rval) { dev_err(&client->dev, - "v4l2_device_register_subdev failed\n"); + "media_create_pad_link failed\n"); return rval; } }
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.
Change-Id: I71ad1190cd8e4cddd96b3dc751bd2c443ea5da5f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 7 ------- drivers/media/media-entity.c | 2 ++ 2 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 138b18416460..0d85c6c28004 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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, diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 27fce6224972..0926f08be981 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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 */
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.
Change-Id: I558e8f87f200fe5f83ddaafe5560f91f0d906b63 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- 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(-)
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index c38ef1a72b4a..2d06bcff0946 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -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;
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0d85c6c28004..3e649cacfc07 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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); diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0926f08be981..d5efa0e2c88c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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;
- links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL); - if (links == NULL) - return -ENOMEM; - entity->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);
@@ -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; graph->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);
+ /** * 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)) { struct 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; }
@@ -358,12 +359,12 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
/* Has the entity already been visited? */ if (__test_and_set_bit(media_entity_id(next), graph->entities)) { - link_top(graph)++; + link_top(graph) = link_top(graph)->next; continue; }
/* Push the new entity to stack and start over. */ - link_top(graph)++; + link_top(graph) = link_top(graph)->next; stack_push(graph, next); }
@@ -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; int 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); - 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;
@@ -582,25 +582,20 @@ EXPORT_SYMBOL_GPL(media_entity_put);
static struct media_link *media_entity_add_link(struct media_entity *entity) { - if (entity->num_links >= entity->max_links) { - struct media_link *links = entity->links; - unsigned int max_links = entity->max_links + 2; - unsigned int i; - - links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL); - if (links == NULL) - return NULL; + struct media_link *link;
- for (i = 0; i < entity->num_links; i++) - links[i].reverse->reverse = &links[i]; + link = kzalloc(sizeof(*link), GFP_KERNEL); + if (link == NULL) + return NULL;
- entity->max_links = max_links; - entity->links = links; - } + list_add_tail(&link->list, &entity->links);
- return &entity->links[entity->num_links++]; + return link; }
+static void __media_entity_remove_link(struct media_entity *entity, + struct media_link *link); + int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags) @@ -629,7 +624,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, */ backlink = media_entity_add_link(sink); if (backlink == NULL) { - source->num_links--; + __media_entity_remove_link(source, link); return -ENOMEM; }
@@ -645,43 +640,51 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->reverse = link;
sink->num_backlinks++; + sink->num_links++; + source->num_links++;
return 0; } EXPORT_SYMBOL_GPL(media_create_pad_link);
-void __media_entity_remove_links(struct media_entity *entity) +static void __media_entity_remove_link(struct media_entity *entity, + struct media_link *link) { - 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; + 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++; + 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]; - - if (rlink != link->reverse) { - r++; - continue; - } + if (--remote->num_links == 0) + break;
- if (link->source->entity == entity) - remote->num_backlinks--; + /* Remove the remote link */ + list_del(&rlink->list); + kfree(rlink); + } + 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; @@ -806,11 +809,8 @@ struct media_link * media_entity_find_link(struct media_pad *source, struct media_pad *sink) { struct media_link *link; - unsigned int i; - - for (i = 0; i < source->entity->num_links; ++i) { - link = &source->entity->links[i];
+ list_for_each_entry(link, &source->entity->links, list) { if (link->source->entity == source->entity && link->source->index == source->index && link->sink->entity == sink->entity && @@ -834,11 +834,9 @@ EXPORT_SYMBOL_GPL(media_entity_find_link); */ struct media_pad *media_entity_remote_pad(struct media_pad *pad) { - unsigned int i; - - for (i = 0; i < pad->entity->num_links; i++) { - struct media_link *link = &pad->entity->links[i]; + struct media_link *link;
+ list_for_each_entry(link, &pad->entity->links, list) { if (!(link->flags & MEDIA_LNK_FL_ENABLED)) continue;
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index a55eb524ea21..7f645bcb7463 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -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 }
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 2c040056d4eb..4511e2893282 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -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) diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 8f04b125486f..e8baff4d6290 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -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) diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7df8836f4eef..7016f0619415 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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,
Registering a V4L2 sub-device includes, among other things, registering the related media entity and calling the sub-device's registered op. Since patch "media: convert links from array to list", creating a link between two pads requires registering the entity first. If the registered() op involves link creation, the link list head will not be initialised before it is used.
Resolve this by first registering the entity, then calling its registered() op.
Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com --- Hi Mauro,
You might want to add this patch before "media: Don't accept early-created links". Drivers that create links in their registered() callback will otherwise break.
I'm not extremely happy with the solution, and we might need to think how the life cycle of the graph objects and the initialisation of drivers work in detail. This would seem to fix the issue for now at least.
Regards, Sakari
drivers/media/v4l2-core/v4l2-device.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index bb58d90..66a28af 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -171,26 +171,26 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, return -ENODEV;
sd->v4l2_dev = v4l2_dev; - if (sd->internal_ops && sd->internal_ops->registered) { - err = sd->internal_ops->registered(sd); - if (err) - goto error_module; - } - /* This just returns 0 if either of the two args is NULL */ err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL); if (err) - goto error_unregister; + goto error_module;
#if defined(CONFIG_MEDIA_CONTROLLER) /* Register the entity. */ if (v4l2_dev->mdev) { err = media_device_register_entity(v4l2_dev->mdev, entity); if (err < 0) - goto error_unregister; + goto error_module; } #endif
+ if (sd->internal_ops && sd->internal_ops->registered) { + err = sd->internal_ops->registered(sd); + if (err) + goto error_unregister; + } + spin_lock(&v4l2_dev->lock); list_add_tail(&sd->list, &v4l2_dev->subdevs); spin_unlock(&v4l2_dev->lock); @@ -198,8 +198,7 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, return 0;
error_unregister: - if (sd->internal_ops && sd->internal_ops->unregistered) - sd->internal_ops->unregistered(sd); + media_device_unregister_entity(entity); error_module: if (!sd->owner_v4l2_dev) module_put(sd->owner);
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:13PM -0300, Mauro Carvalho Chehab wrote: ...
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0926f08be981..d5efa0e2c88c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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;
links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
if (links == NULL)
return -ENOMEM;
entity->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);
@@ -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;
... entity->links.next;
graph->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);
Extra newline.
/**
- 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)) {
&stack_top(graph)->links should be fine w/o the parentheses.
struct 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;
Em Mon, 12 Oct 2015 23:25:13 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:13PM -0300, Mauro Carvalho Chehab wrote: ...
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0926f08be981..d5efa0e2c88c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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;
links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
if (links == NULL)
return -ENOMEM;
entity->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);
@@ -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;
... entity->links.next;
graph->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);
Extra newline.
/**
- 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)) {
&stack_top(graph)->links should be fine w/o the parentheses.
struct 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;
Ok, will change the coding style issues above on a separate patch at the end of the series.
Regards, Mauro
Hi Mauro,
Thank you for the patch.
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.
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.
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).
Change-Id: I558e8f87f200fe5f83ddaafe5560f91f0d906b63
No need to infect mainline with gerrit nonsense :-)
Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
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]
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0d85c6c28004..3e649cacfc07 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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 ?
#include <media/media-device.h> #include <media/media-devnode.h>
[snip]
@@ -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;
...
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;
here.
/* 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);
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.
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);
Shouldn't you remove the backlinks too ? How about calling __media_entity_remove_link() to centralize the link removal code ?
- } for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0926f08be981..d5efa0e2c88c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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;
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.
entity->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);
@@ -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 ?
graph->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.
/**
- 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 !=.
struct 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]
@@ -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.
int 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);
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]
+static void __media_entity_remove_link(struct media_entity *entity,
struct media_link *link);
No forward declaration please, let's reorder functions instead.
int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags)
[snip]
-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.
{
- 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;
- 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.
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];
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() ?
list_del(&rlink->list);
kfree(rlink);
- }
And here too ?
- 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;
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 laurent.pinchart@ideasonboard.com escreveu:
Hi Mauro,
Thank you for the patch.
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.
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.
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.
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).
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.
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.
Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
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]
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0d85c6c28004..3e649cacfc07 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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.
#include <media/media-device.h> #include <media/media-devnode.h>
[snip]
@@ -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;
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"...
...
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.
here.
/* 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);
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().
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.
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.
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);
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.
- } for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0926f08be981..d5efa0e2c88c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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;
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.
entity->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);
@@ -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.
graph->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.
/**
- 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.
struct 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]
@@ -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.
int 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);
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]
+static void __media_entity_remove_link(struct media_entity *entity,
struct media_link *link);
No forward declaration please, let's reorder functions instead.
OK.
int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags)
[snip]
-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.
The idea is to distinguish the non-lock protected function from the protected ones: all non-locked functions are called with the __ prefix.
In this specific case, at least for now, we don't have, for now, any usage for a lock-protected media_entity_remove_link() because we only remove links when either removing entities or calling the lock-protected media_entity_remove_links().
Yet, as soon as we start using dynamic link removal, we'll need a locked version of it. So, I think we should keep it named as-is.
{
- 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;
- 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.
OK.
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];
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() ?
Yes, and I'm pretty sure it was called on some earlier version... My guess is that some rebase was badly solved and the call for media_gobj_remove() got lot on some rebase.
I'll re-add it.
list_del(&rlink->list);
kfree(rlink);
- }
And here too ?
Yes. I'll call it.
- 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;
Em Mon, 23 Nov 2015 13:26:30 -0200 Mauro Carvalho Chehab mchehab@osg.samsung.com escreveu:
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0d85c6c28004..3e649cacfc07 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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.
Done. Will send the patch.
@@ -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;
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"...
...
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.
Done. Will send the patch.
here.
/* 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);
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().
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.
I remembered the reason. The problem here is that, despite media_entity_init() name, what this function actually does is to create the PAD objects. If an entity doesn't have any PAD, this function doesn't need to be called. There is at least one place where this function is not called.
What I propose here is to rename this function to media_entity_register_pads() in order to better reflect what the function actually does.
I'm sending such patch.
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.
This was addressed during the final rebase.
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);
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.
This was addressed during the final rebase.
- } for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0926f08be981..d5efa0e2c88c 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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;
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.
Fixed. I moved the media-framework.txt to kerneldoc and fixed it to reflect the current status of the media controller.
I'll send the patches for it too.
entity->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);
@@ -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.
I asked Javier to do this change.
graph->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.
Done on a separate patch.
/**
- 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.
Javier will handle this one too.
struct 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]
@@ -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.
In this specific case, I would keep it here, as link is used by the entire routine. Doing it inside the loop would cause it to be realocated every time. Also, it would conflict with Sakari changes to this part of the code.
So, better to keep it as-is, IMHO.
int 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);
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]
+static void __media_entity_remove_link(struct media_entity *entity,
struct media_link *link);
No forward declaration please, let's reorder functions instead.
OK.
Done.
int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags)
[snip]
-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.
The idea is to distinguish the non-lock protected function from the protected ones: all non-locked functions are called with the __ prefix.
In this specific case, at least for now, we don't have, for now, any usage for a lock-protected media_entity_remove_link() because we only remove links when either removing entities or calling the lock-protected media_entity_remove_links().
Yet, as soon as we start using dynamic link removal, we'll need a locked version of it. So, I think we should keep it named as-is.
We ended by needing this at media_device_entity_unregister(). So, I actually exported this function.
{
- 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;
- 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.
OK.
Done.
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];
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() ?
Yes, and I'm pretty sure it was called on some earlier version... My guess is that some rebase was badly solved and the call for media_gobj_remove() got lot on some rebase.
I'll re-add it.
This got fixed during the final rebase.
list_del(&rlink->list);
kfree(rlink);
- }
And here too ?
Yes. I'll call it.
And here too.
- 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;
Thanks, Mauro
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.
Change-Id: Id45ec9ac5e919bd7554446eacc19d90d9640fa89 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-entity.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index d5efa0e2c88c..625b505e8496 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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;
By 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.
Change-Id: I7adc5808141d301f56f411b8ced2c059c8637465 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- include/media/media-entity.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7016f0619415..6015e996f213 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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 */
Remove entity name from the link as this exists only if the object type is PAD on both link ends.
Change-Id: Id4a9063980accf6114dd1bdfac681f728352343d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-entity.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 625b505e8496..f9c6c2a81903 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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:
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.
Change-Id: I3f46789a764b113c8acca7f0c87ef0eb6a0f265d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-entity.c | 38 ++++++++++++++++++++++++++++++++++++++ include/media/media-entity.h | 9 +++++++++ 2 files changed, 47 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f9c6c2a81903..8e17272936c9 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 6015e996f213..f67c01419268 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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)
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:17PM -0300, Mauro Carvalho Chehab wrote:
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.
Change-Id: I3f46789a764b113c8acca7f0c87ef0eb6a0f265d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-entity.c | 38 ++++++++++++++++++++++++++++++++++++++ include/media/media-entity.h | 9 +++++++++ 2 files changed, 47 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f9c6c2a81903..8e17272936c9 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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);
+}
I think create and remove do not match well as a function pair performing the opposite operations. Instead, I'd use one of these:
- create / destroy - init / cleanup - register / unregister etc.
Interface is often shortened as "iface", I think I'd favour that instead. Up to you.
+EXPORT_SYMBOL_GPL(media_remove_intf_link); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 6015e996f213..f67c01419268 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -78,10 +78,12 @@ struct media_link { union { struct media_gobj *gobj0; struct media_pad *source;
}; union { struct media_gobj *gobj1; struct media_pad *sink;struct media_interface *intf;
}; struct media_link *reverse; /* Link in the reverse direction */ unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */struct media_entity *entity;
@@ -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)
Em Tue, 13 Oct 2015 01:33:03 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:17PM -0300, Mauro Carvalho Chehab wrote:
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.
Change-Id: I3f46789a764b113c8acca7f0c87ef0eb6a0f265d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-entity.c | 38 ++++++++++++++++++++++++++++++++++++++ include/media/media-entity.h | 9 +++++++++ 2 files changed, 47 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f9c6c2a81903..8e17272936c9 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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);
+}
I think create and remove do not match well as a function pair performing the opposite operations. Instead, I'd use one of these:
- create / destroy
I always used remove as the opposite of create. Yet, a grep at include tells something:
$ git grep _create include|wc -l 810 $ git grep _remove include|wc -l 509 $ git grep _destroy include|wc -l 432
It seems that most of the places use create/remove, yet, some places prefer create/destroy. So, I guess it is more a matter of personal taste.
Yet, at least on media, create/remove seems to be a lot more frequent:
$ git grep _remove drivers/media/|wc -l 732 $ git grep _destroy drivers/media/|wc -l 107
(this was measured without the MC next gen patches)
So, I prefer using create/remove on media, since it is used more than destroy.
- init / cleanup
- register / unregister
etc.
Interface is often shortened as "iface", I think I'd favour that instead. Up to you.
Intf is also used as a shortcut. Several drivers use it. I opted to use "intf". Actually, there are more occurrences of "intf" than "iface" at the media subsystem ;)
+EXPORT_SYMBOL_GPL(media_remove_intf_link); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 6015e996f213..f67c01419268 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -78,10 +78,12 @@ struct media_link { union { struct media_gobj *gobj0; struct media_pad *source;
}; union { struct media_gobj *gobj1; struct media_pad *sink;struct media_interface *intf;
}; struct media_link *reverse; /* Link in the reverse direction */ unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */struct media_entity *entity;
@@ -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)
Hi Mauro,
On Tue, Oct 13, 2015 at 08:04:27AM -0300, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 01:33:03 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:17PM -0300, Mauro Carvalho Chehab wrote:
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.
Change-Id: I3f46789a764b113c8acca7f0c87ef0eb6a0f265d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-entity.c | 38 ++++++++++++++++++++++++++++++++++++++ include/media/media-entity.h | 9 +++++++++ 2 files changed, 47 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f9c6c2a81903..8e17272936c9 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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);
+}
I think create and remove do not match well as a function pair performing the opposite operations. Instead, I'd use one of these:
- create / destroy
I always used remove as the opposite of create. Yet, a grep at include tells something:
$ git grep _create include|wc -l 810 $ git grep _remove include|wc -l 509 $ git grep _destroy include|wc -l 432
That doesn't yet tell whether they're even in the same files, or even then, related at all. They could be comments as well.
$Â git grep add include |wc -l 12803
Looking at files that have functions endign with the suggested pairs of names:
$ git grep -l remove( include |xargs grep add( |wc -l 61 $ git grep -l create( include |xargs grep destroy( |wc -l 69 $ git grep -l init( include |xargs grep cleanup( |wc -l 87 $ git grep -l register( include |xargs grep unregister( |wc -l 294 $ git grep -l create( include |xargs grep remove( |wc -l 33
Of the last, I can find only these function pairs. Others are clearly unrelated.
pm_clk_create and pm_clk_remove, wakeup_source_create and wakeup_source_remove, proc_create and proc_remove, p9_client_create and p9_client_remove, cfcnfg_create and cfcnfg_remove, ore_create and ore_remove and snd_ctl_create and snd_ctl_remove
A closer look reveals that wakeup_source_remove() isn't actually related to wakeup_source_create() but wakeup_source_add() instead. Same for p9_client_create(): the opposite operation is p9_client_destroy(), not p9_client_remove(). pm_clk_create() is also related to pm_clk_destroy(), not pm_clk_remove(). Same for snd_ctl_create() and snd_ctl_remove(): they're not each others counter-operations.
So that leaves us with cfcnfg_create() and ore_create(). These are not exactly core kernel APIs. On the other hand, counterexamples are plentiful: I came up with more of those even when not looking for them.
It seems that most of the places use create/remove, yet, some places prefer create/destroy. So, I guess it is more a matter of personal taste.
Yet, at least on media, create/remove seems to be a lot more frequent:
$ git grep _remove drivers/media/|wc -l 732 $ git grep _destroy drivers/media/|wc -l 107
(this was measured without the MC next gen patches)
So, I prefer using create/remove on media, since it is used more than destroy.
- init / cleanup
- register / unregister
etc.
Interface is often shortened as "iface", I think I'd favour that instead. Up to you.
Intf is also used as a shortcut. Several drivers use it. I opted to use "intf". Actually, there are more occurrences of "intf" than "iface" at the media subsystem ;)
Ok.
On Wed, Oct 14, 2015 at 01:02:08PM +0300, Sakari Ailus wrote:
So that leaves us with cfcnfg_create() and ore_create(). These are not
Forgot proc_create() and proc_remove(). That doesn't change the picture much though.
Em Wed, 14 Oct 2015 13:06:55 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
On Wed, Oct 14, 2015 at 01:02:08PM +0300, Sakari Ailus wrote:
So that leaves us with cfcnfg_create() and ore_create(). These are not
Forgot proc_create() and proc_remove(). That doesn't change the picture much though.
Ok, you convinced me ;)
We can add a patch at the end of the series changing the kABI to create/destroy.
Could you do it, or do you prefer if I do?
Regards, Mauro
Hi Mauro,
On Wed, Oct 14, 2015 at 06:39:14PM -0300, Mauro Carvalho Chehab wrote:
Em Wed, 14 Oct 2015 13:06:55 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
On Wed, Oct 14, 2015 at 01:02:08PM +0300, Sakari Ailus wrote:
So that leaves us with cfcnfg_create() and ore_create(). These are not
Forgot proc_create() and proc_remove(). That doesn't change the picture much though.
Ok, you convinced me ;)
We can add a patch at the end of the series changing the kABI to create/destroy.
Could you do it, or do you prefer if I do?
I'm fine with either. I think we should start maintaining a todo list. Such as this one:
mc-v2-todo @ etherpad.fr
I don't post a link as it could be misused. I added the items I could gather there. Let's add a note if someone starts working on them.
Em Thu, 29 Oct 2015 23:46:37 +0200 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Wed, Oct 14, 2015 at 06:39:14PM -0300, Mauro Carvalho Chehab wrote:
Em Wed, 14 Oct 2015 13:06:55 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
On Wed, Oct 14, 2015 at 01:02:08PM +0300, Sakari Ailus wrote:
So that leaves us with cfcnfg_create() and ore_create(). These are not
Forgot proc_create() and proc_remove(). That doesn't change the picture much though.
Ok, you convinced me ;)
We can add a patch at the end of the series changing the kABI to create/destroy.
Could you do it, or do you prefer if I do?
I'm fine with either. I think we should start maintaining a todo list. Such as this one:
mc-v2-todo @ etherpad.fr
I don't post a link as it could be misused. I added the items I could gather there. Let's add a note if someone starts working on them.
I added the items on TODO list there too at the above etherpad.
Regards, Mauro
As we'll be adding other interface types in the future, put the common interface create code on a separate function.
Change-Id: I938594c93baa5e27903ddae45cbc7856b61d8b09 Suggested-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-entity.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 8e17272936c9..74aaa5a5d5bc 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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; }
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
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.
Change-Id: Ia725820f725139a033aabe7a7428b1bfd531d50f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/dvb-core/dvbdev.c | 102 ++++++++++++++++++++++++++++++---------- drivers/media/dvb-core/dvbdev.h | 1 + 2 files changed, 79 insertions(+), 24 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 65f59f2124b4..6bf61d42c017 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -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) { diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index c61a4f03a66f..5f37b4dd1e69 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -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
The media device should list the interface objects, so add a linked list for those interfaces in struct media_device.
Change-Id: Ic376b74756a2199c98137c7ab8cc1fc50b65f665 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 1 + drivers/media/media-entity.c | 3 +++ include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 4 files changed, 9 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 3e649cacfc07..659507bce63f 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 74aaa5a5d5bc..d8038a53f945 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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); diff --git a/include/media/media-device.h b/include/media/media-device.h index 3b14394d5701..51807efa505b 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -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; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f67c01419268..4e36b1f2b2d7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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;
Some interfaces indirectly control multiple entities. Add support for those.
Change-Id: I31f658c2331bdb420e25d2d165d2b4a3d09cc1ca Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/dvb-core/dvbdev.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 6bf61d42c017..ada0738d26f2 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -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,16 @@ 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
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.
Change-Id: Iae655d57621ba596080590c4c173866696c6bbf6 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 26 +++++++------- include/uapi/linux/media.h | 76 ++++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 32 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index ada0738d26f2..dadcf1655070 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -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); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index aca828709bad..f8725b881a1d 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,31 +42,69 @@ struct media_device_info {
#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
+/* + * 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 0x00000000 +#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, + * in the case of having some userspace application using the old + * symbols. + */ +#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) +#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) + +/* 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 + 1) +#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) +#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) +#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) +#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) + +/* 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) - -/* 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) +#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) + +/* Entity types */
#define MEDIA_ENT_FL_DEFAULT (1 << 0)
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
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.
Change-Id: Iae655d57621ba596080590c4c173866696c6bbf6 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
Hans
drivers/media/dvb-core/dvbdev.c | 26 +++++++------- include/uapi/linux/media.h | 76 ++++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 32 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index ada0738d26f2..dadcf1655070 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -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->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_DVB_DEMOD;
dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_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_DVB_DEMUX;
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;dvbdev->entity->type = MEDIA_ENT_T_DVB_CA;
@@ -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);
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index aca828709bad..f8725b881a1d 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,31 +42,69 @@ struct media_device_info {
#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
+/*
- 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 0x00000000 +#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,
* in the case of having some userspace application using the old
* symbols.
*/
+#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) +#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6)
+/* 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 + 1) +#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) +#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) +#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) +#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5)
+/* 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)
-/* 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) +#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4)
+/* Entity types */
#define MEDIA_ENT_FL_DEFAULT (1 << 0)
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; done
Change-Id: I9b33f706081d67831738ed737760a9a5b2f4be2f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 5872f8bbf774..910243d4edb8 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -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> diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 92e8116dc28f..88cd789cdaf7 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -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)); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 71a1b93b0790..44b330589787 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -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; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 83615b8fb46a..e6e1115d8215 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -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);
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
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; done
Change-Id: I9b33f706081d67831738ed737760a9a5b2f4be2f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml | 2 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 5872f8bbf774..910243d4edb8 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -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>
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 92e8116dc28f..88cd789cdaf7 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -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));
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 71a1b93b0790..44b330589787 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -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.name = vdev->name; vdev->entity.info.dev.major = VIDEO_MAJOR; vdev->entity.info.dev.minor = vdev->minor;vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 83615b8fb46a..e6e1115d8215 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -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);
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; done
Change-Id: I6d00b69cfbfff02c18272ba015239e0daf7e372a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 910243d4edb8..32a783635649 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -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>
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).
Change-Id: If78207d9dc129f8612c63207d081c880c2838c21 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/media/media-entity.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4e36b1f2b2d7..220864319d21 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:25PM -0300, Mauro Carvalho Chehab wrote:
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).
Change-Id: If78207d9dc129f8612c63207d081c880c2838c21 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
include/media/media-entity.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4e36b1f2b2d7..220864319d21 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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:
Please apply the patch "media: Correctly determine whether an entity is a sub-device" I sent you after this one, or merge with this.
return true;
- default:
return false;
- }
+}
#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64
Em Mon, 12 Oct 2015 23:49:32 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:25PM -0300, Mauro Carvalho Chehab wrote:
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).
Change-Id: If78207d9dc129f8612c63207d081c880c2838c21 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
include/media/media-entity.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4e36b1f2b2d7..220864319d21 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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:
Please apply the patch "media: Correctly determine whether an entity is a sub-device" I sent you after this one, or merge with this.
OK.
Regards, Mauro
return true;
- default:
return false;
- }
+}
#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
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).
Change-Id: If78207d9dc129f8612c63207d081c880c2838c21 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
include/media/media-entity.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4e36b1f2b2d7..220864319d21 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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
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_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.
Change-Id: Ic4471975dddcd960e87919931a50f0ddee76c86a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/platform/exynos4-is/common.c | 3 +-- drivers/media/platform/exynos4-is/fimc-capture.c | 5 ++--- drivers/media/platform/exynos4-is/fimc-isp-video.c | 3 +-- drivers/media/platform/exynos4-is/fimc-lite.c | 10 ++++------ drivers/media/platform/exynos4-is/media-dev.c | 7 +++---- drivers/media/platform/omap3isp/isp.c | 14 ++++++-------- drivers/media/platform/omap3isp/ispvideo.c | 7 +++---- drivers/media/platform/s3c-camif/camif-capture.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 9 ++++----- drivers/media/platform/xilinx/xilinx-dma.c | 6 ++---- drivers/media/v4l2-core/v4l2-subdev.c | 2 +- drivers/staging/media/davinci_vpfe/vpfe_video.c | 6 +++--- drivers/staging/media/omap4iss/iss.c | 14 ++++++-------- drivers/staging/media/omap4iss/iss_video.c | 5 ++--- 14 files changed, 39 insertions(+), 54 deletions(-)
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c index 0eb34ecb8ee4..8c9a29e0e294 100644 --- a/drivers/media/platform/exynos4-is/common.c +++ b/drivers/media/platform/exynos4-is/common.c @@ -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); diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 0627a93b2f3b..e9810fee4c30 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -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)) diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 3d9ccbf5f10f..5fbaf5e39903 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -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); diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index b2607da4ad14..c2327147b360 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -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; diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 92dbade2fffc..4a25df9dd869 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -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); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 69e7733d36cd..cb8ac90086c1 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -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; diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 4c367352b1f7..52843ac2a9ca 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -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); diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index eae667eab1b9..fb5b016cc0a1 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -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; diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 1f94c1a54e00..f74158224b93 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -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)); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 88cd789cdaf7..8e14841bf445 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -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; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index e6e1115d8215..60da43772de9 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -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);
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 92573fa852a9..16763e0831f2 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -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); diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 8e6a375b0f6c..076ddd412201 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -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; diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 45a3f2d778fc..cbe5783735dc 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -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));
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:26PM -0300, Mauro Carvalho Chehab wrote:
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 92573fa852a9..16763e0831f2 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -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)
far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)if ((!is_media_entity_v4l2_io(remote->entity)) continue;
@@ -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))
On average you have the parentheses right, but I'd balance the two above snippets a bit more. (Neither compiles now.)
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)
subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 0);if (!is_media_entity_v4l2_subdev(entity)) continue;
Em Tue, 13 Oct 2015 01:18:36 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:26PM -0300, Mauro Carvalho Chehab wrote:
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 92573fa852a9..16763e0831f2 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -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)
far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)if ((!is_media_entity_v4l2_io(remote->entity)) continue;
@@ -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))
On average you have the parentheses right, but I'd balance the two above snippets a bit more. (Neither compiles now.)
Weird... I'm pretty sure I fixed this... Perhaps the fix got lost on some rebase....
That's basically why I really rate to rebase too long patch series.
I'll fix it.
Regards, Mauro
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)
subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 0);if (!is_media_entity_v4l2_subdev(entity)) continue;
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
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_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.
Change-Id: Ic4471975dddcd960e87919931a50f0ddee76c86a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/platform/exynos4-is/common.c | 3 +-- drivers/media/platform/exynos4-is/fimc-capture.c | 5 ++--- drivers/media/platform/exynos4-is/fimc-isp-video.c | 3 +-- drivers/media/platform/exynos4-is/fimc-lite.c | 10 ++++------ drivers/media/platform/exynos4-is/media-dev.c | 7 +++---- drivers/media/platform/omap3isp/isp.c | 14 ++++++-------- drivers/media/platform/omap3isp/ispvideo.c | 7 +++---- drivers/media/platform/s3c-camif/camif-capture.c | 2 +- drivers/media/platform/vsp1/vsp1_video.c | 9 ++++----- drivers/media/platform/xilinx/xilinx-dma.c | 6 ++---- drivers/media/v4l2-core/v4l2-subdev.c | 2 +- drivers/staging/media/davinci_vpfe/vpfe_video.c | 6 +++--- drivers/staging/media/omap4iss/iss.c | 14 ++++++-------- drivers/staging/media/omap4iss/iss_video.c | 5 ++--- 14 files changed, 39 insertions(+), 54 deletions(-)
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c index 0eb34ecb8ee4..8c9a29e0e294 100644 --- a/drivers/media/platform/exynos4-is/common.c +++ b/drivers/media/platform/exynos4-is/common.c @@ -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);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 0627a93b2f3b..e9810fee4c30 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -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))
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 3d9ccbf5f10f..5fbaf5e39903 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -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);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index b2607da4ad14..c2327147b360 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -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 ret = -EINVAL;else if (is_media_entity_v4l2_io(remote->entity)) atomic_set(&fimc->out_path, FIMC_IO_DMA);
@@ -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 ret = -EINVAL;else if (is_media_entity_v4l2_subdev(remote->entity)) atomic_set(&fimc->out_path, FIMC_IO_ISP);
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 92dbade2fffc..4a25df9dd869 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -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)
sd = media_entity_to_v4l2_subdev(pad->entity);if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break;
@@ -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);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 69e7733d36cd..cb8ac90086c1 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -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;
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 4c367352b1f7..52843ac2a9ca 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -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);
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index eae667eab1b9..fb5b016cc0a1 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -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;
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 1f94c1a54e00..f74158224b93 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -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));
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 88cd789cdaf7..8e14841bf445 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -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;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index e6e1115d8215..60da43772de9 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -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);
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 92573fa852a9..16763e0831f2 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -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)
far_end = to_vpfe_video(media_entity_to_video_device(entity)); if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)if ((!is_media_entity_v4l2_io(remote->entity)) continue;
@@ -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)
subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 1);if !is_media_entity_v4l2_subdev(entity)) continue;
After fixing the parenthesis bug (as mentioned by Sakari) you can add my:
Acked-by: Hans Verkuil hans.verkuil@cisco.com
Regards,
Hans
@@ -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)
subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 0);if (!is_media_entity_v4l2_subdev(entity)) continue;
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 8e6a375b0f6c..076ddd412201 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -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;
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 45a3f2d778fc..cbe5783735dc 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -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));
On omap3/omap4/davinci drivers, MEDIA_ENT_T_V4L2_SUBDEV macro is abused in order to "simplify" the pad checks.
Basically, it does a logical or of this macro, in order to check for a local index and if the entity is either a subdev or not.
As we'll get rid of MEDIA_ENT_T_V4L2_SUBDEV macro, replace it by 2 << 16 where it occurs, and add a note saying that the code there is actually a hack.
Change-Id: I749cea510c8d2a85d1ed11dd8640c5bcee0a5425 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/platform/omap3isp/ispccdc.c | 15 ++++++++----- drivers/media/platform/omap3isp/ispccp2.c | 13 +++++++---- drivers/media/platform/omap3isp/ispcsi2.c | 11 +++++++--- drivers/media/platform/omap3isp/isppreview.c | 15 ++++++++----- drivers/media/platform/omap3isp/ispresizer.c | 13 +++++++---- drivers/staging/media/davinci_vpfe/dm365_ipipeif.c | 13 +++++++---- drivers/staging/media/davinci_vpfe/dm365_isif.c | 13 +++++++---- drivers/staging/media/davinci_vpfe/dm365_resizer.c | 25 +++++++++++++--------- drivers/staging/media/davinci_vpfe/vpfe_video.c | 4 ++-- drivers/staging/media/omap4iss/iss_csi2.c | 11 +++++++--- drivers/staging/media/omap4iss/iss_ipipeif.c | 13 +++++++---- drivers/staging/media/omap4iss/iss_resizer.c | 11 +++++++--- 12 files changed, 106 insertions(+), 51 deletions(-)
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 9a811f5741fa..f0e530c98188 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2513,9 +2513,14 @@ static int ccdc_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); struct isp_device *isp = to_isp_device(ccdc); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case CCDC_PAD_SINK | 2 << 16: /* Read from the sensor (parallel interface), CCP2, CSI2a or * CSI2c. */ @@ -2543,7 +2548,7 @@ static int ccdc_link_setup(struct media_entity *entity, * Revisit this when it will be implemented, and return -EBUSY for now. */
- case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: + case CCDC_PAD_SOURCE_VP | 2 << 16: /* Write to preview engine, histogram and H3A. When none of * those links are active, the video port can be disabled. */ @@ -2556,7 +2561,7 @@ static int ccdc_link_setup(struct media_entity *entity, } break;
- case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE: + case CCDC_PAD_SOURCE_OF: /* Write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccdc->output & ~CCDC_OUTPUT_MEMORY) @@ -2567,7 +2572,7 @@ static int ccdc_link_setup(struct media_entity *entity, } break;
- case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV: + case CCDC_PAD_SOURCE_OF | 2 << 16: /* Write to resizer */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccdc->output & ~CCDC_OUTPUT_RESIZER) diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index 6ec7d104ab75..ae3038e643cc 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -956,9 +956,14 @@ static int ccp2_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case CCP2_PAD_SINK: /* read from memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccp2->input == CCP2_INPUT_SENSOR) @@ -970,7 +975,7 @@ static int ccp2_link_setup(struct media_entity *entity, } break;
- case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case CCP2_PAD_SINK | 2 << 16: /* read from sensor/phy */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ccp2->input == CCP2_INPUT_MEMORY) @@ -981,7 +986,7 @@ static int ccp2_link_setup(struct media_entity *entity, ccp2->input = CCP2_INPUT_NONE; } break;
- case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case CCP2_PAD_SOURCE | 2 << 16: /* write to video port/ccdc */ if (flags & MEDIA_LNK_FL_ENABLED) ccp2->output = CCP2_OUTPUT_CCDC; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 0fb057a74f69..b1617f7efdee 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1144,14 +1144,19 @@ static int csi2_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl; + int index = local->index;
/* * The ISP core doesn't support pipelines with multiple video outputs. * Revisit this when it will be implemented, and return -EBUSY for now. */
- switch (local->index | media_entity_type(remote->entity)) { - case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case CSI2_PAD_SOURCE: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_MEMORY) return -EBUSY; @@ -1161,7 +1166,7 @@ static int csi2_link_setup(struct media_entity *entity, } break;
- case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case CSI2_PAD_SOURCE | 2 << 16: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_CCDC) return -EBUSY; diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 6986d2f65c19..cfb2debb02bf 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2144,9 +2144,14 @@ static int preview_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_prev_device *prev = v4l2_get_subdevdata(sd); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case PREV_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case PREV_PAD_SINK: /* read from memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->input == PREVIEW_INPUT_CCDC) @@ -2158,7 +2163,7 @@ static int preview_link_setup(struct media_entity *entity, } break;
- case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case PREV_PAD_SINK | 2 << 16: /* read from ccdc */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->input == PREVIEW_INPUT_MEMORY) @@ -2175,7 +2180,7 @@ static int preview_link_setup(struct media_entity *entity, * Revisit this when it will be implemented, and return -EBUSY for now. */
- case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case PREV_PAD_SOURCE: /* write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->output & ~PREVIEW_OUTPUT_MEMORY) @@ -2186,7 +2191,7 @@ static int preview_link_setup(struct media_entity *entity, } break;
- case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case PREV_PAD_SOURCE | 2 << 16: /* write to resizer */ if (flags & MEDIA_LNK_FL_ENABLED) { if (prev->output & ~PREVIEW_OUTPUT_RESIZER) diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 249af7f524f9..e3ecf1787fc4 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1623,9 +1623,14 @@ static int resizer_link_setup(struct media_entity *entity, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct isp_res_device *res = v4l2_get_subdevdata(sd); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case RESZ_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case RESZ_PAD_SINK: /* read from memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (res->input == RESIZER_INPUT_VP) @@ -1637,7 +1642,7 @@ static int resizer_link_setup(struct media_entity *entity, } break;
- case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case RESZ_PAD_SINK | 2 << 16: /* read from ccdc or previewer */ if (flags & MEDIA_LNK_FL_ENABLED) { if (res->input == RESIZER_INPUT_MEMORY) @@ -1649,7 +1654,7 @@ static int resizer_link_setup(struct media_entity *entity, } break;
- case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case RESZ_PAD_SOURCE: /* resizer always write to memory */ break;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c index d96bdaaae50e..b66584ecb693 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c @@ -885,9 +885,14 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct vpfe_device *vpfe = to_vpfe_device(ipipeif); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case IPIPEIF_PAD_SINK | MEDIA_ENT_T_DEVNODE: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case IPIPEIF_PAD_SINK: /* Single shot mode */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->input = IPIPEIF_INPUT_NONE; @@ -896,7 +901,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local, ipipeif->input = IPIPEIF_INPUT_MEMORY; break;
- case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPEIF_PAD_SINK | 2 << 16: /* read from isif */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->input = IPIPEIF_INPUT_NONE; @@ -908,7 +913,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local, ipipeif->input = IPIPEIF_INPUT_ISIF; break;
- case IPIPEIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPEIF_PAD_SOURCE | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->output = IPIPEIF_OUTPUT_NONE; break; diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index df77288b0ec0..8ca0c1297ec8 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c @@ -1707,9 +1707,14 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local, { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case ISIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case ISIF_PAD_SINK | 2 << 16: /* read from decoder/sensor */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { isif->input = ISIF_INPUT_NONE; @@ -1720,7 +1725,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local, isif->input = ISIF_INPUT_PARALLEL; break;
- case ISIF_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case ISIF_PAD_SOURCE: /* write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) isif->output = ISIF_OUTPUT_MEMORY; @@ -1728,7 +1733,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local, isif->output = ISIF_OUTPUT_NONE; break;
- case ISIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case ISIF_PAD_SOURCE | 2 << 16: if (flags & MEDIA_LNK_FL_ENABLED) isif->output = ISIF_OUTPUT_IPIPEIF; else diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index ae942de3a23d..8eb6f5fda21c 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c @@ -1653,10 +1653,15 @@ static int resizer_link_setup(struct media_entity *entity, struct vpfe_device *vpfe_dev = to_vpfe_device(resizer); u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output; u16 ipipe_source = vpfe_dev->vpfe_ipipe.output; + int index = local->index; + + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16;
if (&resizer->crop_resizer.subdev == sd) { - switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_CROP_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + switch (index) { + case RESIZER_CROP_PAD_SINK | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->crop_resizer.input = RESIZER_CROP_INPUT_NONE; @@ -1676,7 +1681,7 @@ static int resizer_link_setup(struct media_entity *entity, return -EINVAL; break;
- case RESIZER_CROP_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case RESIZER_CROP_PAD_SOURCE | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->crop_resizer.output = RESIZER_CROP_OUTPUT_NONE; @@ -1688,7 +1693,7 @@ static int resizer_link_setup(struct media_entity *entity, resizer->crop_resizer.output = RESIZER_A; break;
- case RESIZER_CROP_PAD_SOURCE2 | MEDIA_ENT_T_V4L2_SUBDEV: + case RESIZER_CROP_PAD_SOURCE2 | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE; @@ -1704,8 +1709,8 @@ static int resizer_link_setup(struct media_entity *entity, return -EINVAL; } } else if (&resizer->resizer_a.subdev == sd) { - switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + switch (index) { + case RESIZER_PAD_SINK | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_a.input = RESIZER_INPUT_NONE; break; @@ -1715,7 +1720,7 @@ static int resizer_link_setup(struct media_entity *entity, resizer->resizer_a.input = RESIZER_INPUT_CROP_RESIZER; break;
- case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case RESIZER_PAD_SOURCE: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_a.output = RESIZER_OUTPUT_NONE; break; @@ -1729,8 +1734,8 @@ static int resizer_link_setup(struct media_entity *entity, return -EINVAL; } } else if (&resizer->resizer_b.subdev == sd) { - switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + switch (index) { + case RESIZER_PAD_SINK | 2 << 16: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_b.input = RESIZER_INPUT_NONE; break; @@ -1740,7 +1745,7 @@ static int resizer_link_setup(struct media_entity *entity, resizer->resizer_b.input = RESIZER_INPUT_CROP_RESIZER; break;
- case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + case RESIZER_PAD_SOURCE: if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->resizer_b.output = RESIZER_OUTPUT_NONE; break; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 16763e0831f2..9eef64e0f0ab 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -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 ((!is_media_entity_v4l2_io(remote->entity)) + if (!is_media_entity_v4l2_io(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 !is_media_entity_v4l2_subdev(entity)) + if (!is_media_entity_v4l2_subdev(entity)) continue; subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 1); diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c index 341489864da5..907e59edcb04 100644 --- a/drivers/staging/media/omap4iss/iss_csi2.c +++ b/drivers/staging/media/omap4iss/iss_csi2.c @@ -1170,14 +1170,19 @@ static int csi2_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct iss_csi2_ctrl_cfg *ctrl = &csi2->ctrl; + int index = local->index; + + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16;
/* * The ISS core doesn't support pipelines with multiple video outputs. * Revisit this when it will be implemented, and return -EBUSY for now. */
- switch (local->index | media_entity_type(remote->entity)) { - case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: + switch (index) { + case CSI2_PAD_SOURCE: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_MEMORY) return -EBUSY; @@ -1187,7 +1192,7 @@ static int csi2_link_setup(struct media_entity *entity, } break;
- case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case CSI2_PAD_SOURCE | 2 << 16: if (flags & MEDIA_LNK_FL_ENABLED) { if (csi2->output & ~CSI2_OUTPUT_IPIPEIF) return -EBUSY; diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c index 1c447cec4d3f..36a570e60496 100644 --- a/drivers/staging/media/omap4iss/iss_ipipeif.c +++ b/drivers/staging/media/omap4iss/iss_ipipeif.c @@ -662,9 +662,14 @@ static int ipipeif_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(ipipeif); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case IPIPEIF_PAD_SINK | 2 << 16: /* Read from the sensor CSI2a or CSI2b. */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipeif->input = IPIPEIF_INPUT_NONE; @@ -681,7 +686,7 @@ static int ipipeif_link_setup(struct media_entity *entity,
break;
- case IPIPEIF_PAD_SOURCE_ISIF_SF | MEDIA_ENT_T_DEVNODE: + case IPIPEIF_PAD_SOURCE_ISIF_SF: /* Write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ipipeif->output & ~IPIPEIF_OUTPUT_MEMORY) @@ -692,7 +697,7 @@ static int ipipeif_link_setup(struct media_entity *entity, } break;
- case IPIPEIF_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPEIF_PAD_SOURCE_VP | 2 << 16: /* Send to IPIPE/RESIZER */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ipipeif->output & ~IPIPEIF_OUTPUT_VP) diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c index 65e4ae9c9f67..5de093715f98 100644 --- a/drivers/staging/media/omap4iss/iss_resizer.c +++ b/drivers/staging/media/omap4iss/iss_resizer.c @@ -717,9 +717,14 @@ static int resizer_link_setup(struct media_entity *entity, struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(resizer); + int index = local->index;
- switch (local->index | media_entity_type(remote->entity)) { - case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + /* FIXME: this is actually a hack! */ + if (is_media_entity_v4l2_subdev(remote->entity)) + index |= 2 << 16; + + switch (index) { + case RESIZER_PAD_SINK | 2 << 16: /* Read from IPIPE or IPIPEIF. */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { resizer->input = RESIZER_INPUT_NONE; @@ -737,7 +742,7 @@ static int resizer_link_setup(struct media_entity *entity,
break;
- case RESIZER_PAD_SOURCE_MEM | MEDIA_ENT_T_DEVNODE: + case RESIZER_PAD_SOURCE_MEM : /* Write to memory */ if (flags & MEDIA_LNK_FL_ENABLED) { if (resizer->output & ~RESIZER_OUTPUT_MEMORY)
This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.
As this is a sensor driver, the proper type is likely MEDIA_ENT_T_CAM_SENSOR.
Change-Id: Ied3f78a20dc93671f5894646d7b783c9ea5ccffc Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index c81bfbfea32f..abae37321c0c 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads); @@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; - oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads);
X-Patchwork-Delegate: m.chehab@samsung.com This sensor driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, creating some subdevs with a non-existing type.
As this is a sensor driver, the proper type is likely MEDIA_ENT_T_V4L2_SUBDEV_SENSOR.
Change-Id: I16676def20fa9d0f1ab48cacde2184266823003a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/i2c/s5k5baf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index d3bff30bcb6f..0513196bd48c 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
if (!ret)
This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV:
- it uses a hack to check if the remote entity is a subdev; - it still uses the legacy entity subtype check macro, that will be removed soon.
Change-Id: Id5d46b82a4ca194a569c4f82876d4a624bdd440f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/staging/media/davinci_vpfe/dm365_ipipe.c | 9 ++++++--- drivers/staging/media/davinci_vpfe/vpfe_video.c | 5 ++--- 2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c index b89a057b8b7e..7fd78329e3e1 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c +++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c @@ -1711,8 +1711,11 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local, struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe); u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
- switch (local->index | media_entity_type(remote->entity)) { - case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + if (!is_media_entity_v4l2_subdev(remote->entity)) + return -EINVAL; + + switch (local->index) { + case IPIPE_PAD_SINK: if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipe->input = IPIPE_INPUT_NONE; break; @@ -1725,7 +1728,7 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local, ipipe->input = IPIPE_INPUT_CCDC; break;
- case IPIPE_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPE_PAD_SOURCE: /* out to RESIZER */ if (flags & MEDIA_LNK_FL_ENABLED) ipipe->output = IPIPE_OUTPUT_RESIZER; diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c index 9eef64e0f0ab..2dbf14b9bb5f 100644 --- a/drivers/staging/media/davinci_vpfe/vpfe_video.c +++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c @@ -88,7 +88,7 @@ vpfe_video_remote_subdev(struct vpfe_video_device *video, u32 *pad) { struct media_pad *remote = media_entity_remote_pad(&video->pad);
- if (remote == NULL || remote->entity->type != MEDIA_ENT_T_V4L2_SUBDEV) + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) return NULL; if (pad) *pad = remote->index; @@ -243,8 +243,7 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
/* Retrieve the source format */ pad = media_entity_remote_pad(pad); - if (pad == NULL || - pad->entity->type != MEDIA_ENT_T_V4L2_SUBDEV) + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) break;
subdev = media_entity_to_v4l2_subdev(pad->entity);
This driver is abusing MEDIA_ENT_T_V4L2_SUBDEV, as it uses a hack to check if the remote entity is a subdev. Get rid of it.
Change-Id: I77df2e0b78ce74458dba5b2d5abc9abd5a9a6551 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/staging/media/omap4iss/iss_ipipe.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c index e1a7b7ba7362..eb91ec48a21e 100644 --- a/drivers/staging/media/omap4iss/iss_ipipe.c +++ b/drivers/staging/media/omap4iss/iss_ipipe.c @@ -447,8 +447,11 @@ static int ipipe_link_setup(struct media_entity *entity, struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd); struct iss_device *iss = to_iss_device(ipipe);
- switch (local->index | media_entity_type(remote->entity)) { - case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: + if (!is_media_entity_v4l2_subdev(remote->entity)) + return -EINVAL; + + switch (local->index) { + case IPIPE_PAD_SINK: /* Read from IPIPEIF. */ if (!(flags & MEDIA_LNK_FL_ENABLED)) { ipipe->input = IPIPE_INPUT_NONE; @@ -463,7 +466,7 @@ static int ipipe_link_setup(struct media_entity *entity,
break;
- case IPIPE_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: + case IPIPE_PAD_SOURCE_VP: /* Send to RESIZER */ if (flags & MEDIA_LNK_FL_ENABLED) { if (ipipe->output & ~IPIPE_OUTPUT_VP)
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
+ if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || + entity->type == MEDIA_ENT_T_UNKNOWN) + dev_warn(mdev->dev, + "Entity type for entity %s was not initialized!\n", + entity->name); + /* Warn if we apparently re-register an entity */ WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 60da43772de9..b3bcc8253182 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; + sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; #endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index f8725b881a1d..3d6210095336 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,6 +42,14 @@ struct media_device_info {
#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
+/* Used values for media_entity_desc::type */ + +/* + * Initial value to be used when a new entity is created + * Drivers should change it to something useful + */ +#define MEDIA_ENT_T_UNKNOWN 0x00000000 + /* * Base numbers for entity types * @@ -75,6 +83,15 @@ struct media_device_info { #define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6)
/* V4L2 Sub-device entities */ + + /* + * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, + * in order to preserve backward compatibility. + * Drivers should change to the proper subdev type before + * registering the entity. + */ +#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)
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:32PM -0300, Mauro Carvalho Chehab wrote:
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
dev_warn(mdev->dev,
"Entity type for entity %s was not initialized!\n",
entity->name);
I don't think I'd warn about MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN --- there are entities that do not fall into any category of existing functions. For instance image signal processors have such; they are hardware specific and often their functionality is somewhat so as well. Some of them perform a variety of functions (image processing algorithms) but I doubt it'd make sense to start e.g. listing those until we have any standardised interface for them.
The two entities in smiapp don't have a specific function either. Adding a new one (scaler) might make sense for the two, but I think I'd leave that out from this set.
- /* Warn if we apparently re-register an entity */ WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 60da43772de9..b3bcc8253182 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
#endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index f8725b881a1d..3d6210095336 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,6 +42,14 @@ struct media_device_info {
#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
+/* Used values for media_entity_desc::type */
+/*
- Initial value to be used when a new entity is created
- Drivers should change it to something useful
- */
+#define MEDIA_ENT_T_UNKNOWN 0x00000000
/*
- Base numbers for entity types
@@ -75,6 +83,15 @@ struct media_device_info { #define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6)
/* V4L2 Sub-device entities */
- /*
* Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN,
* in order to preserve backward compatibility.
* Drivers should change to the proper subdev type before
* registering the entity.
*/
+#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)
Em Tue, 13 Oct 2015 01:25:35 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:32PM -0300, Mauro Carvalho Chehab wrote:
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
dev_warn(mdev->dev,
"Entity type for entity %s was not initialized!\n",
entity->name);
I don't think I'd warn about MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN --- there are entities that do not fall into any category of existing functions. For instance image signal processors have such; they are hardware specific and often their functionality is somewhat so as well. Some of them perform a variety of functions (image processing algorithms) but I doubt it'd make sense to start e.g. listing those until we have any standardised interface for them.
The two entities in smiapp don't have a specific function either. Adding a new one (scaler) might make sense for the two, but I think I'd leave that out from this set.
IMHO, if the entity function is really unknown, it shouldn't even be at the graph in the first place, as an unknown entity can't be controlled.
So, I think we should either add a new function for those entities, for them to be used on userspace, or simply remove them, if they won't be used on userspace, because they aren't documented.
Regards, Mauro
- /* Warn if we apparently re-register an entity */ WARN_ON(entity->graph_obj.mdev != NULL); entity->graph_obj.mdev = mdev;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 60da43772de9..b3bcc8253182 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
#endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index f8725b881a1d..3d6210095336 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,6 +42,14 @@ struct media_device_info {
#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
+/* Used values for media_entity_desc::type */
+/*
- Initial value to be used when a new entity is created
- Drivers should change it to something useful
- */
+#define MEDIA_ENT_T_UNKNOWN 0x00000000
/*
- Base numbers for entity types
@@ -75,6 +83,15 @@ struct media_device_info { #define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6)
/* V4L2 Sub-device entities */
- /*
* Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN,
* in order to preserve backward compatibility.
* Drivers should change to the proper subdev type before
* registering the entity.
*/
+#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)
Hi Mauro,
On Mon, Oct 12, 2015 at 09:26:04PM -0300, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 01:25:35 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:32PM -0300, Mauro Carvalho Chehab wrote:
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
dev_warn(mdev->dev,
"Entity type for entity %s was not initialized!\n",
entity->name);
I don't think I'd warn about MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN --- there are entities that do not fall into any category of existing functions. For instance image signal processors have such; they are hardware specific and often their functionality is somewhat so as well. Some of them perform a variety of functions (image processing algorithms) but I doubt it'd make sense to start e.g. listing those until we have any standardised interface for them.
The two entities in smiapp don't have a specific function either. Adding a new one (scaler) might make sense for the two, but I think I'd leave that out from this set.
IMHO, if the entity function is really unknown, it shouldn't even be at the graph in the first place, as an unknown entity can't be controlled.
These used to be just "sub-devices" without a type that 1) did not fall into any existing category and 2) was not generic enough to warrant adding a specific type for them. I don't think that has really changed with functions.
So, I think we should either add a new function for those entities, for them to be used on userspace, or simply remove them, if they won't be used on userspace, because they aren't documented.
What kind of "function" could you use for e.g. OMAP3ISP CCDC or preview blocks?
The issue is that for the user to meaningfully use the devices, one has to know exactly what they are. The fact they do "image processing" for instance is not really useful alone.
Flash devices, for instance, have a well defined control interface. The fact that a device can do scaling or cropping can be found querying the selections. Besides, a sensor sub-device could be capable of scaling or cropping as well.
Em Wed, 14 Oct 2015 13:15:40 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 09:26:04PM -0300, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 01:25:35 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:32PM -0300, Mauro Carvalho Chehab wrote:
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
dev_warn(mdev->dev,
"Entity type for entity %s was not initialized!\n",
entity->name);
I don't think I'd warn about MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN --- there are entities that do not fall into any category of existing functions. For instance image signal processors have such; they are hardware specific and often their functionality is somewhat so as well. Some of them perform a variety of functions (image processing algorithms) but I doubt it'd make sense to start e.g. listing those until we have any standardised interface for them.
The two entities in smiapp don't have a specific function either. Adding a new one (scaler) might make sense for the two, but I think I'd leave that out from this set.
IMHO, if the entity function is really unknown, it shouldn't even be at the graph in the first place, as an unknown entity can't be controlled.
These used to be just "sub-devices" without a type that 1) did not fall into any existing category
No problem. You can create a new function
and 2) was not generic enough to warrant adding a specific type for them. I don't think that has really changed with functions.
Well, you could add a device-specific function name. We have already other device specific things (like device-only FOURCCs, device-specific controls). I don't see why not having device-specific functions when we want/need to map such entities.
So, I think we should either add a new function for those entities, for them to be used on userspace, or simply remove them, if they won't be used on userspace, because they aren't documented.
What kind of "function" could you use for e.g. OMAP3ISP CCDC or preview blocks?
ENT_F_OMAP3ISP_CCDC
if the preview is generic enough, it could be ENT_F_PREVIEW. If not, ENT_F_OMAP3ISP_PREVIEW.
The issue is that for the user to meaningfully use the devices, one has to know exactly what they are. The fact they do "image processing" for instance is not really useful alone.
Flash devices, for instance, have a well defined control interface.
Yes, but a ENT_F_OMAP3_CCDC would also have a well defined control interface.
The fact that a device can do scaling or cropping can be found querying the selections. Besides, a sensor sub-device could be capable of scaling or cropping as well.
Hi Mauro,
On Wed, Oct 14, 2015 at 06:35:48PM -0300, Mauro Carvalho Chehab wrote:
Em Wed, 14 Oct 2015 13:15:40 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 09:26:04PM -0300, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 01:25:35 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:32PM -0300, Mauro Carvalho Chehab wrote:
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
dev_warn(mdev->dev,
"Entity type for entity %s was not initialized!\n",
entity->name);
I don't think I'd warn about MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN --- there are entities that do not fall into any category of existing functions. For instance image signal processors have such; they are hardware specific and often their functionality is somewhat so as well. Some of them perform a variety of functions (image processing algorithms) but I doubt it'd make sense to start e.g. listing those until we have any standardised interface for them.
The two entities in smiapp don't have a specific function either. Adding a new one (scaler) might make sense for the two, but I think I'd leave that out from this set.
IMHO, if the entity function is really unknown, it shouldn't even be at the graph in the first place, as an unknown entity can't be controlled.
These used to be just "sub-devices" without a type that 1) did not fall into any existing category
No problem. You can create a new function
and 2) was not generic enough to warrant adding a specific type for them. I don't think that has really changed with functions.
Well, you could add a device-specific function name. We have already other device specific things (like device-only FOURCCs, device-specific controls). I don't see why not having device-specific functions when we want/need to map such entities.
What would be the benefit of having device specific functions?
The user who would need to access such a device would probably use the name instead, probably combined with the bus information in the future (or serial number etc.).
So, I think we should either add a new function for those entities, for them to be used on userspace, or simply remove them, if they won't be used on userspace, because they aren't documented.
What kind of "function" could you use for e.g. OMAP3ISP CCDC or preview blocks?
ENT_F_OMAP3ISP_CCDC
if the preview is generic enough, it could be ENT_F_PREVIEW. If not, ENT_F_OMAP3ISP_PREVIEW.
The issue is that for the user to meaningfully use the devices, one has to know exactly what they are. The fact they do "image processing" for instance is not really useful alone.
Flash devices, for instance, have a well defined control interface.
Yes, but a ENT_F_OMAP3_CCDC would also have a well defined control interface.
..and its private IOCTLs as well.
I'd like to have Laurent's and Hans's opinion on this.
We'll also start needing multiple functions per entity in this case, since existing device specific functions would need to be amended with standardised functions. Supposing functions can be device specific, I think functions such as "scaler" should be standardised as well.
Hello,
CC'ing the linux-media mailing list.
On Sunday 08 November 2015 00:02:55 Sakari Ailus wrote:
On Wed, Oct 14, 2015 at 06:35:48PM -0300, Mauro Carvalho Chehab wrote:
Em Wed, 14 Oct 2015 13:15:40 +0300 Sakari Ailus escreveu:
On Mon, Oct 12, 2015 at 09:26:04PM -0300, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 01:25:35 +0300 Sakari Ailus escreveu:
On Mon, Oct 12, 2015 at 01:43:32PM -0300, Mauro Carvalho Chehab wrote:
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
dev_warn(mdev->dev,
"Entity type for entity %s was not initialized!\n",
entity->name);
First of all the subject of the patch is very misleading as you initialize the entity type for new subdevs to MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, not MEDIA_ENT_T_UNKNOWN.
I don't think I'd warn about MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN --- there are entities that do not fall into any category of existing functions. For instance image signal processors have such; they are hardware specific and often their functionality is somewhat so as well. Some of them perform a variety of functions (image processing algorithms) but I doubt it'd make sense to start e.g. listing those until we have any standardised interface for them.
Most of the subdevs we have today are of the "unknown" type, which isn't very user-friendly. Part of the reason is that there has never been a big incentive for driver writes to add proper subdev types, as the type is ignored in userspace in most cases. This should hopefully change with functions, and we'll need to push for new subdevs to have at least one function defined, even if it's a generic function such as image processing for lack of a better alternative. Warning on MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN has the advantage that it will push driver authors to think about the issue instead of just ignoring it and setting the type/function to unknown. That might be a wrong solution though, as if we introduce a generic image processing function (which we'll need for lack of a better or more precise alternative in some cases) driver authors might just use that one instead of MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, and it would become the equivalent of the unknown type for all practical purpose. We would only have pushed the problem one step further without solving it. I wonder how we could improve that.
The two entities in smiapp don't have a specific function either. Adding a new one (scaler) might make sense for the two, but I think I'd leave that out from this set.
IMHO, if the entity function is really unknown, it shouldn't even be at the graph in the first place, as an unknown entity can't be controlled.
These used to be just "sub-devices" without a type that 1) did not fall into any existing category
No problem. You can create a new function
and 2) was not generic enough to warrant adding a specific type for them. I don't think that has really changed with functions.
Well, you could add a device-specific function name. We have already other device specific things (like device-only FOURCCs, device-specific controls). I don't see why not having device-specific functions when we want/need to map such entities.
What would be the benefit of having device specific functions?
The user who would need to access such a device would probably use the name instead, probably combined with the bus information in the future (or serial number etc.).
So, I think we should either add a new function for those entities, for them to be used on userspace, or simply remove them, if they won't be used on userspace, because they aren't documented.
What kind of "function" could you use for e.g. OMAP3ISP CCDC or preview blocks?
ENT_F_OMAP3ISP_CCDC
if the preview is generic enough, it could be ENT_F_PREVIEW. If not, ENT_F_OMAP3ISP_PREVIEW.
The issue is that for the user to meaningfully use the devices, one has to know exactly what they are. The fact they do "image processing" for instance is not really useful alone.
Flash devices, for instance, have a well defined control interface.
Yes, but a ENT_F_OMAP3_CCDC would also have a well defined control interface.
..and its private IOCTLs as well.
I'd like to have Laurent's and Hans's opinion on this.
I don't think it makes sense to create a device-specific function for those subdevs. Functions should be defined generically, not in a hardware-specific fashion. Otherwise we would mix two very different usages, the identification of what an entity does and the identification of what an entity is. Locating an entity precisely in the graph ("where is the OMAP3 ISP CCDC entity?") is the purpose of the entity name. Using ENT_F_OMAP3_CCDC would mean "the OMAP3 ISP CCDC entity does ENT_F_OMAP3_CCDC, defined as whatever the OMAP3 ISP CCDC entity does". That sounds tautological to me. I'd rather know that "the OMAP3 ISP CCDC entity does image processing", or possibly "the OMAP3 ISP CCDC entity does black level compensation, fault pixel correction and lens shading correction".
We'll also start needing multiple functions per entity in this case, since existing device specific functions would need to be amended with standardised functions. Supposing functions can be device specific, I think functions such as "scaler" should be standardised as well.
I agree with both statements, we'll need multiple functions per entity, and the scaler function should be standardized.
Hello,
CC'ing the linux-media mailing list, for real this time.
On Sunday 08 November 2015 00:02:55 Sakari Ailus wrote:
On Wed, Oct 14, 2015 at 06:35:48PM -0300, Mauro Carvalho Chehab wrote:
Em Wed, 14 Oct 2015 13:15:40 +0300 Sakari Ailus escreveu:
On Mon, Oct 12, 2015 at 09:26:04PM -0300, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 01:25:35 +0300 Sakari Ailus escreveu:
On Mon, Oct 12, 2015 at 01:43:32PM -0300, Mauro Carvalho Chehab wrote:
Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN.
Change-Id: I294ee20f49b6c40dd95339d6730d90fa85b0dea9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 6 ++++++ drivers/media/v4l2-core/v4l2-subdev.c | 2 +- include/uapi/linux/media.h | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 659507bce63f..134fe7510195 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -435,6 +435,12 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
dev_warn(mdev->dev,
"Entity type for entity %s was not initialized!\n",
entity->name);
First of all the subject of the patch is very misleading as you initialize the entity type for new subdevs to MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, not MEDIA_ENT_T_UNKNOWN.
I don't think I'd warn about MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN --- there are entities that do not fall into any category of existing functions. For instance image signal processors have such; they are hardware specific and often their functionality is somewhat so as well. Some of them perform a variety of functions (image processing algorithms) but I doubt it'd make sense to start e.g. listing those until we have any standardised interface for them.
Most of the subdevs we have today are of the "unknown" type, which isn't very user-friendly. Part of the reason is that there has never been a big incentive for driver writes to add proper subdev types, as the type is ignored in userspace in most cases. This should hopefully change with functions, and we'll need to push for new subdevs to have at least one function defined, even if it's a generic function such as image processing for lack of a better alternative. Warning on MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN has the advantage that it will push driver authors to think about the issue instead of just ignoring it and setting the type/function to unknown. That might be a wrong solution though, as if we introduce a generic image processing function (which we'll need for lack of a better or more precise alternative in some cases) driver authors might just use that one instead of MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, and it would become the equivalent of the unknown type for all practical purpose. We would only have pushed the problem one step further without solving it. I wonder how we could improve that.
The two entities in smiapp don't have a specific function either. Adding a new one (scaler) might make sense for the two, but I think I'd leave that out from this set.
IMHO, if the entity function is really unknown, it shouldn't even be at the graph in the first place, as an unknown entity can't be controlled.
These used to be just "sub-devices" without a type that 1) did not fall into any existing category
No problem. You can create a new function
and 2) was not generic enough to warrant adding a specific type for them. I don't think that has really changed with functions.
Well, you could add a device-specific function name. We have already other device specific things (like device-only FOURCCs, device-specific controls). I don't see why not having device-specific functions when we want/need to map such entities.
What would be the benefit of having device specific functions?
The user who would need to access such a device would probably use the name instead, probably combined with the bus information in the future (or serial number etc.).
So, I think we should either add a new function for those entities, for them to be used on userspace, or simply remove them, if they won't be used on userspace, because they aren't documented.
What kind of "function" could you use for e.g. OMAP3ISP CCDC or preview blocks?
ENT_F_OMAP3ISP_CCDC
if the preview is generic enough, it could be ENT_F_PREVIEW. If not, ENT_F_OMAP3ISP_PREVIEW.
The issue is that for the user to meaningfully use the devices, one has to know exactly what they are. The fact they do "image processing" for instance is not really useful alone.
Flash devices, for instance, have a well defined control interface.
Yes, but a ENT_F_OMAP3_CCDC would also have a well defined control interface.
..and its private IOCTLs as well.
I'd like to have Laurent's and Hans's opinion on this.
I don't think it makes sense to create a device-specific function for those subdevs. Functions should be defined generically, not in a hardware-specific fashion. Otherwise we would mix two very different usages, the identification of what an entity does and the identification of what an entity is. Locating an entity precisely in the graph ("where is the OMAP3 ISP CCDC entity?") is the purpose of the entity name. Using ENT_F_OMAP3_CCDC would mean "the OMAP3 ISP CCDC entity does ENT_F_OMAP3_CCDC, defined as whatever the OMAP3 ISP CCDC entity does". That sounds tautological to me. I'd rather know that "the OMAP3 ISP CCDC entity does image processing", or possibly "the OMAP3 ISP CCDC entity does black level compensation, fault pixel correction and lens shading correction".
We'll also start needing multiple functions per entity in this case, since existing device specific functions would need to be amended with standardised functions. Supposing functions can be device specific, I think functions such as "scaler" should be standardised as well.
I agree with both statements, we'll need multiple functions per entity, and the scaler function should be standardized.
Don't use anymore the type/subtype entity data/macros inside the Kernel.
Change-Id: I6de900ab758e8d40bd875336602307d160254665 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/media/media-entity.h | 10 ---------- include/uapi/linux/media.h | 2 -- 2 files changed, 12 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 220864319d21..7320cdc45833 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -185,16 +185,6 @@ struct media_intf_devnode { u32 minor; };
-static inline u32 media_entity_type(struct media_entity *entity) -{ - return entity->type & MEDIA_ENT_TYPE_MASK; -} - -static inline u32 media_entity_subtype(struct media_entity *entity) -{ - return entity->type & MEDIA_ENT_SUBTYPE_MASK; -} - static inline u32 media_entity_id(struct media_entity *entity) { return entity->graph_obj.id; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3d6210095336..f90147cb9b57 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,8 +42,6 @@ struct media_device_info {
#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
-/* Used values for media_entity_desc::type */ - /* * Initial value to be used when a new entity is created * Drivers should change it to something useful
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Don't use anymore the type/subtype entity data/macros inside the Kernel.
Change-Id: I6de900ab758e8d40bd875336602307d160254665 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
include/media/media-entity.h | 10 ---------- include/uapi/linux/media.h | 2 -- 2 files changed, 12 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 220864319d21..7320cdc45833 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -185,16 +185,6 @@ struct media_intf_devnode { u32 minor; };
-static inline u32 media_entity_type(struct media_entity *entity) -{
- return entity->type & MEDIA_ENT_TYPE_MASK;
-}
-static inline u32 media_entity_subtype(struct media_entity *entity) -{
- return entity->type & MEDIA_ENT_SUBTYPE_MASK;
-}
static inline u32 media_entity_id(struct media_entity *entity) { return entity->graph_obj.id; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3d6210095336..f90147cb9b57 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,8 +42,6 @@ struct media_device_info {
#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
-/* Used values for media_entity_desc::type */
/*
- Initial value to be used when a new entity is created
- Drivers should change it to something useful
Put the legacy MEDIA_ENT_* macros under a #ifndef __KERNEL__, in order to be sure that none of those old symbols are used inside the Kernel.
Change-Id: I898bed3e4e978734205052133948b2e336b368d4 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- include/uapi/linux/media.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index f90147cb9b57..a1bd7afba110 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -105,6 +105,7 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) #define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5)
+#ifndef __KERNEL__ /* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 @@ -118,6 +119,7 @@ struct media_device_info { #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 (MEDIA_ENT_T_DEVNODE + 4) +#endif
/* Entity types */
Cleanup the media controller entities description: - remove MEDIA_ENT_T_DEVNODE and MEDIA_ENT_T_V4L2_SUBDEV entity types, as they don't mean anything; - add MEDIA_ENT_T_UNKNOWN with a proper description; - remove ALSA and FB entity types. Those should not be used, as the types are deprecated. We'll soon be adidng ALSA, but with a different entity namespace; - improve the description of some entities.
Change-Id: I0db7672809b567e04a5f367ff6b31315f7b7be8a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- .../DocBook/media/v4l/media-ioc-enum-entities.xml | 47 ++++++++++------------ 1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 32a783635649..bc101516e372 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -179,70 +179,65 @@ <colspec colname="c2"/> <tbody valign="top"> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry> - <entry>Unknown device node</entry> + <entry><constant>MEDIA_ENT_T_UNKNOWN</constant> and <constant>MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN</constant></entry> + <entry>Unknown entity. That generally indicates that + a driver didn't initialize properly the entity, with is a Kernel bug</entry> </row> <row> <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry> - <entry>V4L video, radio or vbi device node</entry> + <entry>V4L video streaming input or output entity</entry> </row> - <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry> - <entry>Frame buffer device node</entry> + <entry><constant>MEDIA_ENT_T_V4L2_VBI</constant></entry> + <entry>V4L VBI streaming input or output entity</entry> </row> - <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry> - <entry>ALSA card</entry> + <entry><constant>MEDIA_ENT_T_V4L2_SWRADIO</constant></entry> + <entry>V4L Sofware Digital Radio (SDR) streaming input or output entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry> - <entry>DVB frontend devnode</entry> + <entry>DVB demodulator entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry> - <entry>DVB demux devnode</entry> + <entry>DVB demux entity. Could be implemented on hardware or in Kernelspace</entry> </row> <row> <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry> - <entry>DVB DVR devnode</entry> + <entry>DVB Transport Stream output entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry> - <entry>DVB CAM devnode</entry> + <entry>DVB Conditional Access module (CAM) entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry> - <entry>DVB network devnode</entry> - </row> - <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry> - <entry>Unknown V4L sub-device</entry> + <entry>DVB network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry> </row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry> - <entry>Video sensor</entry> + <entry>Camera video sensor entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry> - <entry>Flash controller</entry> + <entry>Flash controller entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry> - <entry>Lens controller</entry> + <entry>Lens controller entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_DECODER</constant></entry> - <entry>Video decoder, the basic function of the video decoder is to - accept analogue video from a wide variety of sources such as + <entry>Analog video decoder, the basic function of the video decoder + is to accept analogue video from a wide variety of sources such as broadcast, DVD players, cameras and video cassette recorders, in - either NTSC, PAL or HD format and still occasionally SECAM, separate - it into its component parts, luminance and chrominance, and output + either NTSC, PAL, SECAM or HD format, separating the stream + into its component parts, luminance and chrominance, and output it in some digital video standard, with appropriate embedded timing signals.</entry> </row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry> - <entry>TV and/or radio tuner</entry> + <entry>Digital TV, analog TV, radio and/or software radio tuner</entry> </row> </tbody> </tgroup>
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Cleanup the media controller entities description:
- remove MEDIA_ENT_T_DEVNODE and MEDIA_ENT_T_V4L2_SUBDEV entity types, as they don't mean anything;
- add MEDIA_ENT_T_UNKNOWN with a proper description;
- remove ALSA and FB entity types. Those should not be used, as the types are deprecated. We'll soon be adidng ALSA, but with a different entity namespace;
- improve the description of some entities.
Change-Id: I0db7672809b567e04a5f367ff6b31315f7b7be8a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
.../DocBook/media/v4l/media-ioc-enum-entities.xml | 47 ++++++++++------------ 1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index 32a783635649..bc101516e372 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -179,70 +179,65 @@ <colspec colname="c2"/>
<tbody valign="top"> <row> - <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry> - <entry>Unknown device node</entry> + <entry><constant>MEDIA_ENT_T_UNKNOWN</constant> and <constant>MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN</constant></entry> + <entry>Unknown entity. That generally indicates that + a driver didn't initialize properly the entity, with is a Kernel bug</entry> </row> <row> <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry> - <entry>V4L video, radio or vbi device node</entry> + <entry>V4L video streaming input or output entity</entry> </row> - <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry> - <entry>Frame buffer device node</entry> + <entry><constant>MEDIA_ENT_T_V4L2_VBI</constant></entry> + <entry>V4L VBI streaming input or output entity</entry> </row> - <row> - <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry> - <entry>ALSA card</entry> + <entry><constant>MEDIA_ENT_T_V4L2_SWRADIO</constant></entry> + <entry>V4L Sofware Digital Radio (SDR) streaming input or output entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry> - <entry>DVB frontend devnode</entry> + <entry>DVB demodulator entity</entry> </row> <row> <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry> - <entry>DVB demux devnode</entry> + <entry>DVB demux entity. Could be implemented on hardware or in Kernelspace</entry>
s/on/in/
</row> <row> <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry>
<entry>DVB DVR devnode</entry>
<entry>DVB Transport Stream output entity</entry>
</row> <row> <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry>
<entry>DVB CAM devnode</entry>
<entry>DVB Conditional Access module (CAM) entity</entry>
</row> <row> <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry>
<entry>DVB network devnode</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
<entry>Unknown V4L sub-device</entry>
<entry>DVB network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry>
s/desencapsulation/de-encapsulation/ s/on/in/
After fixing these small typos you can add my:
Acked-by: Hans Verkuil hans.verkuil@cisco.com
Hans
</row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry>
<entry>Video sensor</entry>
<entry>Camera video sensor entity</entry>
</row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry>
<entry>Flash controller</entry>
<entry>Flash controller entity</entry>
</row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry>
<entry>Lens controller</entry>
<entry>Lens controller entity</entry>
</row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_DECODER</constant></entry>
<entry>Video decoder, the basic function of the video decoder is to
accept analogue video from a wide variety of sources such as
<entry>Analog video decoder, the basic function of the video decoder
is to accept analogue video from a wide variety of sources such as broadcast, DVD players, cameras and video cassette recorders, in
either NTSC, PAL or HD format and still occasionally SECAM, separate
it into its component parts, luminance and chrominance, and output
either NTSC, PAL, SECAM or HD format, separating the stream
into its component parts, luminance and chrominance, and output it in some digital video standard, with appropriate embedded timing signals.</entry>
</row> <row> <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry>
<entry>TV and/or radio tuner</entry>
<entry>Digital TV, analog TV, radio and/or software radio tuner</entry>
</row> </tbody> </tgroup>
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.
Change-Id: I58d6a8058572fcef7ac94f6601ad11571b83a36d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dmxdev.c | 4 +- drivers/media/dvb-core/dvb_ca_en50221.c | 2 +- drivers/media/dvb-core/dvb_frontend.c | 2 +- drivers/media/dvb-core/dvb_net.c | 2 +- drivers/media/dvb-core/dvbdev.c | 146 +++++++++++++++++++++++++---- drivers/media/dvb-core/dvbdev.h | 9 +- drivers/media/firewire/firedtv-ci.c | 2 +- drivers/media/pci/bt8xx/dst_ca.c | 3 +- drivers/media/pci/ddbridge/ddbridge-core.c | 2 +- drivers/media/pci/ngene/ngene-core.c | 2 +- drivers/media/pci/ttpci/av7110.c | 2 +- drivers/media/pci/ttpci/av7110_av.c | 4 +- drivers/media/pci/ttpci/av7110_ca.c | 2 +- 13 files changed, 148 insertions(+), 34 deletions(-)
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index d0e3f9d85f34..baaed28ee975 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -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);
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index fb66184dc9b6..f82cd1ff4f3a 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -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;
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 2d06bcff0946..58601bfe0b8d 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -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 diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index b81e026edab3..14f51b68f4fe 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -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); diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index dadcf1655070..6babc688801b 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -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); diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 5f37b4dd1e69..0b140e8595de 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -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 diff --git a/drivers/media/firewire/firedtv-ci.c b/drivers/media/firewire/firedtv-ci.c index e63f582378bf..edbb30fdd9d9 100644 --- a/drivers/media/firewire/firedtv-ci.c +++ b/drivers/media/firewire/firedtv-ci.c @@ -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"); diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index c5cc14ef8347..0149a9ed6e58 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -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; } diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index 0ac2dd35fe50..4caca5df2931 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -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; }
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 1b92d836a564..4e924e2d1638 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -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; } diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index 3f24fce74fc1..63f1d56bdfb2 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -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); diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c index 9544cfc06601..da11501fe5d2 100644 --- a/drivers/media/pci/ttpci/av7110_av.c +++ b/drivers/media/pci/ttpci/av7110_av.c @@ -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; } diff --git a/drivers/media/pci/ttpci/av7110_ca.c b/drivers/media/pci/ttpci/av7110_ca.c index a6079b90252a..235f0202dc7e 100644 --- a/drivers/media/pci/ttpci/av7110_ca.c +++ b/drivers/media/pci/ttpci/av7110_ca.c @@ -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)
Sometimes, it is important to see if the created pad is sink or source. Add info to track that.
Change-Id: Idddf19e19a548ad46eca4b6734d2dbf9e779b21e Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-entity.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index d8038a53f945..6ed5eef88593 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -121,8 +121,11 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_pad *pad = gobj_to_pad(gobj);
dev_dbg(gobj->mdev->dev, - "%s: id 0x%08x pad#%d: '%s':%d\n", - event_name, gobj->id, media_localid(gobj), + "%s: id 0x%08x %s%spad#%d: '%s':%d\n", + event_name, gobj->id, + pad->flags & MEDIA_PAD_FL_SINK ? " sink " : "", + pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "", + media_localid(gobj), pad->entity->name, pad->index); break; }
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Sometimes, it is important to see if the created pad is sink or source. Add info to track that.
Change-Id: Idddf19e19a548ad46eca4b6734d2dbf9e779b21e Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-entity.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index d8038a53f945..6ed5eef88593 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -121,8 +121,11 @@ static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj) struct media_pad *pad = gobj_to_pad(gobj);
dev_dbg(gobj->mdev->dev,
"%s: id 0x%08x pad#%d: '%s':%d\n",
event_name, gobj->id, media_localid(gobj),
"%s: id 0x%08x %s%spad#%d: '%s':%d\n",
event_name, gobj->id,
pad->flags & MEDIA_PAD_FL_SINK ? " sink " : "",
pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "",
break; }media_localid(gobj), pad->entity->name, pad->index);
Add a new ioctl that will report the entire topology on one go.
Change-Id: Ic022469be237dcaca56a077073b404f7de21f655 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7320cdc45833..2d5ad40254b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf; + + /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor; }; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index a1bd7afba110..b17f6763aff4 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28) + struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -249,11 +253,93 @@ struct media_links_enum { #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 */ +/* + * MC next gen API definitions + * + * NOTE: The declarations below are close to the MC RFC for the Media + * Controller, the next generation. Yet, there are a few adjustments + * to do, as we want to be able to have a functional API before + * the MC properties change. Those will be properly marked below. + * Please also notice that I removed "num_pads", "num_links", + * from the proposal, as a proper userspace application will likely + * use lists for pads/links, just as we intend to do in Kernelspace. + * The API definition should be freed from fields that are bound to + * some specific data structure. + * + * FIXME: Currently, I opted to name the new types as "media_v2", as this + * won't cause any conflict with the Kernelspace namespace, nor with + * the previous kAPI media_*_desc namespace. This can be changed + * later, before the adding this API upstream. + */ + + +struct media_v2_entity { + __u32 id; + char name[64]; /* FIXME: move to a property? (RFC says so) */ + __u16 reserved[14]; +}; + +/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode { + __u32 major; + __u32 minor; +}; + +struct media_v2_interface { + __u32 id; + __u32 intf_type; + __u32 flags; + __u32 reserved[9]; + + union { + struct media_v2_intf_devnode devnode; + __u32 raw[16]; + }; +}; + +struct media_v2_pad { + __u32 id; + __u32 entity_id; + __u32 flags; + __u16 reserved[9]; +}; + +struct media_v2_link { + __u32 id; + __u32 source_id; + __u32 sink_id; + __u32 flags; + __u32 reserved[5]; +}; + +struct media_v2_topology { + __u32 topology_version; + + __u32 num_entities; + struct media_v2_entity *entities; + + __u32 num_interfaces; + struct media_v2_interface *interfaces; + + __u32 num_pads; + struct media_v2_pad *pads; + + __u32 num_links; + struct media_v2_link *links; + + struct { + __u32 reserved_num; + void *reserved_ptr; + } reserved_types[16]; + __u32 reserved[8]; +}; + +/* ioctls */
#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) +#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology)
#endif /* __LINUX_MEDIA_H */
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:38PM -0300, Mauro Carvalho Chehab wrote:
Add a new ioctl that will report the entire topology on one go.
Change-Id: Ic022469be237dcaca56a077073b404f7de21f655 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7320cdc45833..2d5ad40254b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf;
- /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor;
}; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index a1bd7afba110..b17f6763aff4 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
How about removing the extra spaces between # and define? Or were they intended?
struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -249,11 +253,93 @@ struct media_links_enum { #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 */ +/*
- MC next gen API definitions
- NOTE: The declarations below are close to the MC RFC for the Media
Controller, the next generation. Yet, there are a few adjustments
to do, as we want to be able to have a functional API before
the MC properties change. Those will be properly marked below.
Please also notice that I removed "num_pads", "num_links",
from the proposal, as a proper userspace application will likely
use lists for pads/links, just as we intend to do in Kernelspace.
The API definition should be freed from fields that are bound to
some specific data structure.
- FIXME: Currently, I opted to name the new types as "media_v2", as this
won't cause any conflict with the Kernelspace namespace, nor with
the previous kAPI media_*_desc namespace. This can be changed
later, before the adding this API upstream.
- */
+struct media_v2_entity {
- __u32 id;
- char name[64]; /* FIXME: move to a property? (RFC says so) */
That indeed requires the property API. We can't have it this week or next (and perhaps not next month either). Shall we wait, use a temporary field (and remind the user that the API is experimental) or go without name (which is rather important)?
I think clearly labelling this experimental would be the thing to do, and then after some time remove the name field. Albeit historically APIs marked clearly as experimental have been used by applications and then fixing those APIs has been no-go since the applications already use them. Oh, well...
- __u16 reserved[14];
How about 32-bit fields instead? I think the only reason to have 16-bit reserved fields is to align 16-bit aligned fields to higher alignment, but this is not the case here.
+};
+/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode {
- __u32 major;
- __u32 minor;
+};
+struct media_v2_interface {
- __u32 id;
- __u32 intf_type;
- __u32 flags;
- __u32 reserved[9];
- union {
struct media_v2_intf_devnode devnode;
__u32 raw[16];
- };
+};
+struct media_v2_pad {
- __u32 id;
- __u32 entity_id;
- __u32 flags;
- __u16 reserved[9];
Any particular reason for an odd number of 16-bit reserved fields? :-)
+};
+struct media_v2_link {
- __u32 id;
- __u32 source_id;
- __u32 sink_id;
- __u32 flags;
- __u32 reserved[5];
+};
+struct media_v2_topology {
- __u32 topology_version;
- __u32 num_entities;
- struct media_v2_entity *entities;
- __u32 num_interfaces;
- struct media_v2_interface *interfaces;
If you added reserved fields to align the pointers to 64 bits we'd get away with some error-prone compat code. These should also have the __user modifier.
- __u32 num_pads;
- struct media_v2_pad *pads;
- __u32 num_links;
- struct media_v2_link *links;
- struct {
__u32 reserved_num;
void *reserved_ptr;
- } reserved_types[16];
- __u32 reserved[8];
+};
+/* ioctls */
#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) +#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology)
#endif /* __LINUX_MEDIA_H */
Em Tue, 13 Oct 2015 12:16:51 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:38PM -0300, Mauro Carvalho Chehab wrote:
Add a new ioctl that will report the entire topology on one go.
Change-Id: Ic022469be237dcaca56a077073b404f7de21f655 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7320cdc45833..2d5ad40254b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf;
- /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor;
}; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index a1bd7afba110..b17f6763aff4 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
How about removing the extra spaces between # and define? Or were they intended?
They're intended. This is a common way to tell that the two defines below are related to the first one.
struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -249,11 +253,93 @@ struct media_links_enum { #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 */ +/*
- MC next gen API definitions
- NOTE: The declarations below are close to the MC RFC for the Media
Controller, the next generation. Yet, there are a few adjustments
to do, as we want to be able to have a functional API before
the MC properties change. Those will be properly marked below.
Please also notice that I removed "num_pads", "num_links",
from the proposal, as a proper userspace application will likely
use lists for pads/links, just as we intend to do in Kernelspace.
The API definition should be freed from fields that are bound to
some specific data structure.
- FIXME: Currently, I opted to name the new types as "media_v2", as this
won't cause any conflict with the Kernelspace namespace, nor with
the previous kAPI media_*_desc namespace. This can be changed
later, before the adding this API upstream.
- */
+struct media_v2_entity {
- __u32 id;
- char name[64]; /* FIXME: move to a property? (RFC says so) */
That indeed requires the property API. We can't have it this week or next (and perhaps not next month either). Shall we wait, use a temporary field (and remind the user that the API is experimental) or go without name (which is rather important)?
I think clearly labelling this experimental would be the thing to do, and then after some time remove the name field. Albeit historically APIs marked clearly as experimental have been used by applications and then fixing those APIs has been no-go since the applications already use them. Oh, well...
- __u16 reserved[14];
How about 32-bit fields instead? I think the only reason to have 16-bit reserved fields is to align 16-bit aligned fields to higher alignment, but this is not the case here.
+};
+/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode {
- __u32 major;
- __u32 minor;
+};
+struct media_v2_interface {
- __u32 id;
- __u32 intf_type;
- __u32 flags;
- __u32 reserved[9];
- union {
struct media_v2_intf_devnode devnode;
__u32 raw[16];
- };
+};
+struct media_v2_pad {
- __u32 id;
- __u32 entity_id;
- __u32 flags;
- __u16 reserved[9];
Any particular reason for an odd number of 16-bit reserved fields? :-)
+};
+struct media_v2_link {
- __u32 id;
- __u32 source_id;
- __u32 sink_id;
- __u32 flags;
- __u32 reserved[5];
+};
+struct media_v2_topology {
- __u32 topology_version;
- __u32 num_entities;
- struct media_v2_entity *entities;
- __u32 num_interfaces;
- struct media_v2_interface *interfaces;
If you added reserved fields to align the pointers to 64 bits we'd get away with some error-prone compat code. These should also have the __user modifier.
- __u32 num_pads;
- struct media_v2_pad *pads;
- __u32 num_links;
- struct media_v2_link *links;
- struct {
__u32 reserved_num;
void *reserved_ptr;
- } reserved_types[16];
- __u32 reserved[8];
+};
+/* ioctls */
#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) +#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology)
#endif /* __LINUX_MEDIA_H */
Em Tue, 13 Oct 2015 08:09:53 -0300 Mauro Carvalho Chehab mchehab@osg.samsung.com escreveu:
Em Tue, 13 Oct 2015 12:16:51 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:38PM -0300, Mauro Carvalho Chehab wrote:
Add a new ioctl that will report the entire topology on one go.
Change-Id: Ic022469be237dcaca56a077073b404f7de21f655 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7320cdc45833..2d5ad40254b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf;
- /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor;
}; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index a1bd7afba110..b17f6763aff4 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
How about removing the extra spaces between # and define? Or were they intended?
They're intended. This is a common way to tell that the two defines below are related to the first one.
Sorry, I didn't see the other comments. See below.
struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -249,11 +253,93 @@ struct media_links_enum { #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 */ +/*
- MC next gen API definitions
- NOTE: The declarations below are close to the MC RFC for the Media
Controller, the next generation. Yet, there are a few adjustments
to do, as we want to be able to have a functional API before
the MC properties change. Those will be properly marked below.
Please also notice that I removed "num_pads", "num_links",
from the proposal, as a proper userspace application will likely
use lists for pads/links, just as we intend to do in Kernelspace.
The API definition should be freed from fields that are bound to
some specific data structure.
- FIXME: Currently, I opted to name the new types as "media_v2", as this
won't cause any conflict with the Kernelspace namespace, nor with
the previous kAPI media_*_desc namespace. This can be changed
later, before the adding this API upstream.
- */
+struct media_v2_entity {
- __u32 id;
- char name[64]; /* FIXME: move to a property? (RFC says so) */
That indeed requires the property API. We can't have it this week or next (and perhaps not next month either). Shall we wait, use a temporary field (and remind the user that the API is experimental) or go without name (which is rather important)?
I think clearly labelling this experimental would be the thing to do, and then after some time remove the name field. Albeit historically APIs marked clearly as experimental have been used by applications and then fixing those APIs has been no-go since the applications already use them. Oh, well...
I added the FIXME due to a purpose: IMHO, despite the discussions we had at the MC summit, I think we should keep the name at the main struct.
The rationale is that, unlikely other properties that are typically optional, the name is mandatory, as we want all entities to have a name. By having it at the struct, we'll be sure about that. Ok, the drawback is that we'll waste space at the ioctl, so, I'm not 100% sure about that.
In any case, we should address this before having the API at a released Kernel.
I mean: we need to decide if the entity name will be at a property or at struct media_v2_entity. If we decide to put it on a property, we should just remove the name there and comment the part of the mc_nextgen_test that uses it, uncommenting (and changing accordingly) only when we merge the properties API.
Otherwise, we should remove the /* FIXME */ from it.
Comments?
- __u16 reserved[14];
How about 32-bit fields instead? I think the only reason to have 16-bit reserved fields is to align 16-bit aligned fields to higher alignment, but this is not the case here.
That came from hverkuil's RFC/suggestion. I don't have any strong opinion about that.
+};
+/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode {
- __u32 major;
- __u32 minor;
+};
+struct media_v2_interface {
- __u32 id;
- __u32 intf_type;
- __u32 flags;
- __u32 reserved[9];
- union {
struct media_v2_intf_devnode devnode;
__u32 raw[16];
- };
+};
+struct media_v2_pad {
- __u32 id;
- __u32 entity_id;
- __u32 flags;
- __u16 reserved[9];
Any particular reason for an odd number of 16-bit reserved fields? :-)
Ask Hans. I just used his RFC design here ;)
+};
+struct media_v2_link {
- __u32 id;
- __u32 source_id;
- __u32 sink_id;
- __u32 flags;
- __u32 reserved[5];
+};
+struct media_v2_topology {
- __u32 topology_version;
- __u32 num_entities;
- struct media_v2_entity *entities;
- __u32 num_interfaces;
- struct media_v2_interface *interfaces;
If you added reserved fields to align the pointers to 64 bits we'd get away with some error-prone compat code.
Maybe. It seems that arm64 has some differences with regards to struct aligns. I didn't analyze yet what are the arch differences, but I suspect that we may need to add some compat code anyway.
I'm open to suggestions.
These should also have the __user modifier.
I have to check, but I guess __user should not be used at the struct definition at the .h, but when using it at media_device.c.
- __u32 num_pads;
- struct media_v2_pad *pads;
- __u32 num_links;
- struct media_v2_link *links;
- struct {
__u32 reserved_num;
void *reserved_ptr;
- } reserved_types[16];
- __u32 reserved[8];
+};
+/* ioctls */
#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) +#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology)
#endif /* __LINUX_MEDIA_H */
media-workshop mailing list media-workshop@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/media-workshop
On 10/15/2015 04:26 AM, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 08:09:53 -0300 Mauro Carvalho Chehab mchehab@osg.samsung.com escreveu:
Em Tue, 13 Oct 2015 12:16:51 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:38PM -0300, Mauro Carvalho Chehab wrote:
Add a new ioctl that will report the entire topology on one go.
Change-Id: Ic022469be237dcaca56a077073b404f7de21f655 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7320cdc45833..2d5ad40254b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf;
- /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor;
}; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index a1bd7afba110..b17f6763aff4 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
How about removing the extra spaces between # and define? Or were they intended?
They're intended. This is a common way to tell that the two defines below are related to the first one.
Sorry, I didn't see the other comments. See below.
struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -249,11 +253,93 @@ struct media_links_enum { #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 */ +/*
- MC next gen API definitions
- NOTE: The declarations below are close to the MC RFC for the Media
Controller, the next generation. Yet, there are a few adjustments
to do, as we want to be able to have a functional API before
the MC properties change. Those will be properly marked below.
Please also notice that I removed "num_pads", "num_links",
from the proposal, as a proper userspace application will likely
use lists for pads/links, just as we intend to do in Kernelspace.
The API definition should be freed from fields that are bound to
some specific data structure.
- FIXME: Currently, I opted to name the new types as "media_v2", as this
won't cause any conflict with the Kernelspace namespace, nor with
the previous kAPI media_*_desc namespace. This can be changed
later, before the adding this API upstream.
- */
+struct media_v2_entity {
- __u32 id;
- char name[64]; /* FIXME: move to a property? (RFC says so) */
That indeed requires the property API. We can't have it this week or next (and perhaps not next month either). Shall we wait, use a temporary field (and remind the user that the API is experimental) or go without name (which is rather important)?
I think clearly labelling this experimental would be the thing to do, and then after some time remove the name field. Albeit historically APIs marked clearly as experimental have been used by applications and then fixing those APIs has been no-go since the applications already use them. Oh, well...
I added the FIXME due to a purpose: IMHO, despite the discussions we had at the MC summit, I think we should keep the name at the main struct.
The rationale is that, unlikely other properties that are typically optional, the name is mandatory, as we want all entities to have a name. By having it at the struct, we'll be sure about that. Ok, the drawback is that we'll waste space at the ioctl, so, I'm not 100% sure about that.
In any case, we should address this before having the API at a released Kernel.
I mean: we need to decide if the entity name will be at a property or at struct media_v2_entity. If we decide to put it on a property, we should just remove the name there and comment the part of the mc_nextgen_test that uses it, uncommenting (and changing accordingly) only when we merge the properties API.
Otherwise, we should remove the /* FIXME */ from it.
Comments?
- __u16 reserved[14];
How about 32-bit fields instead? I think the only reason to have 16-bit reserved fields is to align 16-bit aligned fields to higher alignment, but this is not the case here.
That came from hverkuil's RFC/suggestion. I don't have any strong opinion about that.
I think u16 here is a left-over from then the struct ended with a u16. Replacing it with u32 is better.
+};
+/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode {
- __u32 major;
- __u32 minor;
+};
+struct media_v2_interface {
- __u32 id;
- __u32 intf_type;
- __u32 flags;
- __u32 reserved[9];
- union {
struct media_v2_intf_devnode devnode;
__u32 raw[16];
- };
+};
+struct media_v2_pad {
- __u32 id;
- __u32 entity_id;
- __u32 flags;
- __u16 reserved[9];
Any particular reason for an odd number of 16-bit reserved fields? :-)
Ask Hans. I just used his RFC design here ;)
Same reason as above: if memory serves the flags field was originally a u16, but now that it is a u32 it makes no sense anymore to use u16 for reserved[].
+};
+struct media_v2_link {
- __u32 id;
- __u32 source_id;
- __u32 sink_id;
- __u32 flags;
- __u32 reserved[5];
+};
+struct media_v2_topology {
- __u32 topology_version;
- __u32 num_entities;
- struct media_v2_entity *entities;
- __u32 num_interfaces;
- struct media_v2_interface *interfaces;
If you added reserved fields to align the pointers to 64 bits we'd get away with some error-prone compat code.
Maybe. It seems that arm64 has some differences with regards to struct aligns. I didn't analyze yet what are the arch differences, but I suspect that we may need to add some compat code anyway.
I'm open to suggestions.
You need compat code anyway. Pointers have after all different sizes, so this will require compat32 code.
Regards,
Hans
Hi Mauro,
On Wed, Oct 14, 2015 at 11:26:00PM -0300, Mauro Carvalho Chehab wrote:
Em Tue, 13 Oct 2015 08:09:53 -0300 Mauro Carvalho Chehab mchehab@osg.samsung.com escreveu:
Em Tue, 13 Oct 2015 12:16:51 +0300 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:38PM -0300, Mauro Carvalho Chehab wrote:
Add a new ioctl that will report the entire topology on one go.
Change-Id: Ic022469be237dcaca56a077073b404f7de21f655 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7320cdc45833..2d5ad40254b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf;
- /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor;
}; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index a1bd7afba110..b17f6763aff4 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
How about removing the extra spaces between # and define? Or were they intended?
They're intended. This is a common way to tell that the two defines below are related to the first one.
Sorry, I didn't see the other comments. See below.
struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -249,11 +253,93 @@ struct media_links_enum { #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 */ +/*
- MC next gen API definitions
- NOTE: The declarations below are close to the MC RFC for the Media
Controller, the next generation. Yet, there are a few adjustments
to do, as we want to be able to have a functional API before
the MC properties change. Those will be properly marked below.
Please also notice that I removed "num_pads", "num_links",
from the proposal, as a proper userspace application will likely
use lists for pads/links, just as we intend to do in Kernelspace.
The API definition should be freed from fields that are bound to
some specific data structure.
- FIXME: Currently, I opted to name the new types as "media_v2", as this
won't cause any conflict with the Kernelspace namespace, nor with
the previous kAPI media_*_desc namespace. This can be changed
later, before the adding this API upstream.
- */
+struct media_v2_entity {
- __u32 id;
- char name[64]; /* FIXME: move to a property? (RFC says so) */
That indeed requires the property API. We can't have it this week or next (and perhaps not next month either). Shall we wait, use a temporary field (and remind the user that the API is experimental) or go without name (which is rather important)?
I think clearly labelling this experimental would be the thing to do, and then after some time remove the name field. Albeit historically APIs marked clearly as experimental have been used by applications and then fixing those APIs has been no-go since the applications already use them. Oh, well...
I added the FIXME due to a purpose: IMHO, despite the discussions we had at the MC summit, I think we should keep the name at the main struct.
The rationale is that, unlikely other properties that are typically optional, the name is mandatory, as we want all entities to have a name. By having it at the struct, we'll be sure about that. Ok, the drawback is that we'll waste space at the ioctl, so, I'm not 100% sure about that.
In any case, we should address this before having the API at a released Kernel.
I mean: we need to decide if the entity name will be at a property or at struct media_v2_entity. If we decide to put it on a property, we should just remove the name there and comment the part of the mc_nextgen_test that uses it, uncommenting (and changing accordingly) only when we merge the properties API.
Otherwise, we should remove the /* FIXME */ from it.
Comments?
I think the name should be visible as a property independently of whether it's part of the struct or not. I have no objections to putting it to the struct, however.
If you do need the name in the user space using this API which I believe you do, having no name field would essentially make the set depend on the property API which will take quite some time to design in detail level, implement and agree on.
- __u16 reserved[14];
How about 32-bit fields instead? I think the only reason to have 16-bit reserved fields is to align 16-bit aligned fields to higher alignment, but this is not the case here.
That came from hverkuil's RFC/suggestion. I don't have any strong opinion about that.
So should be __32's instead.
+};
+/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode {
- __u32 major;
- __u32 minor;
+};
+struct media_v2_interface {
- __u32 id;
- __u32 intf_type;
- __u32 flags;
- __u32 reserved[9];
- union {
struct media_v2_intf_devnode devnode;
__u32 raw[16];
- };
+};
+struct media_v2_pad {
- __u32 id;
- __u32 entity_id;
- __u32 flags;
- __u16 reserved[9];
Any particular reason for an odd number of 16-bit reserved fields? :-)
Ask Hans. I just used his RFC design here ;)
+};
+struct media_v2_link {
- __u32 id;
- __u32 source_id;
- __u32 sink_id;
- __u32 flags;
- __u32 reserved[5];
+};
+struct media_v2_topology {
- __u32 topology_version;
- __u32 num_entities;
- struct media_v2_entity *entities;
- __u32 num_interfaces;
- struct media_v2_interface *interfaces;
If you added reserved fields to align the pointers to 64 bits we'd get away with some error-prone compat code.
Maybe. It seems that arm64 has some differences with regards to struct aligns. I didn't analyze yet what are the arch differences, but I suspect that we may need to add some compat code anyway.
I'm open to suggestions.
These should also have the __user modifier.
I have to check, but I guess __user should not be used at the struct definition at the .h, but when using it at media_device.c.
If you have a pointer in a struct that's used in a user space header, the __user should be there AFAIU. It's stripped out by make headers_install anyway.
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Add a new ioctl that will report the entire topology on one go.
Change-Id: Ic022469be237dcaca56a077073b404f7de21f655 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7320cdc45833..2d5ad40254b7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf;
- /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor;
}; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index a1bd7afba110..b17f6763aff4 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2)
+#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28)
struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -249,11 +253,93 @@ struct media_links_enum { #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 */ +/*
- MC next gen API definitions
- NOTE: The declarations below are close to the MC RFC for the Media
Controller, the next generation. Yet, there are a few adjustments
to do, as we want to be able to have a functional API before
the MC properties change. Those will be properly marked below.
Please also notice that I removed "num_pads", "num_links",
from the proposal, as a proper userspace application will likely
use lists for pads/links, just as we intend to do in Kernelspace.
The API definition should be freed from fields that are bound to
some specific data structure.
- FIXME: Currently, I opted to name the new types as "media_v2", as this
won't cause any conflict with the Kernelspace namespace, nor with
the previous kAPI media_*_desc namespace. This can be changed
later, before the adding this API upstream.
- */
+struct media_v2_entity {
- __u32 id;
- char name[64]; /* FIXME: move to a property? (RFC says so) */
- __u16 reserved[14];
+};
+/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode {
- __u32 major;
- __u32 minor;
+};
+struct media_v2_interface {
- __u32 id;
- __u32 intf_type;
- __u32 flags;
- __u32 reserved[9];
- union {
struct media_v2_intf_devnode devnode;
__u32 raw[16];
- };
+};
+struct media_v2_pad {
- __u32 id;
- __u32 entity_id;
- __u32 flags;
- __u16 reserved[9];
+};
+struct media_v2_link {
- __u32 id;
- __u32 source_id;
- __u32 sink_id;
- __u32 flags;
- __u32 reserved[5];
+};
+struct media_v2_topology {
- __u32 topology_version;
- __u32 num_entities;
- struct media_v2_entity *entities;
- __u32 num_interfaces;
- struct media_v2_interface *interfaces;
- __u32 num_pads;
- struct media_v2_pad *pads;
- __u32 num_links;
- struct media_v2_link *links;
- struct {
__u32 reserved_num;
void *reserved_ptr;
- } reserved_types[16];
- __u32 reserved[8];
+};
+/* ioctls */
#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) +#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology)
#endif /* __LINUX_MEDIA_H */
Just like we do with entities, use a similar macro for the interfaces loop.
Change-Id: I1ecc416de912fb9ffe86decf22d654bd20ba313e Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/dvb-core/dvbdev.c | 3 ++- include/media/media-device.h | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 6babc688801b..f00f1a5f279c 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -578,9 +578,10 @@ void dvb_create_media_graph(struct dvb_adapter *adap) }
/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ - list_for_each_entry(intf, &mdev->interfaces, list) { + media_device_for_each_intf(intf, mdev) { 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);
diff --git a/include/media/media-device.h b/include/media/media-device.h index 51807efa505b..f23d686aaac6 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -113,6 +113,11 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_entity(entity, mdev) \ list_for_each_entry(entity, &(mdev)->entities, list)
+/* Iterate over all interfaces. */ +#define media_device_for_each_intf(intf, mdev) \ + list_for_each_entry(intf, &(mdev)->interfaces, list) + + #else static inline int media_device_register(struct media_device *mdev) {
Let's control the topology changes inside the graph_object. So, move the addition and removal of interfaces/entities from the mdev lists to media_gobj_init() and media_gobj_remove().
The main reason is that mdev should have lists for all object types, as the new MC api will require to store objects in separate places.
Change-Id: I19c66e6ca3962eded9c6e068d1827ae8bd3a6d88 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 4 +--- drivers/media/media-entity.c | 15 ++++++++++++--- include/media/media-device.h | 4 ++-- include/media/media-entity.h | 3 +-- 4 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 134fe7510195..ec98595b8a7a 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -415,7 +415,7 @@ void media_device_unregister(struct media_device *mdev) struct media_entity *entity; struct media_entity *next;
- list_for_each_entry_safe(entity, next, &mdev->entities, list) + list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) media_device_unregister_entity(entity);
device_remove_file(&mdev->devnode.dev, &dev_attr_model); @@ -449,7 +449,6 @@ int __must_check media_device_register_entity(struct media_device *mdev, spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); - list_add_tail(&entity->list, &mdev->entities);
/* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++) @@ -487,7 +486,6 @@ void media_device_unregister_entity(struct media_entity *entity) for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj); - list_del(&entity->list); spin_unlock(&mdev->lock); entity->graph_obj.mdev = NULL; } diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 6ed5eef88593..cbb0604e81c1 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -170,6 +170,7 @@ void media_gobj_init(struct media_device *mdev, switch (type) { case MEDIA_GRAPH_ENTITY: gobj->id = media_gobj_gen_id(type, ++mdev->entity_id); + list_add_tail(&gobj->list, &mdev->entities); break; case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); @@ -178,6 +179,7 @@ void media_gobj_init(struct media_device *mdev, gobj->id = media_gobj_gen_id(type, ++mdev->link_id); break; case MEDIA_GRAPH_INTF_DEVNODE: + list_add_tail(&gobj->list, &mdev->interfaces); gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id); break; } @@ -193,6 +195,16 @@ void media_gobj_init(struct media_device *mdev, */ void media_gobj_remove(struct media_gobj *gobj) { + /* Remove the object from mdev list */ + switch (media_type(gobj)) { + case MEDIA_GRAPH_ENTITY: + case MEDIA_GRAPH_INTF_DEVNODE: + list_del(&gobj->list); + break; + default: + break; + } + dev_dbg_obj(__func__, gobj); }
@@ -864,8 +876,6 @@ 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 */ @@ -894,7 +904,6 @@ 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); diff --git a/include/media/media-device.h b/include/media/media-device.h index f23d686aaac6..85fa302047bd 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -111,11 +111,11 @@ struct media_device *media_device_find_devres(struct device *dev);
/* Iterate over all entities. */ #define media_device_for_each_entity(entity, mdev) \ - list_for_each_entry(entity, &(mdev)->entities, list) + list_for_each_entry(entity, &(mdev)->entities, graph_obj.list)
/* Iterate over all interfaces. */ #define media_device_for_each_intf(intf, mdev) \ - list_for_each_entry(intf, &(mdev)->interfaces, list) + list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
#else diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 2d5ad40254b7..bc7eb6240795 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -66,6 +66,7 @@ enum media_gobj_type { struct media_gobj { struct media_device *mdev; u32 id; + struct list_head list; };
@@ -114,7 +115,6 @@ struct media_entity_operations {
struct media_entity { 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_*) */ u32 revision; /* Entity revision, driver specific */ @@ -166,7 +166,6 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj; - struct list_head list; struct list_head links; u32 type; u32 flags;
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Let's control the topology changes inside the graph_object. So, move the addition and removal of interfaces/entities from the mdev lists to media_gobj_init() and media_gobj_remove().
The main reason is that mdev should have lists for all object types, as the new MC api will require to store objects in separate places.
Change-Id: I19c66e6ca3962eded9c6e068d1827ae8bd3a6d88 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-device.c | 4 +--- drivers/media/media-entity.c | 15 ++++++++++++--- include/media/media-device.h | 4 ++-- include/media/media-entity.h | 3 +-- 4 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 134fe7510195..ec98595b8a7a 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -415,7 +415,7 @@ void media_device_unregister(struct media_device *mdev) struct media_entity *entity; struct media_entity *next;
- list_for_each_entry_safe(entity, next, &mdev->entities, list)
list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list) media_device_unregister_entity(entity);
device_remove_file(&mdev->devnode.dev, &dev_attr_model);
@@ -449,7 +449,6 @@ int __must_check media_device_register_entity(struct media_device *mdev, spin_lock(&mdev->lock); /* Initialize media_gobj embedded at the entity */ media_gobj_init(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
list_add_tail(&entity->list, &mdev->entities);
/* Initialize objects at the pads */ for (i = 0; i < entity->num_pads; i++)
@@ -487,7 +486,6 @@ void media_device_unregister_entity(struct media_entity *entity) for (i = 0; i < entity->num_pads; i++) media_gobj_remove(&entity->pads[i].graph_obj); media_gobj_remove(&entity->graph_obj);
- list_del(&entity->list); spin_unlock(&mdev->lock); entity->graph_obj.mdev = NULL;
} diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 6ed5eef88593..cbb0604e81c1 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -170,6 +170,7 @@ void media_gobj_init(struct media_device *mdev, switch (type) { case MEDIA_GRAPH_ENTITY: gobj->id = media_gobj_gen_id(type, ++mdev->entity_id);
break; case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id);list_add_tail(&gobj->list, &mdev->entities);
@@ -178,6 +179,7 @@ void media_gobj_init(struct media_device *mdev, 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);list_add_tail(&gobj->list, &mdev->interfaces);
I'd swap these lines: first set the id, then add to the list.
After this change you can add my:
Acked-by: Hans Verkuil hans.verkuil@cisco.com
(Ah, you swapped it in patch 52. It's better to do it right here.)
Hans
break;
} @@ -193,6 +195,16 @@ void media_gobj_init(struct media_device *mdev, */ void media_gobj_remove(struct media_gobj *gobj) {
- /* Remove the object from mdev list */
- switch (media_type(gobj)) {
- case MEDIA_GRAPH_ENTITY:
- case MEDIA_GRAPH_INTF_DEVNODE:
list_del(&gobj->list);
break;
- default:
break;
- }
- dev_dbg_obj(__func__, gobj);
}
@@ -864,8 +876,6 @@ 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 */ @@ -894,7 +904,6 @@ 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); diff --git a/include/media/media-device.h b/include/media/media-device.h index f23d686aaac6..85fa302047bd 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -111,11 +111,11 @@ struct media_device *media_device_find_devres(struct device *dev);
/* Iterate over all entities. */ #define media_device_for_each_entity(entity, mdev) \
- list_for_each_entry(entity, &(mdev)->entities, list)
- list_for_each_entry(entity, &(mdev)->entities, graph_obj.list)
/* Iterate over all interfaces. */ #define media_device_for_each_intf(intf, mdev) \
- list_for_each_entry(intf, &(mdev)->interfaces, list)
- list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
#else diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 2d5ad40254b7..bc7eb6240795 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -66,6 +66,7 @@ enum media_gobj_type { struct media_gobj { struct media_device *mdev; u32 id;
- struct list_head list;
};
@@ -114,7 +115,6 @@ struct media_entity_operations {
struct media_entity { 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_*) */ u32 revision; /* Entity revision, driver specific */
@@ -166,7 +166,6 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj;
- struct list_head list; struct list_head links; u32 type; u32 flags;
The MC next gen API sends objects to userspace grouped by their types.
In the case of pads and links, in order to improve performance and have a simpler code, the best is to store them also on separate linked lists at MC.
If we don't do that, we would need this kind of interaction to send data to userspace (code is in structured english):
for each entity: for each pad: store pads
for each entity: for each link: store link
for each interface: for each link: store link
With would require one nexted loop for pads and two nested loops for links. By using separate linked lists for them, just one loop would be enough.
Change-Id: I61984a57cc22e07c3cddaa8b304846155a67a515 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-device.c | 2 ++ drivers/media/media-entity.c | 17 ++++++----------- include/media/media-device.h | 12 ++++++++++++ 3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index ec98595b8a7a..5b2c9f7fcd45 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -382,6 +382,8 @@ int __must_check __media_device_register(struct media_device *mdev,
INIT_LIST_HEAD(&mdev->entities); INIT_LIST_HEAD(&mdev->interfaces); + INIT_LIST_HEAD(&mdev->pads); + INIT_LIST_HEAD(&mdev->links); spin_lock_init(&mdev->lock); mutex_init(&mdev->graph_mutex);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index cbb0604e81c1..568553d41f5d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -174,13 +174,15 @@ void media_gobj_init(struct media_device *mdev, break; case MEDIA_GRAPH_PAD: gobj->id = media_gobj_gen_id(type, ++mdev->pad_id); + list_add_tail(&gobj->list, &mdev->pads); break; case MEDIA_GRAPH_LINK: gobj->id = media_gobj_gen_id(type, ++mdev->link_id); + list_add_tail(&gobj->list, &mdev->links); break; case MEDIA_GRAPH_INTF_DEVNODE: - list_add_tail(&gobj->list, &mdev->interfaces); gobj->id = media_gobj_gen_id(type, ++mdev->intf_devnode_id); + list_add_tail(&gobj->list, &mdev->interfaces); break; } dev_dbg_obj(__func__, gobj); @@ -195,17 +197,10 @@ void media_gobj_init(struct media_device *mdev, */ void media_gobj_remove(struct media_gobj *gobj) { - /* Remove the object from mdev list */ - switch (media_type(gobj)) { - case MEDIA_GRAPH_ENTITY: - case MEDIA_GRAPH_INTF_DEVNODE: - list_del(&gobj->list); - break; - default: - break; - } - dev_dbg_obj(__func__, gobj); + + /* Remove the object from mdev list */ + list_del(&gobj->list); }
/** diff --git a/include/media/media-device.h b/include/media/media-device.h index 85fa302047bd..0d1b9c687454 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -47,6 +47,8 @@ struct device; * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities * @interfaces: List of registered interfaces + * @pads: List of registered pads + * @links: List of registered links * @lock: Entities list lock * @graph_mutex: Entities graph operation lock * @link_notify: Link state change notification callback @@ -79,6 +81,8 @@ struct media_device {
struct list_head entities; struct list_head interfaces; + struct list_head pads; + struct list_head links;
/* Protects the entities list */ spinlock_t lock; @@ -117,6 +121,14 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_intf(intf, mdev) \ list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list)
+/* Iterate over all pads. */ +#define media_device_for_each_pad(pad, mdev) \ + list_for_each_entry(pad, &(mdev)->pads, graph_obj.list) + +/* Iterate over all links. */ +#define media_device_for_each_link(link, mdev) \ + list_for_each_entry(link, &(mdev)->links, graph_obj.list) +
#else static inline int media_device_register(struct media_device *mdev)
Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.
Change-Id: Ia97d27960399ca7d98b1d3d32d8622286387d7a8 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-entity.c | 5 +++++ include/media/media-device.h | 4 ++++ 2 files changed, 9 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 568553d41f5d..064515f2ba9b 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -185,6 +185,9 @@ void media_gobj_init(struct media_device *mdev, list_add_tail(&gobj->list, &mdev->interfaces); break; } + + mdev->topology_version++; + dev_dbg_obj(__func__, gobj); }
@@ -199,6 +202,8 @@ void media_gobj_remove(struct media_gobj *gobj) { dev_dbg_obj(__func__, gobj);
+ gobj->mdev->topology_version++; + /* Remove the object from mdev list */ list_del(&gobj->list); } diff --git a/include/media/media-device.h b/include/media/media-device.h index 0d1b9c687454..1b12774a9ab4 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -41,6 +41,8 @@ struct device; * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision * @driver_version: Device driver version + * @topology_version: Monotonic counter for storing the version of the graph + * topology. Should be incremented each time the topology changes. * @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 @@ -74,6 +76,8 @@ struct media_device { u32 hw_revision; u32 driver_version;
+ u32 topology_version; + u32 entity_id; u32 pad_id; u32 link_id;
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it.
Change-Id: Ia97d27960399ca7d98b1d3d32d8622286387d7a8 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-entity.c | 5 +++++ include/media/media-device.h | 4 ++++ 2 files changed, 9 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 568553d41f5d..064515f2ba9b 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -185,6 +185,9 @@ void media_gobj_init(struct media_device *mdev, list_add_tail(&gobj->list, &mdev->interfaces); break; }
- mdev->topology_version++;
- dev_dbg_obj(__func__, gobj);
}
@@ -199,6 +202,8 @@ void media_gobj_remove(struct media_gobj *gobj) { dev_dbg_obj(__func__, gobj);
- gobj->mdev->topology_version++;
- /* Remove the object from mdev list */ list_del(&gobj->list);
} diff --git a/include/media/media-device.h b/include/media/media-device.h index 0d1b9c687454..1b12774a9ab4 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -41,6 +41,8 @@ struct device;
- @bus_info: Unique and stable device location identifier
- @hw_revision: Hardware device revision
- @driver_version: Device driver version
- @topology_version: Monotonic counter for storing the version of the graph
topology. Should be incremented each time the topology changes.
- @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
@@ -74,6 +76,8 @@ struct media_device { u32 hw_revision; u32 driver_version;
- u32 topology_version;
- u32 entity_id; u32 pad_id; u32 link_id;
Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation.
Change-Id: I6b499617d7a4ebb51f24c1d06f34761f6c61ce06 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 158 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 5b2c9f7fcd45..96a476eeb16e 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -232,6 +232,156 @@ static long media_device_setup_link(struct media_device *mdev, return ret; }
+static long __media_device_get_topology(struct media_device *mdev, + struct media_v2_topology *topo) +{ + struct media_entity *entity; + struct media_interface *intf; + struct media_pad *pad; + struct media_link *link; + struct media_v2_entity uentity; + struct media_v2_interface uintf; + struct media_v2_pad upad; + struct media_v2_link ulink; + int ret = 0, i; + + topo->topology_version = mdev->topology_version; + + /* Get entities and number of entities */ + i = 0; + media_device_for_each_entity(entity, mdev) { + i++; + + if (ret || !topo->entities) + continue; + + if (i > topo->num_entities) { + ret = -ENOSPC; + continue; + } + + /* Copy fields to userspace struct if not error */ + memset(&uentity, 0, sizeof(uentity)); + uentity.id = entity->graph_obj.id; + strncpy(uentity.name, entity->name, + sizeof(uentity.name)); + + if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity))) + ret = -EFAULT; + } + topo->num_entities = i; + + /* Get interfaces and number of interfaces */ + i = 0; + media_device_for_each_intf(intf, mdev) { + i++; + + if (ret || !topo->interfaces) + continue; + + if (i > topo->num_interfaces) { + ret = -ENOSPC; + continue; + } + + memset(&uintf, 0, sizeof(uintf)); + + /* Copy intf fields to userspace struct */ + uintf.id = intf->graph_obj.id; + uintf.intf_type = intf->type; + uintf.flags = intf->flags; + + if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) { + struct media_intf_devnode *devnode; + + devnode = intf_to_devnode(intf); + + uintf.devnode.major = devnode->major; + uintf.devnode.minor = devnode->minor; + } + + if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf))) + ret = -EFAULT; + } + topo->num_interfaces = i; + + /* Get pads and number of pads */ + i = 0; + media_device_for_each_pad(pad, mdev) { + i++; + + if (ret || !topo->pads) + continue; + + if (i > topo->num_pads) { + ret = -ENOSPC; + continue; + } + + memset(&upad, 0, sizeof(upad)); + + /* Copy pad fields to userspace struct */ + upad.id = pad->graph_obj.id; + upad.entity_id = pad->entity->graph_obj.id; + upad.flags = pad->flags; + + if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad))) + ret = -EFAULT; + } + topo->num_pads = i; + + /* Get links and number of links */ + i = 0; + media_device_for_each_link(link, mdev) { + i++; + + if (ret || !topo->links) + continue; + + if (i > topo->num_links) { + ret = -ENOSPC; + continue; + } + + memset(&ulink, 0, sizeof(ulink)); + + /* Copy link fields to userspace struct */ + ulink.id = link->graph_obj.id; + ulink.source_id = link->gobj0->id; + ulink.sink_id = link->gobj1->id; + ulink.flags = link->flags; + + if (media_type(link->gobj0) != MEDIA_GRAPH_PAD) + ulink.flags |= MEDIA_LNK_FL_INTERFACE_LINK; + + if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink))) + ret = -EFAULT; + } + topo->num_links = i; + + return ret; +} + +static long media_device_get_topology(struct media_device *mdev, + struct media_v2_topology __user *utopo) +{ + struct media_v2_topology ktopo; + int ret; + + ret = copy_from_user(&ktopo, utopo, sizeof(ktopo)); + + if (ret < 0) + return ret; + + ret = __media_device_get_topology(mdev, &ktopo); + if (ret < 0) + return ret; + + ret = copy_to_user(utopo, &ktopo, sizeof(*utopo)); + + return ret; +} + static long media_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -264,6 +414,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, mutex_unlock(&dev->graph_mutex); break;
+ case MEDIA_IOC_G_TOPOLOGY: + mutex_lock(&dev->graph_mutex); + ret = media_device_get_topology(dev, + (struct media_v2_topology __user *)arg); + mutex_unlock(&dev->graph_mutex); + break; + default: ret = -ENOIOCTLCMD; } @@ -312,6 +469,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, case MEDIA_IOC_DEVICE_INFO: case MEDIA_IOC_ENUM_ENTITIES: case MEDIA_IOC_SETUP_LINK: + case MEDIA_IOC_G_TOPOLOGY: return media_device_ioctl(filp, cmd, arg);
case MEDIA_IOC_ENUM_LINKS32:
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Add support for the new MEDIA_IOC_G_TOPOLOGY ioctl, according with the RFC for the MC next generation.
Change-Id: I6b499617d7a4ebb51f24c1d06f34761f6c61ce06 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-device.c | 158 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 5b2c9f7fcd45..96a476eeb16e 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -232,6 +232,156 @@ static long media_device_setup_link(struct media_device *mdev, return ret; }
+static long __media_device_get_topology(struct media_device *mdev,
struct media_v2_topology *topo)
+{
- struct media_entity *entity;
- struct media_interface *intf;
- struct media_pad *pad;
- struct media_link *link;
- struct media_v2_entity uentity;
- struct media_v2_interface uintf;
- struct media_v2_pad upad;
- struct media_v2_link ulink;
I'd move these media_v2_ structs in a union: you use only one at a time, so there is no need to allocate them all on the stack.
- int ret = 0, i;
- topo->topology_version = mdev->topology_version;
- /* Get entities and number of entities */
- i = 0;
- media_device_for_each_entity(entity, mdev) {
i++;
if (ret || !topo->entities)
continue;
if (i > topo->num_entities) {
ret = -ENOSPC;
continue;
}
/* Copy fields to userspace struct if not error */
memset(&uentity, 0, sizeof(uentity));
uentity.id = entity->graph_obj.id;
strncpy(uentity.name, entity->name,
sizeof(uentity.name));
Use strlcpy.
if (copy_to_user(&topo->entities[i - 1], &uentity, sizeof(uentity)))
ret = -EFAULT;
- }
- topo->num_entities = i;
- /* Get interfaces and number of interfaces */
- i = 0;
- media_device_for_each_intf(intf, mdev) {
i++;
if (ret || !topo->interfaces)
continue;
if (i > topo->num_interfaces) {
ret = -ENOSPC;
continue;
}
memset(&uintf, 0, sizeof(uintf));
/* Copy intf fields to userspace struct */
uintf.id = intf->graph_obj.id;
uintf.intf_type = intf->type;
uintf.flags = intf->flags;
if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) {
struct media_intf_devnode *devnode;
devnode = intf_to_devnode(intf);
uintf.devnode.major = devnode->major;
uintf.devnode.minor = devnode->minor;
}
if (copy_to_user(&topo->interfaces[i - 1], &uintf, sizeof(uintf)))
ret = -EFAULT;
- }
- topo->num_interfaces = i;
- /* Get pads and number of pads */
- i = 0;
- media_device_for_each_pad(pad, mdev) {
i++;
if (ret || !topo->pads)
continue;
if (i > topo->num_pads) {
ret = -ENOSPC;
continue;
}
memset(&upad, 0, sizeof(upad));
/* Copy pad fields to userspace struct */
upad.id = pad->graph_obj.id;
upad.entity_id = pad->entity->graph_obj.id;
upad.flags = pad->flags;
if (copy_to_user(&topo->pads[i - 1], &upad, sizeof(upad)))
ret = -EFAULT;
- }
- topo->num_pads = i;
- /* Get links and number of links */
- i = 0;
- media_device_for_each_link(link, mdev) {
i++;
if (ret || !topo->links)
continue;
if (i > topo->num_links) {
ret = -ENOSPC;
continue;
}
memset(&ulink, 0, sizeof(ulink));
/* Copy link fields to userspace struct */
ulink.id = link->graph_obj.id;
ulink.source_id = link->gobj0->id;
ulink.sink_id = link->gobj1->id;
ulink.flags = link->flags;
if (media_type(link->gobj0) != MEDIA_GRAPH_PAD)
ulink.flags |= MEDIA_LNK_FL_INTERFACE_LINK;
if (copy_to_user(&topo->links[i - 1], &ulink, sizeof(ulink)))
ret = -EFAULT;
- }
- topo->num_links = i;
- return ret;
+}
+static long media_device_get_topology(struct media_device *mdev,
struct media_v2_topology __user *utopo)
+{
- struct media_v2_topology ktopo;
- int ret;
- ret = copy_from_user(&ktopo, utopo, sizeof(ktopo));
- if (ret < 0)
return ret;
This should be:
if (copy_from_user(&ktopo, utopo, sizeof(ktopo))) return -EFAULT;
- ret = __media_device_get_topology(mdev, &ktopo);
- if (ret < 0)
return ret;
- ret = copy_to_user(utopo, &ktopo, sizeof(*utopo));
Ditto.
These functions do not return a traditional linux error.
- return ret;
+}
static long media_device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -264,6 +414,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, mutex_unlock(&dev->graph_mutex); break;
- case MEDIA_IOC_G_TOPOLOGY:
mutex_lock(&dev->graph_mutex);
ret = media_device_get_topology(dev,
(struct media_v2_topology __user *)arg);
mutex_unlock(&dev->graph_mutex);
break;
- default: ret = -ENOIOCTLCMD; }
@@ -312,6 +469,7 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd, case MEDIA_IOC_DEVICE_INFO: case MEDIA_IOC_ENUM_ENTITIES: case MEDIA_IOC_SETUP_LINK:
case MEDIA_IOC_G_TOPOLOGY: return media_device_ioctl(filp, cmd, arg);
case MEDIA_IOC_ENUM_LINKS32:
Regards,
Hans
Add functions to explicitly unregister all entity links. This function is called automatically when an entity link is destroyed.
Change-Id: I186b4fd5ab80439946c22e1d92cd80aad1203d0d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Acked-by: Hans Verkuil hans.verkuil@cisco.com --- drivers/media/media-entity.c | 23 +++++++++++++++++++++++ include/media/media-entity.h | 3 +++ 2 files changed, 26 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 064515f2ba9b..a37ccd2edfd5 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -903,6 +903,7 @@ EXPORT_SYMBOL_GPL(media_devnode_create);
void media_devnode_remove(struct media_intf_devnode *devnode) { + media_remove_intf_links(&devnode->intf); media_gobj_remove(&devnode->intf.graph_obj); kfree(devnode); } @@ -944,3 +945,25 @@ void media_remove_intf_link(struct media_link *link) mutex_unlock(&link->graph_obj.mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_remove_intf_link); + +void __media_remove_intf_links(struct media_interface *intf) +{ + struct media_link *link, *tmp; + + list_for_each_entry_safe(link, tmp, &intf->links, list) + __media_remove_intf_link(link); + +} +EXPORT_SYMBOL_GPL(__media_remove_intf_links); + +void media_remove_intf_links(struct media_interface *intf) +{ + /* Do nothing if the intf is not registered. */ + if (intf->graph_obj.mdev == NULL) + return; + + mutex_lock(&intf->graph_obj.mdev->graph_mutex); + __media_remove_intf_links(intf); + mutex_unlock(&intf->graph_obj.mdev->graph_mutex); +} +EXPORT_SYMBOL_GPL(media_remove_intf_links); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index bc7eb6240795..ca4a4f23362f 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -318,6 +318,9 @@ 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); +void __media_remove_intf_links(struct media_interface *intf); +void media_remove_intf_links(struct media_interface *intf); +
#define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \
Interface links connected to an entity should be removed before being able of removing the entity.
Change-Id: I18377e05409c7f1d594f02e35bffdd99620dd07d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 96a476eeb16e..7c37aeab05bb 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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; }
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Interface links connected to an entity should be removed before being able of removing the entity.
Change-Id: I18377e05409c7f1d594f02e35bffdd99620dd07d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 96a476eeb16e..7c37aeab05bb 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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;
}
Just like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there.
Change-Id: I51c1742fe071965f4606d98ed890712e81a1d4d9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 17 ++++++++++++++++- drivers/media/media-entity.c | 4 ++++ include/media/media-entity.h | 13 +++++++++---- 3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 7c37aeab05bb..0238885fcc74 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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); }
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a37ccd2edfd5..cd4d767644df 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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); }
/** diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ca4a4f23362f..fb5f0e21f137 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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)
Hi Mauro,
On Mon, Oct 12, 2015 at 01:43:46PM -0300, 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.
Change-Id: I51c1742fe071965f4606d98ed890712e81a1d4d9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-device.c | 17 ++++++++++++++++- drivers/media/media-entity.c | 4 ++++ include/media/media-entity.h | 13 +++++++++---- 3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 7c37aeab05bb..0238885fcc74 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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);
- }
Do you need to remove the interface links explicitly? Doesn't media_device_unregister_entity() already do that below? Same comment on the data links below btw.
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);
kfree(link); }list_del(&link->list);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a37ccd2edfd5..cd4d767644df 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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);
}
/** diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ca4a4f23362f..fb5f0e21f137 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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)
On 10/12/2015 06:43 PM, 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.
Change-Id: I51c1742fe071965f4606d98ed890712e81a1d4d9 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 17 ++++++++++++++++- drivers/media/media-entity.c | 4 ++++ include/media/media-entity.h | 13 +++++++++---- 3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 7c37aeab05bb..0238885fcc74 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -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);
kfree(link); }list_del(&link->list);
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index a37ccd2edfd5..cd4d767644df 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -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);
}
/** diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ca4a4f23362f..fb5f0e21f137 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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)
au0828_analog_unregister() calls video_unregister_device(), with, in turn, calls media_devnode_remove() in order to drop the media interfaces.
We can't release the media controller before that, or an OOPS will occur:
[ 176.938752] usb 1-4.4: Media device released [ 176.938753] usb 1-4.4: Media device unregistered [ 177.091235] general protection fault: 0000 [#1] SMP [ 177.091253] Modules linked in: ir_lirc_codec ir_xmp_decoder lirc_dev ir_mce_kbd_decoder ir_sharp_decoder ir_sanyo_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_nec_decoder ir_rc5_decoder au8522_dig xc5000 tuner au8522_decoder au8522_common au0828(-) videobuf2_vmalloc videobuf2_memops tveeprom videobuf2_core dvb_core rc_core v4l2_common videodev media cpufreq_powersave cpufreq_conservative cpufreq_userspace cpufreq_stats parport_pc ppdev lp parport snd_hda_codec_hdmi i915 x86_pkg_temp_thermal intel_powerclamp intel_rapl iosf_mbi coretemp kvm_intel kvm btusb crct10dif_pclmul snd_hda_codec_realtek crc32_pclmul btrtl crc32c_intel btbcm snd_hda_codec_generic ghash_clmulni_intel btintel i2c_algo_bit drm_kms_helper bluetooth iTCO_wdt snd_usb_audio snd_hda_intel iTCO_vendor_support jitterentropy_rng [ 177.091455] snd_hda_codec evdev sha256_ssse3 drm sha256_generic hmac snd_usbmidi_lib snd_hwdep snd_hda_core snd_rawmidi drbg snd_seq_device snd_pcm aesni_intel aes_x86_64 lrw gf128mul mei_me glue_helper snd_timer ablk_helper cryptd mei rfkill snd psmouse sg shpchp soundcore lpc_ich serio_raw i2c_i801 pcspkr mfd_core tpm_tis tpm battery dw_dmac video i2c_designware_platform dw_dmac_core i2c_designware_core acpi_pad processor button ext4 crc16 mbcache jbd2 dm_mod sd_mod ahci libahci libata e1000e scsi_mod ptp pps_core ehci_pci xhci_pci ehci_hcd xhci_hcd thermal fan thermal_sys sdhci_acpi sdhci mmc_core i2c_hid hid [last unloaded: rc_core] [ 177.091632] CPU: 1 PID: 18040 Comm: rmmod Tainted: G W 4.2.0-rc2+ #9 [ 177.091648] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/NUC5i7RYB, BIOS RYBDWi35.86A.0246.2015.0309.1355 03/09/2015 [ 177.091677] task: ffff88040811b080 ti: ffff880036b88000 task.ti: ffff880036b88000 [ 177.091693] RIP: 0010:[<ffffffff810aecc3>] [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.091718] RSP: 0018:ffff880036b8bcd8 EFLAGS: 00010202 [ 177.091730] RAX: 0000000000003ffe RBX: ffff880407e11b70 RCX: ffff88041ec962c0 [ 177.091745] RDX: 7463656a62506357 RSI: 0000000000080000 RDI: ffff880407e11b74 [ 177.091760] RBP: ffff880407e11b74 R08: 0000000000000001 R09: ffffffff812bf4e0 [ 177.091776] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88040811b080 [ 177.091791] R13: ffff88003601cec8 R14: ffff8804084b8890 R15: ffff8804084b8800 [ 177.091807] FS: 00007f2f9bab1700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000 [ 177.091824] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 177.091837] CR2: 00007fe8c0f900e0 CR3: 0000000035c47000 CR4: 00000000003407e0 [ 177.091852] Stack: [ 177.091857] ffffffff81562e3d ffffffff815613b3 0000000000000000 0000000000000000 [ 177.091876] ffff88040b6d3240 ffff8804084b8890 ffff880407e11b70 ffff88003601cd30 [ 177.091895] ffff88003601ce28 ffff88003601cec8 ffff8804084b8890 ffffffff8156148b [ 177.091914] Call Trace: [ 177.091923] [<ffffffff81562e3d>] ? _raw_spin_lock+0x1d/0x20 [ 177.091936] [<ffffffff815613b3>] ? __mutex_lock_slowpath+0x43/0x100 [ 177.091951] [<ffffffff8156148b>] ? mutex_lock+0x1b/0x30 [ 177.091965] [<ffffffffa028480d>] ? media_remove_intf_links+0x1d/0x40 [media] [ 177.091981] [<ffffffffa028483e>] ? media_devnode_remove+0xe/0x20 [media] [ 177.091997] [<ffffffffa063d875>] ? v4l2_device_release+0x95/0x100 [videodev] [ 177.092014] [<ffffffff813ca19d>] ? device_release+0x2d/0x90 [ 177.092028] [<ffffffff812be5e9>] ? kobject_release+0x79/0x1b0 [ 177.092042] [<ffffffffa07b19ea>] ? au0828_analog_unregister+0x2a/0x60 [au0828] [ 177.092059] [<ffffffffa07ac10e>] ? au0828_usb_disconnect+0x9e/0xd0 [au0828] [ 177.092075] [<ffffffff8140e609>] ? usb_unbind_interface+0x79/0x270 [ 177.092090] [<ffffffff813cf285>] ? __device_release_driver+0x95/0x130 [ 177.092105] [<ffffffff813cf41b>] ? driver_detach+0xab/0xb0 [ 177.092120] [<ffffffff813ce4c5>] ? bus_remove_driver+0x55/0xd0 [ 177.092134] [<ffffffff8140d951>] ? usb_deregister+0x71/0xc0 [ 177.092148] [<ffffffff810e438a>] ? SyS_delete_module+0x1aa/0x250 [ 177.092163] [<ffffffff81088ee9>] ? task_work_run+0x89/0xc0 [ 177.092176] [<ffffffff815631f2>] ? entry_SYSCALL_64_fastpath+0x16/0x75 [ 177.092191] Code: 87 47 02 c1 e0 10 85 c0 74 38 48 89 c2 c1 e8 12 48 c1 ea 0c 83 e8 01 83 e2 30 48 98 48 81 c2 c0 62 01 00 48 03 14 c5 c0 62 90 81 <48> 89 0a 8b 41 08 85 c0 75 0d f3 90 8b 41 08 85 c0 74 f7 eb 02 [ 177.092281] RIP [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.092299] RSP <ffff880036b8bcd8> [ 177.097721] ---[ end trace b12d5a66f4c6f1c1 ]--- [ 177.243899] lirc_dev: module unloaded
Change-Id: Iffc0a92034632bbcb0d06fa0fbd224b11a949606 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/usb/au0828/au0828-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 7f645bcb7463..e28cabe65934 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -175,8 +175,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface) */ dev->dev_state = DEV_DISCONNECTED;
- au0828_unregister_media_device(dev); - au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev); @@ -193,6 +191,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface) return; } #endif + au0828_unregister_media_device(dev); + au0828_usb_release(dev); }
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
au0828_analog_unregister() calls video_unregister_device(), with, in turn, calls media_devnode_remove() in order to drop
s/with/which/
Has this been tested by keeping a video node open, then disconnecting, and then closing the open node? And doing the same for a dvb device node?
Those cases can be tricky.
Regards,
Hans
the media interfaces.
We can't release the media controller before that, or an OOPS will occur:
[ 176.938752] usb 1-4.4: Media device released [ 176.938753] usb 1-4.4: Media device unregistered [ 177.091235] general protection fault: 0000 [#1] SMP [ 177.091253] Modules linked in: ir_lirc_codec ir_xmp_decoder lirc_dev ir_mce_kbd_decoder ir_sharp_decoder ir_sanyo_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_nec_decoder ir_rc5_decoder au8522_dig xc5000 tuner au8522_decoder au8522_common au0828(-) videobuf2_vmalloc videobuf2_memops tveeprom videobuf2_core dvb_core rc_core v4l2_common videodev media cpufreq_powersave cpufreq_conservative cpufreq_userspace cpufreq_stats parport_pc ppdev lp parport snd_hda_codec_hdmi i915 x86_pkg_temp_thermal intel_powerclamp intel_rapl iosf_mbi coretemp kvm_intel kvm btusb crct10dif_pclmul snd_hda_codec_realtek crc32_pclmul btrtl crc32c_intel btbcm snd_hda_codec_generic ghash_clmulni_intel btintel i2c_algo_bit drm_kms_helper bluetooth iTCO_wdt snd_usb_audio snd_hda_intel iTCO_vendor_support jitterentropy_rng [ 177.091455] snd_hda_codec evdev sha256_ssse3 drm sha256_generic hmac snd_usbmidi_lib snd_hwdep snd_hda_core snd_rawmidi drbg snd_seq_device snd_pcm aesni_intel aes_x86_64 lrw gf128mul mei_me glue_helper snd_timer ablk_helper cryptd mei rfkill snd psmouse sg shpchp soundcore lpc_ich serio_raw i2c_i801 pcspkr mfd_core tpm_tis tpm battery dw_dmac video i2c_designware_platform dw_dmac_core i2c_designware_core acpi_pad processor button ext4 crc16 mbcache jbd2 dm_mod sd_mod ahci libahci libata e1000e scsi_mod ptp pps_core ehci_pci xhci_pci ehci_hcd xhci_hcd thermal fan thermal_sys sdhci_acpi sdhci mmc_core i2c_hid hid [last unloaded: rc_core] [ 177.091632] CPU: 1 PID: 18040 Comm: rmmod Tainted: G W 4.2.0-rc2+ #9 [ 177.091648] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/NUC5i7RYB, BIOS RYBDWi35.86A.0246.2015.0309.1355 03/09/2015 [ 177.091677] task: ffff88040811b080 ti: ffff880036b88000 task.ti: ffff880036b88000 [ 177.091693] RIP: 0010:[<ffffffff810aecc3>] [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.091718] RSP: 0018:ffff880036b8bcd8 EFLAGS: 00010202 [ 177.091730] RAX: 0000000000003ffe RBX: ffff880407e11b70 RCX: ffff88041ec962c0 [ 177.091745] RDX: 7463656a62506357 RSI: 0000000000080000 RDI: ffff880407e11b74 [ 177.091760] RBP: ffff880407e11b74 R08: 0000000000000001 R09: ffffffff812bf4e0 [ 177.091776] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88040811b080 [ 177.091791] R13: ffff88003601cec8 R14: ffff8804084b8890 R15: ffff8804084b8800 [ 177.091807] FS: 00007f2f9bab1700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000 [ 177.091824] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 177.091837] CR2: 00007fe8c0f900e0 CR3: 0000000035c47000 CR4: 00000000003407e0 [ 177.091852] Stack: [ 177.091857] ffffffff81562e3d ffffffff815613b3 0000000000000000 0000000000000000 [ 177.091876] ffff88040b6d3240 ffff8804084b8890 ffff880407e11b70 ffff88003601cd30 [ 177.091895] ffff88003601ce28 ffff88003601cec8 ffff8804084b8890 ffffffff8156148b [ 177.091914] Call Trace: [ 177.091923] [<ffffffff81562e3d>] ? _raw_spin_lock+0x1d/0x20 [ 177.091936] [<ffffffff815613b3>] ? __mutex_lock_slowpath+0x43/0x100 [ 177.091951] [<ffffffff8156148b>] ? mutex_lock+0x1b/0x30 [ 177.091965] [<ffffffffa028480d>] ? media_remove_intf_links+0x1d/0x40 [media] [ 177.091981] [<ffffffffa028483e>] ? media_devnode_remove+0xe/0x20 [media] [ 177.091997] [<ffffffffa063d875>] ? v4l2_device_release+0x95/0x100 [videodev] [ 177.092014] [<ffffffff813ca19d>] ? device_release+0x2d/0x90 [ 177.092028] [<ffffffff812be5e9>] ? kobject_release+0x79/0x1b0 [ 177.092042] [<ffffffffa07b19ea>] ? au0828_analog_unregister+0x2a/0x60 [au0828] [ 177.092059] [<ffffffffa07ac10e>] ? au0828_usb_disconnect+0x9e/0xd0 [au0828] [ 177.092075] [<ffffffff8140e609>] ? usb_unbind_interface+0x79/0x270 [ 177.092090] [<ffffffff813cf285>] ? __device_release_driver+0x95/0x130 [ 177.092105] [<ffffffff813cf41b>] ? driver_detach+0xab/0xb0 [ 177.092120] [<ffffffff813ce4c5>] ? bus_remove_driver+0x55/0xd0 [ 177.092134] [<ffffffff8140d951>] ? usb_deregister+0x71/0xc0 [ 177.092148] [<ffffffff810e438a>] ? SyS_delete_module+0x1aa/0x250 [ 177.092163] [<ffffffff81088ee9>] ? task_work_run+0x89/0xc0 [ 177.092176] [<ffffffff815631f2>] ? entry_SYSCALL_64_fastpath+0x16/0x75 [ 177.092191] Code: 87 47 02 c1 e0 10 85 c0 74 38 48 89 c2 c1 e8 12 48 c1 ea 0c 83 e8 01 83 e2 30 48 98 48 81 c2 c0 62 01 00 48 03 14 c5 c0 62 90 81 <48> 89 0a 8b 41 08 85 c0 75 0d f3 90 8b 41 08 85 c0 74 f7 eb 02 [ 177.092281] RIP [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.092299] RSP <ffff880036b8bcd8> [ 177.097721] ---[ end trace b12d5a66f4c6f1c1 ]--- [ 177.243899] lirc_dev: module unloaded
Change-Id: Iffc0a92034632bbcb0d06fa0fbd224b11a949606 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/usb/au0828/au0828-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 7f645bcb7463..e28cabe65934 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -175,8 +175,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface) */ dev->dev_state = DEV_DISCONNECTED;
- au0828_unregister_media_device(dev);
- au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev);
@@ -193,6 +191,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface) return; } #endif
- au0828_unregister_media_device(dev);
- au0828_usb_release(dev);
}
On 10/16/2015 08:03 AM, Hans Verkuil wrote:
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
au0828_analog_unregister() calls video_unregister_device(), with, in turn, calls media_devnode_remove() in order to drop
s/with/which/
Has this been tested by keeping a video node open, then disconnecting, and then closing the open node? And doing the same for a dvb device node?
Those cases can be tricky.
This isn't working. I am seeing slowpath warnings from media_devnode_remove(). I reported the problem a couple of days ago.
thanks, -- Shuah
the media interfaces.
We can't release the media controller before that, or an OOPS will occur:
[ 176.938752] usb 1-4.4: Media device released [ 176.938753] usb 1-4.4: Media device unregistered [ 177.091235] general protection fault: 0000 [#1] SMP [ 177.091253] Modules linked in: ir_lirc_codec ir_xmp_decoder lirc_dev ir_mce_kbd_decoder ir_sharp_decoder ir_sanyo_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_nec_decoder ir_rc5_decoder au8522_dig xc5000 tuner au8522_decoder au8522_common au0828(-) videobuf2_vmalloc videobuf2_memops tveeprom videobuf2_core dvb_core rc_core v4l2_common videodev media cpufreq_powersave cpufreq_conservative cpufreq_userspace cpufreq_stats parport_pc ppdev lp parport snd_hda_codec_hdmi i915 x86_pkg_temp_thermal intel_powerclamp intel_rapl iosf_mbi coretemp kvm_intel kvm btusb crct10dif_pclmul snd_hda_codec_realtek crc32_pclmul btrtl crc32c_intel btbcm snd_hda_codec_generic ghash_clmulni_intel btintel i2c_algo_bit drm_kms_helper bluetooth iTCO_wdt snd_usb_audio snd_hda_intel iTCO_vendor_support jitterentropy_rng [ 177.091455] snd_hda_codec evdev sha256_ssse3 drm sha256_generic hmac snd_usbmidi_lib snd_hwdep snd_hda_core snd_rawmidi drbg snd_seq_device snd_pcm aesni_intel aes_x86_64 lrw gf128mul mei_me glue_helper snd_timer ablk_helper cryptd mei rfkill snd psmouse sg shpchp soundcore lpc_ich serio_raw i2c_i801 pcspkr mfd_core tpm_tis tpm battery dw_dmac video i2c_designware_platform dw_dmac_core i2c_designware_core acpi_pad processor button ext4 crc16 mbcache jbd2 dm_mod sd_mod ahci libahci libata e1000e scsi_mod ptp pps_core ehci_pci xhci_pci ehci_hcd xhci_hcd thermal fan thermal_sys sdhci_acpi sdhci mmc_core i2c_hid hid [last unloaded: rc_core] [ 177.091632] CPU: 1 PID: 18040 Comm: rmmod Tainted: G W 4.2.0-rc2+ #9 [ 177.091648] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/NUC5i7RYB, BIOS RYBDWi35.86A.0246.2015.0309.1355 03/09/2015 [ 177.091677] task: ffff88040811b080 ti: ffff880036b88000 task.ti: ffff880036b88000 [ 177.091693] RIP: 0010:[<ffffffff810aecc3>] [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.091718] RSP: 0018:ffff880036b8bcd8 EFLAGS: 00010202 [ 177.091730] RAX: 0000000000003ffe RBX: ffff880407e11b70 RCX: ffff88041ec962c0 [ 177.091745] RDX: 7463656a62506357 RSI: 0000000000080000 RDI: ffff880407e11b74 [ 177.091760] RBP: ffff880407e11b74 R08: 0000000000000001 R09: ffffffff812bf4e0 [ 177.091776] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88040811b080 [ 177.091791] R13: ffff88003601cec8 R14: ffff8804084b8890 R15: ffff8804084b8800 [ 177.091807] FS: 00007f2f9bab1700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000 [ 177.091824] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 177.091837] CR2: 00007fe8c0f900e0 CR3: 0000000035c47000 CR4: 00000000003407e0 [ 177.091852] Stack: [ 177.091857] ffffffff81562e3d ffffffff815613b3 0000000000000000 0000000000000000 [ 177.091876] ffff88040b6d3240 ffff8804084b8890 ffff880407e11b70 ffff88003601cd30 [ 177.091895] ffff88003601ce28 ffff88003601cec8 ffff8804084b8890 ffffffff8156148b [ 177.091914] Call Trace: [ 177.091923] [<ffffffff81562e3d>] ? _raw_spin_lock+0x1d/0x20 [ 177.091936] [<ffffffff815613b3>] ? __mutex_lock_slowpath+0x43/0x100 [ 177.091951] [<ffffffff8156148b>] ? mutex_lock+0x1b/0x30 [ 177.091965] [<ffffffffa028480d>] ? media_remove_intf_links+0x1d/0x40 [media] [ 177.091981] [<ffffffffa028483e>] ? media_devnode_remove+0xe/0x20 [media] [ 177.091997] [<ffffffffa063d875>] ? v4l2_device_release+0x95/0x100 [videodev] [ 177.092014] [<ffffffff813ca19d>] ? device_release+0x2d/0x90 [ 177.092028] [<ffffffff812be5e9>] ? kobject_release+0x79/0x1b0 [ 177.092042] [<ffffffffa07b19ea>] ? au0828_analog_unregister+0x2a/0x60 [au0828] [ 177.092059] [<ffffffffa07ac10e>] ? au0828_usb_disconnect+0x9e/0xd0 [au0828] [ 177.092075] [<ffffffff8140e609>] ? usb_unbind_interface+0x79/0x270 [ 177.092090] [<ffffffff813cf285>] ? __device_release_driver+0x95/0x130 [ 177.092105] [<ffffffff813cf41b>] ? driver_detach+0xab/0xb0 [ 177.092120] [<ffffffff813ce4c5>] ? bus_remove_driver+0x55/0xd0 [ 177.092134] [<ffffffff8140d951>] ? usb_deregister+0x71/0xc0 [ 177.092148] [<ffffffff810e438a>] ? SyS_delete_module+0x1aa/0x250 [ 177.092163] [<ffffffff81088ee9>] ? task_work_run+0x89/0xc0 [ 177.092176] [<ffffffff815631f2>] ? entry_SYSCALL_64_fastpath+0x16/0x75 [ 177.092191] Code: 87 47 02 c1 e0 10 85 c0 74 38 48 89 c2 c1 e8 12 48 c1 ea 0c 83 e8 01 83 e2 30 48 98 48 81 c2 c0 62 01 00 48 03 14 c5 c0 62 90 81 <48> 89 0a 8b 41 08 85 c0 75 0d f3 90 8b 41 08 85 c0 74 f7 eb 02 [ 177.092281] RIP [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.092299] RSP <ffff880036b8bcd8> [ 177.097721] ---[ end trace b12d5a66f4c6f1c1 ]--- [ 177.243899] lirc_dev: module unloaded
Change-Id: Iffc0a92034632bbcb0d06fa0fbd224b11a949606 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/usb/au0828/au0828-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 7f645bcb7463..e28cabe65934 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -175,8 +175,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface) */ dev->dev_state = DEV_DISCONNECTED;
- au0828_unregister_media_device(dev);
- au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev);
@@ -193,6 +191,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface) return; } #endif
- au0828_unregister_media_device(dev);
- au0828_usb_release(dev);
}
media-workshop mailing list media-workshop@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/media-workshop
Em Fri, 16 Oct 2015 16:03:58 +0200 Hans Verkuil hverkuil@xs4all.nl escreveu:
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
au0828_analog_unregister() calls video_unregister_device(), with, in turn, calls media_devnode_remove() in order to drop
s/with/which/
Has this been tested by keeping a video node open, then disconnecting, and then closing the open node? And doing the same for a dvb device node?
Those cases can be tricky.
Don't remember the specific case, but I guess it was happening with just rmmod without even opening the device node.
Regards,
Hans
the media interfaces.
We can't release the media controller before that, or an OOPS will occur:
[ 176.938752] usb 1-4.4: Media device released [ 176.938753] usb 1-4.4: Media device unregistered [ 177.091235] general protection fault: 0000 [#1] SMP [ 177.091253] Modules linked in: ir_lirc_codec ir_xmp_decoder lirc_dev ir_mce_kbd_decoder ir_sharp_decoder ir_sanyo_decoder ir_sony_decoder ir_jvc_decoder ir_rc6_decoder ir_nec_decoder ir_rc5_decoder au8522_dig xc5000 tuner au8522_decoder au8522_common au0828(-) videobuf2_vmalloc videobuf2_memops tveeprom videobuf2_core dvb_core rc_core v4l2_common videodev media cpufreq_powersave cpufreq_conservative cpufreq_userspace cpufreq_stats parport_pc ppdev lp parport snd_hda_codec_hdmi i915 x86_pkg_temp_thermal intel_powerclamp intel_rapl iosf_mbi coretemp kvm_intel kvm btusb crct10dif_pclmul snd_hda_codec_realtek crc32_pclmul btrtl crc32c_intel btbcm snd_hda_codec_generic ghash_clmulni_intel btintel i2c_algo_bit drm_kms_helper bluetooth iTCO_wdt snd_usb_audio snd_hda_intel iTCO_vendor_support jitterentropy_rng [ 177.091455] snd_hda_codec evdev sha256_ssse3 drm sha256_generic hmac snd_usbmidi_lib snd_hwdep snd_hda_core snd_rawmidi drbg snd_seq_device snd_pcm aesni_intel aes_x86_64 lrw gf128mul mei_me glue_helper snd_timer ablk_helper cryptd mei rfkill snd psmouse sg shpchp soundcore lpc_ich serio_raw i2c_i801 pcspkr mfd_core tpm_tis tpm battery dw_dmac video i2c_designware_platform dw_dmac_core i2c_designware_core acpi_pad processor button ext4 crc16 mbcache jbd2 dm_mod sd_mod ahci libahci libata e1000e scsi_mod ptp pps_core ehci_pci xhci_pci ehci_hcd xhci_hcd thermal fan thermal_sys sdhci_acpi sdhci mmc_core i2c_hid hid [last unloaded: rc_core] [ 177.091632] CPU: 1 PID: 18040 Comm: rmmod Tainted: G W 4.2.0-rc2+ #9 [ 177.091648] Hardware name: \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff \xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff\xffffffff/NUC5i7RYB, BIOS RYBDWi35.86A.0246.2015.0309.1355 03/09/2015 [ 177.091677] task: ffff88040811b080 ti: ffff880036b88000 task.ti: ffff880036b88000 [ 177.091693] RIP: 0010:[<ffffffff810aecc3>] [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.091718] RSP: 0018:ffff880036b8bcd8 EFLAGS: 00010202 [ 177.091730] RAX: 0000000000003ffe RBX: ffff880407e11b70 RCX: ffff88041ec962c0 [ 177.091745] RDX: 7463656a62506357 RSI: 0000000000080000 RDI: ffff880407e11b74 [ 177.091760] RBP: ffff880407e11b74 R08: 0000000000000001 R09: ffffffff812bf4e0 [ 177.091776] R10: 0000000000000000 R11: 0000000000000000 R12: ffff88040811b080 [ 177.091791] R13: ffff88003601cec8 R14: ffff8804084b8890 R15: ffff8804084b8800 [ 177.091807] FS: 00007f2f9bab1700(0000) GS:ffff88041ec80000(0000) knlGS:0000000000000000 [ 177.091824] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 177.091837] CR2: 00007fe8c0f900e0 CR3: 0000000035c47000 CR4: 00000000003407e0 [ 177.091852] Stack: [ 177.091857] ffffffff81562e3d ffffffff815613b3 0000000000000000 0000000000000000 [ 177.091876] ffff88040b6d3240 ffff8804084b8890 ffff880407e11b70 ffff88003601cd30 [ 177.091895] ffff88003601ce28 ffff88003601cec8 ffff8804084b8890 ffffffff8156148b [ 177.091914] Call Trace: [ 177.091923] [<ffffffff81562e3d>] ? _raw_spin_lock+0x1d/0x20 [ 177.091936] [<ffffffff815613b3>] ? __mutex_lock_slowpath+0x43/0x100 [ 177.091951] [<ffffffff8156148b>] ? mutex_lock+0x1b/0x30 [ 177.091965] [<ffffffffa028480d>] ? media_remove_intf_links+0x1d/0x40 [media] [ 177.091981] [<ffffffffa028483e>] ? media_devnode_remove+0xe/0x20 [media] [ 177.091997] [<ffffffffa063d875>] ? v4l2_device_release+0x95/0x100 [videodev] [ 177.092014] [<ffffffff813ca19d>] ? device_release+0x2d/0x90 [ 177.092028] [<ffffffff812be5e9>] ? kobject_release+0x79/0x1b0 [ 177.092042] [<ffffffffa07b19ea>] ? au0828_analog_unregister+0x2a/0x60 [au0828] [ 177.092059] [<ffffffffa07ac10e>] ? au0828_usb_disconnect+0x9e/0xd0 [au0828] [ 177.092075] [<ffffffff8140e609>] ? usb_unbind_interface+0x79/0x270 [ 177.092090] [<ffffffff813cf285>] ? __device_release_driver+0x95/0x130 [ 177.092105] [<ffffffff813cf41b>] ? driver_detach+0xab/0xb0 [ 177.092120] [<ffffffff813ce4c5>] ? bus_remove_driver+0x55/0xd0 [ 177.092134] [<ffffffff8140d951>] ? usb_deregister+0x71/0xc0 [ 177.092148] [<ffffffff810e438a>] ? SyS_delete_module+0x1aa/0x250 [ 177.092163] [<ffffffff81088ee9>] ? task_work_run+0x89/0xc0 [ 177.092176] [<ffffffff815631f2>] ? entry_SYSCALL_64_fastpath+0x16/0x75 [ 177.092191] Code: 87 47 02 c1 e0 10 85 c0 74 38 48 89 c2 c1 e8 12 48 c1 ea 0c 83 e8 01 83 e2 30 48 98 48 81 c2 c0 62 01 00 48 03 14 c5 c0 62 90 81 <48> 89 0a 8b 41 08 85 c0 75 0d f3 90 8b 41 08 85 c0 74 f7 eb 02 [ 177.092281] RIP [<ffffffff810aecc3>] native_queued_spin_lock_slowpath+0x103/0x180 [ 177.092299] RSP <ffff880036b8bcd8> [ 177.097721] ---[ end trace b12d5a66f4c6f1c1 ]--- [ 177.243899] lirc_dev: module unloaded
Change-Id: Iffc0a92034632bbcb0d06fa0fbd224b11a949606 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/usb/au0828/au0828-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 7f645bcb7463..e28cabe65934 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -175,8 +175,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface) */ dev->dev_state = DEV_DISCONNECTED;
- au0828_unregister_media_device(dev);
- au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev);
@@ -193,6 +191,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface) return; } #endif
- au0828_unregister_media_device(dev);
- au0828_usb_release(dev);
}
V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled.
Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA.
Change-Id: I570210b1c08ebf5f29e2917da27c957bb798d2b0 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/v4l2-core/v4l2-dev.c | 112 ++++++++++++++++++++++++++++------ drivers/media/v4l2-core/v4l2-device.c | 16 ++++- include/media/v4l2-dev.h | 1 + 3 files changed, 110 insertions(+), 19 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 44b330589787..07123dd569c4 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -194,9 +194,12 @@ static void v4l2_device_release(struct device *cd) mutex_unlock(&videodev_lock);
#if defined(CONFIG_MEDIA_CONTROLLER) - if (v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) - media_device_unregister_entity(&vdev->entity); + if (v4l2_dev->mdev) { + /* Remove interfaces and interface links */ + media_devnode_remove(vdev->intf_devnode); + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) + media_device_unregister_entity(&vdev->entity); + } #endif
/* Do not call v4l2_device_put if there is no release callback set. @@ -713,6 +716,92 @@ static void determine_valid_ioctls(struct video_device *vdev) BASE_VIDIOC_PRIVATE); }
+ +static int video_register_media_controller(struct video_device *vdev, int type) +{ +#if defined(CONFIG_MEDIA_CONTROLLER) + u32 intf_type; + int ret; + + if (!vdev->v4l2_dev->mdev) + return 0; + + vdev->entity.type = MEDIA_ENT_T_UNKNOWN; + + switch (type) { + case VFL_TYPE_GRABBER: + intf_type = MEDIA_INTF_T_V4L_VIDEO; + vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO; + break; + case VFL_TYPE_VBI: + intf_type = MEDIA_INTF_T_V4L_VBI; + vdev->entity.type = MEDIA_ENT_T_V4L2_VBI; + break; + case VFL_TYPE_SDR: + intf_type = MEDIA_INTF_T_V4L_SWRADIO; + vdev->entity.type = MEDIA_ENT_T_V4L2_SWRADIO; + break; + case VFL_TYPE_RADIO: + intf_type = MEDIA_INTF_T_V4L_RADIO; + /* + * Radio doesn't have an entity at the V4L2 side to represent + * radio input or output. Instead, the audio input/output goes + * via either physical wires or ALSA. + */ + break; + case VFL_TYPE_SUBDEV: + intf_type = MEDIA_INTF_T_V4L_SUBDEV; + /* Entity will be created via v4l2_device_register_subdev() */ + break; + default: + return 0; + } + + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + vdev->entity.name = vdev->name; + + /* Needed just for backward compatibility with legacy MC API */ + vdev->entity.info.dev.major = VIDEO_MAJOR; + vdev->entity.info.dev.minor = vdev->minor; + + ret = media_device_register_entity(vdev->v4l2_dev->mdev, + &vdev->entity); + if (ret < 0) { + printk(KERN_WARNING + "%s: media_device_register_entity failed\n", + __func__); + return ret; + } + } + + vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev, + intf_type, + 0, VIDEO_MAJOR, + vdev->minor, + GFP_KERNEL); + if (!vdev->intf_devnode) { + media_device_unregister_entity(&vdev->entity); + return -ENOMEM; + } + + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + struct media_link *link; + + link = media_create_intf_link(&vdev->entity, + &vdev->intf_devnode->intf, 0); + if (!link) { + media_devnode_remove(vdev->intf_devnode); + media_device_unregister_entity(&vdev->entity); + return -ENOMEM; + } + } + + /* FIXME: how to create the other interface links? */ + +#endif + return 0; +} + /** * __video_register_device - register video4linux devices * @vdev: video device structure we want to register @@ -908,22 +997,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr, /* Increase v4l2_device refcount */ v4l2_device_get(vdev->v4l2_dev);
-#if defined(CONFIG_MEDIA_CONTROLLER) /* Part 5: Register the entity. */ - if (vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) { - 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; - ret = media_device_register_entity(vdev->v4l2_dev->mdev, - &vdev->entity); - if (ret < 0) - printk(KERN_WARNING - "%s: media_device_register_entity failed\n", - __func__); - } -#endif + ret = video_register_media_controller(vdev, type); + /* Part 6: Activate this minor. The char device can now be used. */ set_bit(V4L2_FL_REGISTERED, &vdev->flags);
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 5b0a30b9252b..e788a085ba96 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -249,6 +249,17 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.info.dev.major = VIDEO_MAJOR; sd->entity.info.dev.minor = vdev->minor; + + /* Interface is created by __video_register_device() */ + if (vdev->v4l2_dev->mdev) { + struct media_link *link; + + link = media_create_intf_link(&sd->entity, + &vdev->intf_devnode->intf, + 0); + if (!link) + goto clean_up; + } #endif sd->devnode = vdev; } @@ -285,7 +296,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
#if defined(CONFIG_MEDIA_CONTROLLER) if (v4l2_dev->mdev) { - media_entity_remove_links(&sd->entity); + /* + * No need to explicitly remove links, as both pads and + * links are removed by the function below, in the right order + */ media_device_unregister_entity(&sd->entity); } #endif diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index acbcd2f5fe7f..eeabf20e87a6 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -86,6 +86,7 @@ struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; + struct media_intf_devnode *intf_devnode; #endif /* device ops */ const struct v4l2_file_operations *fops;
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled.
Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA.
Change-Id: I570210b1c08ebf5f29e2917da27c957bb798d2b0 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
But see comment below:
drivers/media/v4l2-core/v4l2-dev.c | 112 ++++++++++++++++++++++++++++------ drivers/media/v4l2-core/v4l2-device.c | 16 ++++- include/media/v4l2-dev.h | 1 + 3 files changed, 110 insertions(+), 19 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 44b330589787..07123dd569c4 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c
<snip>
@@ -713,6 +716,92 @@ static void determine_valid_ioctls(struct video_device *vdev) BASE_VIDIOC_PRIVATE); }
+static int video_register_media_controller(struct video_device *vdev, int type) +{ +#if defined(CONFIG_MEDIA_CONTROLLER)
- u32 intf_type;
- int ret;
- if (!vdev->v4l2_dev->mdev)
return 0;
- vdev->entity.type = MEDIA_ENT_T_UNKNOWN;
- switch (type) {
- case VFL_TYPE_GRABBER:
intf_type = MEDIA_INTF_T_V4L_VIDEO;
vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
break;
I think I mentioned it before: V4L vs V4L2 in the macro names is inconsistent. I would suggest using V4L2 as well in MEDIA_INTF_. It looks really weird and arbitrary here.
Regards,
Hans
Em Fri, 16 Oct 2015 16:09:10 +0200 Hans Verkuil hverkuil@xs4all.nl escreveu:
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled.
Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA.
Change-Id: I570210b1c08ebf5f29e2917da27c957bb798d2b0 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
I had to fold this patch with a change on au0828, in order to avoid breaking runtime bisectability when the device is removed (or the a80828 module is removed). The problem seems to be specific to au0828 and the hybrid analog/digital demod.
The applied patch follows.
commit d3d9410a345643dce9dcb28e1b11f58da56720cd Author: Mauro Carvalho Chehab mchehab@osg.samsung.com Date: Mon Aug 24 08:47:54 2015 -0300
[media] v4l2-core: create MC interfaces for devnodes
V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled.
Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA.
PS.: Before this patch, au0828 should remove the media_device earlier. However, after the core changes, this should be postponed, otherwise an OOPS occurs. So, fold the au0828 changes on this patch.
Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 7f645bcb7463..5f0b210cc797 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -175,8 +175,6 @@ static void au0828_usb_disconnect(struct usb_interface *interface) */ dev->dev_state = DEV_DISCONNECTED;
- au0828_unregister_media_device(dev); - au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev); @@ -190,6 +188,10 @@ static void au0828_usb_disconnect(struct usb_interface *interface) au0828_analog_unregister(dev); v4l2_device_disconnect(&dev->v4l2_dev); v4l2_device_put(&dev->v4l2_dev); + /* + * No need to call au0828_usb_release() if V4L2 is enabled, + * as this is already called via au0828_usb_v4l2_release() + */ return; } #endif diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 2297571a0568..077cdc92778c 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -194,9 +194,12 @@ static void v4l2_device_release(struct device *cd) mutex_unlock(&videodev_lock);
#if defined(CONFIG_MEDIA_CONTROLLER) - if (v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) - media_device_unregister_entity(&vdev->entity); + if (v4l2_dev->mdev) { + /* Remove interfaces and interface links */ + media_devnode_remove(vdev->intf_devnode); + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) + media_device_unregister_entity(&vdev->entity); + } #endif
/* Do not call v4l2_device_put if there is no release callback set. @@ -723,6 +726,91 @@ static void determine_valid_ioctls(struct video_device *vdev) BASE_VIDIOC_PRIVATE); }
+static int video_register_media_controller(struct video_device *vdev, int type) +{ +#if defined(CONFIG_MEDIA_CONTROLLER) + u32 intf_type; + int ret; + + if (!vdev->v4l2_dev->mdev) + return 0; + + vdev->entity.type = MEDIA_ENT_T_UNKNOWN; + + switch (type) { + case VFL_TYPE_GRABBER: + intf_type = MEDIA_INTF_T_V4L_VIDEO; + vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO; + break; + case VFL_TYPE_VBI: + intf_type = MEDIA_INTF_T_V4L_VBI; + vdev->entity.type = MEDIA_ENT_T_V4L2_VBI; + break; + case VFL_TYPE_SDR: + intf_type = MEDIA_INTF_T_V4L_SWRADIO; + vdev->entity.type = MEDIA_ENT_T_V4L2_SWRADIO; + break; + case VFL_TYPE_RADIO: + intf_type = MEDIA_INTF_T_V4L_RADIO; + /* + * Radio doesn't have an entity at the V4L2 side to represent + * radio input or output. Instead, the audio input/output goes + * via either physical wires or ALSA. + */ + break; + case VFL_TYPE_SUBDEV: + intf_type = MEDIA_INTF_T_V4L_SUBDEV; + /* Entity will be created via v4l2_device_register_subdev() */ + break; + default: + return 0; + } + + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + vdev->entity.name = vdev->name; + + /* Needed just for backward compatibility with legacy MC API */ + vdev->entity.info.dev.major = VIDEO_MAJOR; + vdev->entity.info.dev.minor = vdev->minor; + + ret = media_device_register_entity(vdev->v4l2_dev->mdev, + &vdev->entity); + if (ret < 0) { + printk(KERN_WARNING + "%s: media_device_register_entity failed\n", + __func__); + return ret; + } + } + + vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev, + intf_type, + 0, VIDEO_MAJOR, + vdev->minor, + GFP_KERNEL); + if (!vdev->intf_devnode) { + media_device_unregister_entity(&vdev->entity); + return -ENOMEM; + } + + if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + struct media_link *link; + + link = media_create_intf_link(&vdev->entity, + &vdev->intf_devnode->intf, 0); + if (!link) { + media_devnode_remove(vdev->intf_devnode); + media_device_unregister_entity(&vdev->entity); + return -ENOMEM; + } + } + + /* FIXME: how to create the other interface links? */ + +#endif + return 0; +} + /** * __video_register_device - register video4linux devices * @vdev: video device structure we want to register @@ -918,22 +1006,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr, /* Increase v4l2_device refcount */ v4l2_device_get(vdev->v4l2_dev);
-#if defined(CONFIG_MEDIA_CONTROLLER) /* Part 5: Register the entity. */ - if (vdev->v4l2_dev->mdev && - vdev->vfl_type != VFL_TYPE_SUBDEV) { - 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; - ret = media_device_register_entity(vdev->v4l2_dev->mdev, - &vdev->entity); - if (ret < 0) - printk(KERN_WARNING - "%s: media_device_register_entity failed\n", - __func__); - } -#endif + ret = video_register_media_controller(vdev, type); + /* Part 6: Activate this minor. The char device can now be used. */ set_bit(V4L2_FL_REGISTERED, &vdev->flags);
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 7129e438f29e..3c87307e56f0 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -258,6 +258,17 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.info.dev.major = VIDEO_MAJOR; sd->entity.info.dev.minor = vdev->minor; + + /* Interface is created by __video_register_device() */ + if (vdev->v4l2_dev->mdev) { + struct media_link *link; + + link = media_create_intf_link(&sd->entity, + &vdev->intf_devnode->intf, + 0); + if (!link) + goto clean_up; + } #endif sd->devnode = vdev; } @@ -294,7 +305,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
#if defined(CONFIG_MEDIA_CONTROLLER) if (v4l2_dev->mdev) { - media_entity_remove_links(&sd->entity); + /* + * No need to explicitly remove links, as both pads and + * links are removed by the function below, in the right order + */ media_device_unregister_entity(&sd->entity); } #endif diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index acbcd2f5fe7f..eeabf20e87a6 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -86,6 +86,7 @@ struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; + struct media_intf_devnode *intf_devnode; #endif /* device ops */ const struct v4l2_file_operations *fops;
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.
Change-Id: Iec2758c40106c52a922b23740d98041a69e8fb63 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/media/media-entity.h | 110 ++++++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 28 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index fb5f0e21f137..e1a89899deef 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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 * * 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. + * + * @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 + * a pad. On such case, it represents the sink pad. + * @entity: Part of an union. Used only if the second object (gobj0) is + * an entity. + * @reverse: Pointer to the link for the reverse direction of a pad to pad + * 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 */ - 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 + * @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); };
+/** + * 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. + * @num_backlinks: Number of backlinks + * @pads: Pads array with the size defined by @num_pads. + * @links: Linked list for the data links. + * @ops: Entity operations. + * @stream_count: Stream count for the entity. + * @use_count: Use count for the entity. + * @pipe: Pipeline this entity belongs to. + * @info: Union with devnode information. Kept just for backward + * compatibility. + * @major: Devnode major number (zero if not applicable). Kept just + * for backward compatibility. + * @minor: Devnode minor number (zero if not applicable). Kept just + * for backward compatibility. + * + * 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. + */ struct media_entity { struct 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; };
/** - * struct media_interface - Define a Kernel API interface + * struct media_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 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. @@ -177,7 +231,7 @@ struct media_interface { };
/** - * struct media_intf_devnode - Define a Kernel API interface via a device node + * struct media_intf_devnode - Define a media interface via a device node * * @intf: embedded interface object * @major: Major number of a device node
On 10/12/2015 06:43 PM, 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.
Change-Id: Iec2758c40106c52a922b23740d98041a69e8fb63 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
include/media/media-entity.h | 110 ++++++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 28 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index fb5f0e21f137..e1a89899deef 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -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
- 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.
- @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
a pad. On such case, it represents the sink pad.
- @entity: Part of an union. Used only if the second object (gobj0) is
an entity.
- @reverse: Pointer to the link for the reverse direction of a pad to pad
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 */
- 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
- @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); };
+/**
- 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.
- @num_backlinks: Number of backlinks
- @pads: Pads array with the size defined by @num_pads.
- @links: Linked list for the data links.
- @ops: Entity operations.
- @stream_count: Stream count for the entity.
- @use_count: Use count for the entity.
- @pipe: Pipeline this entity belongs to.
- @info: Union with devnode information. Kept just for backward
compatibility.
- @major: Devnode major number (zero if not applicable). Kept just
for backward compatibility.
- @minor: Devnode minor number (zero if not applicable). Kept just
for backward compatibility.
- 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.
- */
struct media_entity { struct 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 {
struct { u32 major; u32 minor; } dev;/* Node specifications */
/* Sub-device specifications */
} info;/* Nothing needed yet */
};
/**
- struct media_interface - Define a Kernel API interface
- struct media_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 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.
@@ -177,7 +231,7 @@ struct media_interface { };
/**
- struct media_intf_devnode - Define a Kernel API interface via a device node
- struct media_intf_devnode - Define a media interface via a device node
- @intf: embedded interface object
- @major: Major number of a device node
Tuners actually have at least one connector on its input.
Add a PAD to connect it.
Change-Id: Ia30a82be6a2ebf87d2e02fc5af3e5da906bb8bf6 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 5 ++++- drivers/media/usb/au0828/au0828-core.c | 5 ++++- drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 8 +++++--- include/media/tuner.h | 8 ++++++++ 5 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index f00f1a5f279c..a8e7e2398f7a 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -34,6 +34,9 @@ #include <linux/mutex.h> #include "dvbdev.h"
+/* Due to enum tuner_pad_index */ +#include <media/tuner.h> + static DEFINE_MUTEX(dvbdev_mutex); static int dvbdev_debug;
@@ -552,7 +555,7 @@ void dvb_create_media_graph(struct dvb_adapter *adap) }
if (tuner && demod) - media_create_pad_link(tuner, 0, demod, 0, 0); + media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, demod, 0, 0);
if (demod && demux) media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index e28cabe65934..f54c7d10f350 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -27,6 +27,9 @@ #include <media/v4l2-common.h> #include <linux/mutex.h>
+/* Due to enum tuner_pad_index */ +#include <media/tuner.h> + /* * 1 = General debug messages * 2 = USB handling @@ -260,7 +263,7 @@ static void au0828_create_media_graph(struct au0828_dev *dev) return;
if (tuner) - media_create_pad_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, MEDIA_LNK_FL_ENABLED); media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 3b5c9ae39ad3..1070d87efc65 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1264,7 +1264,7 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) return;
if (tuner) - media_create_pad_link(tuner, 0, decoder, 0, + media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, MEDIA_LNK_FL_ENABLED); media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED); diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 100b8f069640..b90f2a52db96 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -134,8 +134,9 @@ struct tuner { unsigned int type; /* chip type id */ void *config; const char *name; + #if defined(CONFIG_MEDIA_CONTROLLER) - struct media_pad pad; + struct media_pad pad[TUNER_NUM_PADS]; #endif };
@@ -695,11 +696,12 @@ static int tuner_probe(struct i2c_client *client, /* Should be just before return */ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) - t->pad.flags = MEDIA_PAD_FL_SOURCE; + t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; + t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; t->sd.entity.name = t->name;
- ret = media_entity_init(&t->sd.entity, 1, &t->pad); + ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); if (ret < 0) { tuner_err("failed to initialize media entity!\n"); kfree(t); diff --git a/include/media/tuner.h b/include/media/tuner.h index b46ebb48fe74..95835c8069dd 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -25,6 +25,14 @@
#include <linux/videodev2.h>
+/* Tuner PADs */ +/* FIXME: is this the right place for it? */ +enum tuner_pad_index { + TUNER_PAD_RF_INPUT, + TUNER_PAD_IF_OUTPUT, + TUNER_NUM_PADS +}; + #define ADDR_UNSET (255)
#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Tuners actually have at least one connector on its input.
Add a PAD to connect it.
Change-Id: Ia30a82be6a2ebf87d2e02fc5af3e5da906bb8bf6 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/dvb-core/dvbdev.c | 5 ++++- drivers/media/usb/au0828/au0828-core.c | 5 ++++- drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 8 +++++--- include/media/tuner.h | 8 ++++++++ 5 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index f00f1a5f279c..a8e7e2398f7a 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -34,6 +34,9 @@ #include <linux/mutex.h> #include "dvbdev.h"
+/* Due to enum tuner_pad_index */ +#include <media/tuner.h>
static DEFINE_MUTEX(dvbdev_mutex); static int dvbdev_debug;
@@ -552,7 +555,7 @@ void dvb_create_media_graph(struct dvb_adapter *adap) }
if (tuner && demod)
media_create_pad_link(tuner, 0, demod, 0, 0);
media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, demod, 0, 0);
if (demod && demux) media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index e28cabe65934..f54c7d10f350 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -27,6 +27,9 @@ #include <media/v4l2-common.h> #include <linux/mutex.h>
+/* Due to enum tuner_pad_index */ +#include <media/tuner.h>
/*
- 1 = General debug messages
- 2 = USB handling
@@ -260,7 +263,7 @@ static void au0828_create_media_graph(struct au0828_dev *dev) return;
if (tuner)
media_create_pad_link(tuner, 0, decoder, 0,
media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED);media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 3b5c9ae39ad3..1070d87efc65 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1264,7 +1264,7 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) return;
if (tuner)
media_create_pad_link(tuner, 0, decoder, 0,
media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, MEDIA_LNK_FL_ENABLED);media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 100b8f069640..b90f2a52db96 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -134,8 +134,9 @@ struct tuner { unsigned int type; /* chip type id */ void *config; const char *name;
#if defined(CONFIG_MEDIA_CONTROLLER)
- struct media_pad pad;
- struct media_pad pad[TUNER_NUM_PADS];
#endif };
@@ -695,11 +696,12 @@ static int tuner_probe(struct i2c_client *client, /* Should be just before return */ register_client: #if defined(CONFIG_MEDIA_CONTROLLER)
- t->pad.flags = MEDIA_PAD_FL_SOURCE;
- t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
- t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; t->sd.entity.name = t->name;
- ret = media_entity_init(&t->sd.entity, 1, &t->pad);
- ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); if (ret < 0) { tuner_err("failed to initialize media entity!\n"); kfree(t);
diff --git a/include/media/tuner.h b/include/media/tuner.h index b46ebb48fe74..95835c8069dd 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -25,6 +25,14 @@
#include <linux/videodev2.h>
+/* Tuner PADs */ +/* FIXME: is this the right place for it? */
I think so, yes.
Hans
+enum tuner_pad_index {
- TUNER_PAD_RF_INPUT,
- TUNER_PAD_IF_OUTPUT,
- TUNER_NUM_PADS
+};
#define ADDR_UNSET (255)
#define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */
Depending on the input, an au0828 may have a different number of connectors. add entities to represent them.
Change-Id: I3d3d4b2d2cc2e5398ea73ed0e87db29bf7e9287b Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/usb/au0828/au0828-core.c | 15 +++++++ drivers/media/usb/au0828/au0828-video.c | 76 ++++++++++++++++++++++++++++----- drivers/media/usb/au0828/au0828.h | 3 +- 3 files changed, 82 insertions(+), 12 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index f54c7d10f350..fe9a60484343 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -153,11 +153,26 @@ static void au0828_usb_release(struct au0828_dev *dev) }
#ifdef CONFIG_VIDEO_AU0828_V4L2 + +static void au0828_usb_v4l2_media_release(struct au0828_dev *dev) +{ +#ifdef CONFIG_MEDIA_CONTROLLER + int i; + + for (i = 0; i < AU0828_MAX_INPUT; i++) { + if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED) + return; + media_device_unregister_entity(&dev->input_ent[i]); + } +#endif +} + static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) { struct au0828_dev *dev = container_of(v4l2_dev, struct au0828_dev, v4l2_dev);
+ au0828_usb_v4l2_media_release(dev); v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev); au0828_usb_release(dev); diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 4511e2893282..806b8d320bae 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1793,6 +1793,69 @@ static int au0828_vb2_setup(struct au0828_dev *dev) return 0; }
+static void au0828_analog_create_entities(struct au0828_dev *dev) +{ +#if defined(CONFIG_MEDIA_CONTROLLER) + static const char *inames[] = { + [AU0828_VMUX_COMPOSITE] = "Composite", + [AU0828_VMUX_SVIDEO] = "S-Video", + [AU0828_VMUX_CABLE] = "Cable TV", + [AU0828_VMUX_TELEVISION] = "Television", + [AU0828_VMUX_DVB] = "DVB", + [AU0828_VMUX_DEBUG] = "tv debug" + }; + int ret, i; + + /* Initialize Video and VBI pads */ + dev->video_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); + if (ret < 0) + pr_err("failed to initialize video media entity!\n"); + + dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); + if (ret < 0) + pr_err("failed to initialize vbi media entity!\n"); + + /* Create entities for each input connector */ + for (i = 0; i < AU0828_MAX_INPUT; i++) { + struct media_entity *ent = &dev->input_ent[i]; + + if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED) + break; + + ent->name = inames[AUVI_INPUT(i).type]; + ent->flags = MEDIA_ENT_FL_CONNECTOR; + dev->input_pad[i].flags = MEDIA_PAD_FL_SOURCE; + + switch(AUVI_INPUT(i).type) { + case AU0828_VMUX_COMPOSITE: + ent->type = MEDIA_ENT_T_CONN_COMPOSITE; + break; + case AU0828_VMUX_SVIDEO: + ent->type = MEDIA_ENT_T_CONN_SVIDEO; + break; + case AU0828_VMUX_CABLE: + case AU0828_VMUX_TELEVISION: + case AU0828_VMUX_DVB: + ent->type = MEDIA_ENT_T_CONN_RF; + break; + default: /* AU0828_VMUX_DEBUG */ + ent->type = MEDIA_ENT_T_CONN_TEST; + break; + } + + ret = media_entity_init(ent, 1, &dev->input_pad[i]); + if (ret < 0) + pr_err("failed to initialize input pad[%d]!\n", i); + + ret = media_device_register_entity(dev->media_dev, ent); + if (ret < 0) + pr_err("failed to register input entity %d!\n", i); + } +#endif +} + /**************************************************************************/
int au0828_analog_register(struct au0828_dev *dev, @@ -1881,17 +1944,8 @@ int au0828_analog_register(struct au0828_dev *dev, dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock; strcpy(dev->vbi_dev.name, "au0828a vbi");
-#if defined(CONFIG_MEDIA_CONTROLLER) - dev->video_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad); - if (ret < 0) - pr_err("failed to initialize video media entity!\n"); - - dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; - ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad); - if (ret < 0) - pr_err("failed to initialize vbi media entity!\n"); -#endif + /* Init entities at the Media Controller */ + au0828_analog_create_entities(dev);
/* initialize videobuf2 stuff */ retval = au0828_vb2_setup(dev); diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index d3644b3fe6fa..b7940c54d006 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -93,7 +93,6 @@ struct au0828_board { unsigned char has_ir_i2c:1; unsigned char has_analog:1; struct au0828_input input[AU0828_MAX_INPUT]; - };
struct au0828_dvb { @@ -281,6 +280,8 @@ struct au0828_dev { struct media_device *media_dev; struct media_pad video_pad, vbi_pad; struct media_entity *decoder; + struct media_entity input_ent[AU0828_MAX_INPUT]; + struct media_pad input_pad[AU0828_MAX_INPUT]; #endif };
Now that connectors are entities, we need to represent the connector links.
Change-Id: I49e119f9ad50bfa8a935f48b4deaacdcf9b3f0a7 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/usb/au0828/au0828-core.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index fe9a60484343..35c607c35155 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -257,6 +257,7 @@ static void au0828_create_media_graph(struct au0828_dev *dev) struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; + int i;
if (!mdev) return; @@ -274,6 +275,7 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
/* Analog setup, using tuner as a link */
+ /* Something bad happened! */ if (!decoder) return;
@@ -284,6 +286,30 @@ static void au0828_create_media_graph(struct au0828_dev *dev) MEDIA_LNK_FL_ENABLED); media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, MEDIA_LNK_FL_ENABLED); + + for (i = 0; i < AU0828_MAX_INPUT; i++) { + struct media_entity *ent = &dev->input_ent[i]; + + if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED) + break; + + switch(AUVI_INPUT(i).type) { + case AU0828_VMUX_CABLE: + case AU0828_VMUX_TELEVISION: + case AU0828_VMUX_DVB: + if (tuner) + media_create_pad_link(ent, 0, tuner, + TUNER_PAD_RF_INPUT, + MEDIA_LNK_FL_ENABLED); + break; + case AU0828_VMUX_COMPOSITE: + case AU0828_VMUX_SVIDEO: + default: /* AU0828_VMUX_DEBUG */ + /* FIXME: fix the decoder PAD */ + media_create_pad_link(ent, 0, decoder, 0, 0); + break; + } + } #endif }
Due to the graph traversal algorithm currently in usage, we need a copy of all data links. Those backlinks should not be send to userspace, as otherwise, all links there will be duplicated.
Change-Id: Ib47a5f37b2a193fbd368bf17211da47dac5aa2ac Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 3 +++ drivers/media/media-entity.c | 1 + include/media/media-entity.h | 2 ++ 3 files changed, 6 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0238885fcc74..97eb97d9b662 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -333,6 +333,9 @@ static long __media_device_get_topology(struct media_device *mdev, /* Get links and number of links */ i = 0; media_device_for_each_link(link, mdev) { + if (link->is_backlink) + continue; + i++;
if (ret || !topo->links) diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index cd4d767644df..4868b8269204 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -648,6 +648,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->source = &source->pads[source_pad]; backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags; + backlink->is_backlink = true;
/* Initialize graph object embedded at the new link */ media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK, diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e1a89899deef..3d389f142a1d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -96,6 +96,7 @@ struct media_pipeline { * @reverse: Pointer to the link for the reverse direction of a pad to pad * link. * @flags: Link flags, as defined at uapi/media.h (MEDIA_LNK_FL_*) + * @is_backlink: Indicate if the link is a backlink. */ struct media_link { struct media_gobj graph_obj; @@ -112,6 +113,7 @@ struct media_link { }; struct media_link *reverse; unsigned long flags; + bool is_backlink; };
/**
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Due to the graph traversal algorithm currently in usage, we need a copy of all data links. Those backlinks should not be send to userspace, as otherwise, all links there will be duplicated.
Change-Id: Ib47a5f37b2a193fbd368bf17211da47dac5aa2ac Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 3 +++ drivers/media/media-entity.c | 1 + include/media/media-entity.h | 2 ++ 3 files changed, 6 insertions(+)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 0238885fcc74..97eb97d9b662 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -333,6 +333,9 @@ static long __media_device_get_topology(struct media_device *mdev, /* Get links and number of links */ i = 0; media_device_for_each_link(link, mdev) {
if (link->is_backlink)
continue;
i++;
if (ret || !topo->links)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index cd4d767644df..4868b8269204 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -648,6 +648,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, backlink->source = &source->pads[source_pad]; backlink->sink = &sink->pads[sink_pad]; backlink->flags = flags;
backlink->is_backlink = true;
/* Initialize graph object embedded at the new link */ media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK,
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e1a89899deef..3d389f142a1d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -96,6 +96,7 @@ struct media_pipeline {
- @reverse: Pointer to the link for the reverse direction of a pad to pad
link.
- @flags: Link flags, as defined at uapi/media.h (MEDIA_LNK_FL_*)
*/
- @is_backlink: Indicate if the link is a backlink.
struct media_link { struct media_gobj graph_obj; @@ -112,6 +113,7 @@ struct media_link { }; struct media_link *reverse; unsigned long flags;
- bool is_backlink;
};
/**
Interface links are normally enabled, meaning that the interfaces are bound to the entities. So, any ioctl send to the interface are reflected at the entities managed by the interface.
However, when a device is usage, other interfaces for the same hardware could be decoupled from the entities linked to them, because the hardware may have some parts busy.
That's for example, what happens when an hybrid TV device is in usage. If it is streaming analog TV or capturing signals from S-Video/Composite connectors, typically the digital part of the hardware can't be used and vice-versa.
This is generally due to some internal hardware or firmware limitation, that it is not easily mapped via data pipelines.
What the Kernel drivers do internally is that they decouple the hardware from the interface. So, all changes, if allowed, are done only at some interface cache, but not physically changed at the hardware.
The usage is similar to the usage of the MEDIA_LNK_FL_ENABLED on data links. So, let's use the same flag to indicate if ether the interface to entity link is bound/enabled or not.
Change-Id: I23bf95d0fbe6b7237268ed9029fd79964f830203 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 17 +++++++++++------ drivers/media/v4l2-core/v4l2-dev.c | 3 ++- drivers/media/v4l2-core/v4l2-device.c | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index a8e7e2398f7a..5c4fb41060b4 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -396,7 +396,8 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, if (!dvbdev->entity || !dvbdev->intf_devnode) return;
- media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, 0); + media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, + MEDIA_LNK_FL_ENABLED);
#endif } @@ -583,20 +584,24 @@ void dvb_create_media_graph(struct dvb_adapter *adap) /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ media_device_for_each_intf(intf, mdev) { if (intf->type == MEDIA_INTF_T_DVB_CA && ca) - media_create_intf_link(ca, intf, 0); + media_create_intf_link(ca, intf, MEDIA_LNK_FL_ENABLED);
if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) - media_create_intf_link(tuner, intf, 0); + media_create_intf_link(tuner, intf, + MEDIA_LNK_FL_ENABLED);
if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) - media_create_intf_link(demux, intf, 0); + media_create_intf_link(demux, intf, + MEDIA_LNK_FL_ENABLED);
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); + media_create_intf_link(entity, intf, + MEDIA_LNK_FL_ENABLED); if (!strcmp(entity->name, DEMUX_TSOUT)) - media_create_intf_link(entity, intf, 0); + media_create_intf_link(entity, intf, + MEDIA_LNK_FL_ENABLED); break; } } diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 07123dd569c4..8429da66754a 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -788,7 +788,8 @@ static int video_register_media_controller(struct video_device *vdev, int type) struct media_link *link;
link = media_create_intf_link(&vdev->entity, - &vdev->intf_devnode->intf, 0); + &vdev->intf_devnode->intf, + MEDIA_LNK_FL_ENABLED); if (!link) { media_devnode_remove(vdev->intf_devnode); media_device_unregister_entity(&vdev->entity); diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index e788a085ba96..bb58d90fde5e 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -256,7 +256,7 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
link = media_create_intf_link(&sd->entity, &vdev->intf_devnode->intf, - 0); + MEDIA_LNK_FL_ENABLED); if (!link) goto clean_up; }
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Interface links are normally enabled, meaning that the interfaces are bound to the entities. So, any ioctl send to the interface are reflected at the entities managed by the interface.
However, when a device is usage, other interfaces for the same hardware could be decoupled from the entities linked to them, because the hardware may have some parts busy.
That's for example, what happens when an hybrid TV device is in usage. If it is streaming analog TV or capturing signals from S-Video/Composite connectors, typically the digital part of the hardware can't be used and vice-versa.
This is generally due to some internal hardware or firmware limitation, that it is not easily mapped via data pipelines.
What the Kernel drivers do internally is that they decouple the hardware from the interface. So, all changes, if allowed, are done only at some interface cache, but not physically changed at the hardware.
The usage is similar to the usage of the MEDIA_LNK_FL_ENABLED on data links. So, let's use the same flag to indicate if ether the interface to entity link is bound/enabled or not.
Change-Id: I23bf95d0fbe6b7237268ed9029fd79964f830203 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/dvb-core/dvbdev.c | 17 +++++++++++------ drivers/media/v4l2-core/v4l2-dev.c | 3 ++- drivers/media/v4l2-core/v4l2-device.c | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index a8e7e2398f7a..5c4fb41060b4 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -396,7 +396,8 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, if (!dvbdev->entity || !dvbdev->intf_devnode) return;
- media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, 0);
- media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf,
MEDIA_LNK_FL_ENABLED);
#endif } @@ -583,20 +584,24 @@ void dvb_create_media_graph(struct dvb_adapter *adap) /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ media_device_for_each_intf(intf, mdev) { if (intf->type == MEDIA_INTF_T_DVB_CA && ca)
media_create_intf_link(ca, intf, 0);
media_create_intf_link(ca, intf, MEDIA_LNK_FL_ENABLED);
if (intf->type == MEDIA_INTF_T_DVB_FE && tuner)
media_create_intf_link(tuner, intf, 0);
media_create_intf_link(tuner, intf,
MEDIA_LNK_FL_ENABLED);
if (intf->type == MEDIA_INTF_T_DVB_DVR && demux)
media_create_intf_link(demux, intf, 0);
media_create_intf_link(demux, intf,
MEDIA_LNK_FL_ENABLED);
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);
media_create_intf_link(entity, intf,
MEDIA_LNK_FL_ENABLED); if (!strcmp(entity->name, DEMUX_TSOUT))
media_create_intf_link(entity, intf, 0);
media_create_intf_link(entity, intf,
}MEDIA_LNK_FL_ENABLED); break; }
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 07123dd569c4..8429da66754a 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -788,7 +788,8 @@ static int video_register_media_controller(struct video_device *vdev, int type) struct media_link *link;
link = media_create_intf_link(&vdev->entity,
&vdev->intf_devnode->intf, 0);
&vdev->intf_devnode->intf,
if (!link) { media_devnode_remove(vdev->intf_devnode); media_device_unregister_entity(&vdev->entity);MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index e788a085ba96..bb58d90fde5e 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -256,7 +256,7 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
link = media_create_intf_link(&sd->entity, &vdev->intf_devnode->intf,
0);
}MEDIA_LNK_FL_ENABLED); if (!link) goto clean_up;
Add entities to represent the connectors that exists inside a hybrid TV device.
Change-Id: I2bcf7be3168290d74f6e8cb32ba699e9118a0859 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/uapi/linux/media.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index b17f6763aff4..69433405aec2 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -61,6 +61,7 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_BASE 0x00000000 #define MEDIA_ENT_T_V4L2_BASE 0x00010000 #define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 +#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000
/* * V4L2 entities - Those are used for DMA (mmap/DMABUF) and @@ -105,6 +106,13 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) #define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5)
+/* Connectors */ +#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE) +#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 1) +#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 2) + /* For internal test signal generators and other debug connectors */ +#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 3) + #ifndef __KERNEL__ /* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 @@ -121,9 +129,9 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) #endif
-/* Entity types */ - +/* Entity flags */ #define MEDIA_ENT_FL_DEFAULT (1 << 0) +#define MEDIA_ENT_FL_CONNECTOR (1 << 1)
struct media_entity_desc { __u32 id;
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Add entities to represent the connectors that exists inside a hybrid TV device.
Change-Id: I2bcf7be3168290d74f6e8cb32ba699e9118a0859 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Why is this here? It doesn't seem to be used anywhere yet. I do agree with this patch, but I think it should be done as a separate patch series.
Hans
include/uapi/linux/media.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index b17f6763aff4..69433405aec2 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -61,6 +61,7 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_BASE 0x00000000 #define MEDIA_ENT_T_V4L2_BASE 0x00010000 #define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 +#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000
/*
- V4L2 entities - Those are used for DMA (mmap/DMABUF) and
@@ -105,6 +106,13 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) #define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5)
+/* Connectors */ +#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE) +#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 1) +#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 2)
- /* For internal test signal generators and other debug connectors */
+#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 3)
#ifndef __KERNEL__ /* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 @@ -121,9 +129,9 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) #endif
-/* Entity types */
+/* Entity flags */ #define MEDIA_ENT_FL_DEFAULT (1 << 0) +#define MEDIA_ENT_FL_CONNECTOR (1 << 1)
struct media_entity_desc { __u32 id;
Right now, if something gets wrong at dvb_create_media_entity() or at dvb_create_media_graph(), the device will still be registered.
Change the logic to properly handle it and free all media graph objects if something goes wrong at dvb_register_device().
Also, change the logic at dvb_create_media_graph() to return an error code if something goes wrong. It is up to the caller to implement the right logic and to call dvb_unregister_device() to unregister the already-created objects.
While here, add a missing logic to unregister the created interfaces.
Change-Id: Iffb9de2a48742958ca1ab7246337a0f3a7210573 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 293 ++++++++++++++++++++++------------------ drivers/media/dvb-core/dvbdev.h | 7 +- 2 files changed, 169 insertions(+), 131 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 5c4fb41060b4..5c51084a331a 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -183,7 +183,29 @@ skip: return -ENFILE; }
-static void dvb_create_tsout_entity(struct dvb_device *dvbdev, +static void dvb_media_device_free(struct dvb_device *dvbdev) +{ +#if defined(CONFIG_MEDIA_CONTROLLER_DVB) + if (dvbdev->entity) { + int i; + + for (i = 0; i < dvbdev->tsout_num_entities; i++) { + media_device_unregister_entity(&dvbdev->tsout_entity[i]); + kfree(dvbdev->tsout_entity[i].name); + } + media_device_unregister_entity(dvbdev->entity); + + kfree(dvbdev->entity); + kfree(dvbdev->pads); + kfree(dvbdev->tsout_entity); + kfree(dvbdev->tsout_pads); + } + if (dvbdev->intf_devnode) + media_devnode_remove(dvbdev->intf_devnode); +#endif +} + +static int dvb_create_tsout_entity(struct dvb_device *dvbdev, const char *name, int npads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) @@ -192,77 +214,60 @@ static void dvb_create_tsout_entity(struct dvb_device *dvbdev, dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads), GFP_KERNEL); if (!dvbdev->tsout_pads) - return; + return -ENOMEM; + dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity), GFP_KERNEL); - if (!dvbdev->tsout_entity) { - kfree(dvbdev->tsout_pads); - dvbdev->tsout_pads = NULL; - return; - } + if (!dvbdev->tsout_entity) + return -ENOMEM; + 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; - } + if (!entity->name) + return ret;
entity->type = MEDIA_ENT_T_DVB_TSOUT; pads->flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(entity, 1, pads); if (ret < 0) - break; + return ret;
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); + return ret; } - - 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 + return 0; }
#define DEMUX_TSOUT "demux-tsout" #define DVR_TSOUT "dvr-tsout"
-static void dvb_create_media_entity(struct dvb_device *dvbdev, - int type, int demux_sink_pads) +static int dvb_create_media_entity(struct dvb_device *dvbdev, + int type, int demux_sink_pads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) - int i, ret = 0, npads; + int i, ret, 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; + ret = dvb_create_tsout_entity(dvbdev, DVR_TSOUT, + demux_sink_pads); + return ret; case DVB_DEVICE_DEMUX: npads = 1 + demux_sink_pads; - dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, demux_sink_pads); + ret = dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, + demux_sink_pads); + if (ret < 0) + return ret; break; case DVB_DEVICE_CA: npads = 2; @@ -277,24 +282,22 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, * the Media Controller, let's not create the decap * entities yet. */ - return; + return 0; default: - return; + return 0; }
dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL); if (!dvbdev->entity) - return; + return -ENOMEM;
dvbdev->entity->name = dvbdev->name;
if (npads) { dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), GFP_KERNEL); - if (!dvbdev->pads) { - kfree(dvbdev->entity); - return; - } + if (!dvbdev->pads) + return -ENOMEM; }
switch (type) { @@ -316,49 +319,43 @@ static void dvb_create_media_entity(struct dvb_device *dvbdev, break; default: kfree(dvbdev->entity); + kfree(dvbdev->pads); dvbdev->entity = NULL; - return; + return 0; }
- if (npads) + if (npads) { ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads); - if (!ret) - ret = media_device_register_entity(dvbdev->adapter->mdev, - dvbdev->entity); - if (ret < 0) { - 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; + if (ret) + return ret; } + ret = media_device_register_entity(dvbdev->adapter->mdev, + dvbdev->entity); + if (ret) + return (ret);
printk(KERN_DEBUG "%s: media entity '%s' registered.\n", __func__, dvbdev->entity->name); + #endif + return 0; }
-static void dvb_register_media_device(struct dvb_device *dvbdev, - int type, int minor, - unsigned demux_sink_pads) +static int dvb_register_media_device(struct dvb_device *dvbdev, + int type, int minor, + unsigned demux_sink_pads) { #if defined(CONFIG_MEDIA_CONTROLLER_DVB) + struct media_link *link; u32 intf_type; + int ret;
if (!dvbdev->adapter->mdev) - return; + return 0;
- dvb_create_media_entity(dvbdev, type, demux_sink_pads); + ret = dvb_create_media_entity(dvbdev, type, demux_sink_pads); + if (ret) + return ret;
switch (type) { case DVB_DEVICE_FRONTEND: @@ -377,13 +374,16 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, intf_type = MEDIA_INTF_T_DVB_NET; break; default: - return; + return 0; }
dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev, - intf_type, 0, - DVB_MAJOR, minor, - GFP_KERNEL); + intf_type, 0, + DVB_MAJOR, minor, + GFP_KERNEL); + + if (!dvbdev->intf_devnode) + return -ENOMEM;
/* * Create the "obvious" link, e. g. the ones that represent @@ -393,13 +393,15 @@ static void dvb_register_media_device(struct dvb_device *dvbdev, * DVB demux intf -> dvr */
- if (!dvbdev->entity || !dvbdev->intf_devnode) - return; - - media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, - MEDIA_LNK_FL_ENABLED); + if (!dvbdev->entity) + return 0;
+ link = media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; #endif + return 0; }
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, @@ -410,7 +412,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, struct file_operations *dvbdevfops; struct device *clsdev; int minor; - int id; + int id, ret;
mutex_lock(&dvbdev_register_lock);
@@ -428,6 +430,17 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENOMEM; }
+ ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); + if (ret) { + printk(KERN_ERR + "%s: dvb_register_media_device failed to create the mediagraph\n", + __func__); + + dvb_media_device_free(dvbdev); + mutex_unlock(&dvbdev_register_lock); + return ret; + } + dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
if (!dvbdevfops){ @@ -483,8 +496,6 @@ 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, demux_sink_pads); - return 0; } EXPORT_SYMBOL(dvb_register_device); @@ -499,24 +510,9 @@ void dvb_unregister_device(struct dvb_device *dvbdev) dvb_minors[dvbdev->minor] = NULL; up_write(&minor_rwsem);
- device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); - -#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); - } + dvb_media_device_free(dvbdev);
- kfree(dvbdev->entity); - kfree(dvbdev->pads); - kfree(dvbdev->tsout_entity); - kfree(dvbdev->tsout_pads); - } -#endif + device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
list_del (&dvbdev->list_head); kfree (dvbdev->fops); @@ -526,17 +522,19 @@ EXPORT_SYMBOL(dvb_unregister_device);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB -void dvb_create_media_graph(struct dvb_adapter *adap) +int 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, *ca = NULL; + struct media_link *link; struct media_interface *intf; unsigned demux_pad = 0; unsigned dvr_pad = 0; + int ret;
if (!mdev) - return; + return 0;
media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -555,57 +553,94 @@ void dvb_create_media_graph(struct dvb_adapter *adap) } }
- if (tuner && demod) - media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, demod, 0, 0); + if (tuner && demod) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, + demod, 0, MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + }
- if (demod && demux) - media_create_pad_link(demod, 1, demux, 0, MEDIA_LNK_FL_ENABLED); - if (demux && ca) - media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); + if (demod && demux) { + ret = media_create_pad_link(demod, 1, demux, + 0, MEDIA_LNK_FL_ENABLED); + if (ret) + return -ENOMEM; + } + if (demux && ca) { + ret = media_create_pad_link(demux, 1, ca, + 0, MEDIA_LNK_FL_ENABLED); + if (!ret) + return -ENOMEM; + }
/* 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); + strlen(DVR_TSOUT))) { + ret = media_create_pad_link(demux, + ++dvr_pad, + entity, 0, 0); + if (ret) + return ret; + } if (!strncmp(entity->name, DEMUX_TSOUT, - strlen(DEMUX_TSOUT))) - media_create_pad_link(demux, + strlen(DEMUX_TSOUT))) { + ret = media_create_pad_link(demux, ++demux_pad, - entity, 0, 0); + entity, 0, 0); + if (ret) + return ret; + } } } }
/* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ media_device_for_each_intf(intf, mdev) { - if (intf->type == MEDIA_INTF_T_DVB_CA && ca) - media_create_intf_link(ca, intf, MEDIA_LNK_FL_ENABLED); + if (intf->type == MEDIA_INTF_T_DVB_CA && ca) { + link = media_create_intf_link(ca, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + }
- if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) - media_create_intf_link(tuner, intf, - MEDIA_LNK_FL_ENABLED); + if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) { + link = media_create_intf_link(tuner, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + }
- if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) - media_create_intf_link(demux, intf, - MEDIA_LNK_FL_ENABLED); + if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) { + link = media_create_intf_link(demux, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + }
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, - MEDIA_LNK_FL_ENABLED); - if (!strcmp(entity->name, DEMUX_TSOUT)) - media_create_intf_link(entity, intf, - MEDIA_LNK_FL_ENABLED); + if (!strcmp(entity->name, DVR_TSOUT)) { + link = media_create_intf_link(entity, + intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } + if (!strcmp(entity->name, DEMUX_TSOUT)) { + link = media_create_intf_link(entity, + intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } break; } } } + return 0; } EXPORT_SYMBOL_GPL(dvb_create_media_graph); #endif diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 0b140e8595de..9e24aafeb9ea 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -210,7 +210,7 @@ int dvb_register_device(struct dvb_adapter *adap, void dvb_unregister_device(struct dvb_device *dvbdev);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB -void dvb_create_media_graph(struct dvb_adapter *adap); +int dvb_create_media_graph(struct dvb_adapter *adap); static inline void dvb_register_media_controller(struct dvb_adapter *adap, struct media_device *mdev) { @@ -218,7 +218,10 @@ static inline void dvb_register_media_controller(struct dvb_adapter *adap, }
#else -static inline void dvb_create_media_graph(struct dvb_adapter *adap) {} +static inline int dvb_create_media_graph(struct dvb_adapter *adap) +{ + return 0; +}; #define dvb_register_media_controller(a, b) {} #endif
If media controller is enabled and mdev is filled, it should ensure that the media graph will be properly initialized.
Enforce that.
Change-Id: I72205ca891fe877cdb41b0552c3fe0abb008d4b7 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/common/siano/smsdvb-main.c | 6 +++++- drivers/media/dvb-core/dvbdev.c | 22 +++++++++++----------- drivers/media/dvb-core/dvbdev.h | 2 +- drivers/media/usb/au0828/au0828-dvb.c | 8 +++++--- drivers/media/usb/cx231xx/cx231xx-dvb.c | 6 +++++- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 4 +++- drivers/media/usb/dvb-usb/dvb-usb-dvb.c | 6 ++++-- 7 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index f4305ae800f4..ab345490a43a 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1183,7 +1183,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, if (smsdvb_debugfs_create(client) < 0) pr_info("failed to create debugfs node\n");
- dvb_create_media_graph(&client->adapter); + rc = dvb_create_media_graph(&client->adapter); + if (rc < 0) { + pr_err("dvb_create_media_graph failed %d\n", rc); + goto client_error; + }
pr_info("DVB interface registered.\n"); return 0; diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 5c51084a331a..df2fe4cc2d47 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -430,17 +430,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENOMEM; }
- ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); - if (ret) { - printk(KERN_ERR - "%s: dvb_register_media_device failed to create the mediagraph\n", - __func__); - - dvb_media_device_free(dvbdev); - mutex_unlock(&dvbdev_register_lock); - return ret; - } - dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
if (!dvbdevfops){ @@ -493,6 +482,17 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); return PTR_ERR(clsdev); } + + ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); + if (ret) { + printk(KERN_ERR + "%s: dvb_register_media_device failed to create the media graph\n", + __func__); + + dvb_unregister_device(dvbdev); + return ret; + } + dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, minor, minor);
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 9e24aafeb9ea..bd9fac91c7b9 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -210,7 +210,7 @@ int dvb_register_device(struct dvb_adapter *adap, void dvb_unregister_device(struct dvb_device *dvbdev);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB -int dvb_create_media_graph(struct dvb_adapter *adap); +__must_check int dvb_create_media_graph(struct dvb_adapter *adap); static inline void dvb_register_media_controller(struct dvb_adapter *adap, struct media_device *mdev) { diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index c01772c4f9f0..cd542b49a6c2 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -486,12 +486,14 @@ static int dvb_register(struct au0828_dev *dev) dvb->start_count = 0; dvb->stop_count = 0;
-#ifdef CONFIG_MEDIA_CONTROLLER_DVB - dvb_create_media_graph(&dvb->adapter); -#endif + result = dvb_create_media_graph(&dvb->adapter); + if (result < 0) + goto fail_create_graph;
return 0;
+fail_create_graph: + dvb_net_release(&dvb->net); fail_fe_conn: dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); fail_fe_mem: diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 66ee161fc7ba..aaf8ef246f13 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -551,10 +551,14 @@ static int register_dvb(struct cx231xx_dvb *dvb,
/* register network adapter */ dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); - dvb_create_media_graph(&dvb->adapter); + result = dvb_create_media_graph(&dvb->adapter); + if (result < 0) + goto fail_create_graph;
return 0;
+fail_create_graph: + dvb_net_release(&dvb->net); fail_fe_conn: dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); fail_fe_mem: diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index f5df9eaba04f..6d3f61f6dc77 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -698,7 +698,9 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) } }
- dvb_create_media_graph(&adap->dvb_adap); + ret = dvb_create_media_graph(&adap->dvb_adap); + if (ret < 0) + goto err_dvb_unregister_frontend;
return 0;
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index 8a260c854653..b51dbdf03f42 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -318,10 +318,12 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
adap->num_frontends_initialized++; } + if (ret) + return ret;
- dvb_create_media_graph(&adap->dvb_adap); + ret = dvb_create_media_graph(&adap->dvb_adap);
- return 0; + return ret; }
int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
Drivers should check if interfaces and interface links were created. Add a must_check for them.
Change-Id: I197e4a9cc4f4d1208ae596ec067979fc3f757c67 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/media/media-entity.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 3d389f142a1d..62f882d872b1 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -370,14 +370,16 @@ __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); +struct media_intf_devnode * +__must_check 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); -struct media_link *media_create_intf_link(struct media_entity *entity, - struct media_interface *intf, - u32 flags); +struct media_link * +__must_check 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_links(struct media_interface *intf); void media_remove_intf_links(struct media_interface *intf);
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
Drivers should check if interfaces and interface links were created. Add a must_check for them.
Change-Id: I197e4a9cc4f4d1208ae596ec067979fc3f757c67 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
include/media/media-entity.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 3d389f142a1d..62f882d872b1 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -370,14 +370,16 @@ __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);
+struct media_intf_devnode * +__must_check 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); -struct media_link *media_create_intf_link(struct media_entity *entity,
struct media_interface *intf,
u32 flags);
+struct media_link * +__must_check 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_links(struct media_interface *intf); void media_remove_intf_links(struct media_interface *intf);
If the graph creation fails, don't register the device.
Change-Id: I771dfb29747d860dd28358021e559cb63bf8f69f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/usb/cx231xx/cx231xx-cards.c | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 1070d87efc65..c05aaef85491 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1185,8 +1185,6 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev) */ void cx231xx_release_resources(struct cx231xx *dev) { - cx231xx_unregister_media_device(dev); - cx231xx_release_analog_resources(dev);
cx231xx_remove_from_devlist(dev); @@ -1199,6 +1197,8 @@ void cx231xx_release_resources(struct cx231xx *dev) /* delete v4l2 device */ v4l2_device_unregister(&dev->v4l2_dev);
+ cx231xx_unregister_media_device(dev); + usb_put_dev(dev->udev);
/* Mark device as unused */ @@ -1237,15 +1237,16 @@ static void cx231xx_media_device_register(struct cx231xx *dev, #endif }
-static void cx231xx_create_media_graph(struct cx231xx *dev) +static int cx231xx_create_media_graph(struct cx231xx *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; + int ret;
if (!mdev) - return; + return 0;
media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -1261,16 +1262,24 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) /* Analog setup, using tuner as a link */
if (!decoder) - return; + return 0;
- if (tuner) - media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, - 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); + if (tuner) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + } + ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; + ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret < 0) + return ret; #endif + return 0; }
/* @@ -1732,9 +1741,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* load other modules required */ request_modules(dev);
- cx231xx_create_media_graph(dev); + retval = cx231xx_create_media_graph(dev); + if (retval < 0) { + cx231xx_release_resources(dev); + }
- return 0; + return retval; err_video_alt: /* cx231xx_uninit_dev: */ cx231xx_close_extension(dev);
On 10/12/2015 06:43 PM, Mauro Carvalho Chehab wrote:
If the graph creation fails, don't register the device.
Change-Id: I771dfb29747d860dd28358021e559cb63bf8f69f Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/usb/cx231xx/cx231xx-cards.c | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 1070d87efc65..c05aaef85491 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1185,8 +1185,6 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev) */ void cx231xx_release_resources(struct cx231xx *dev) {
cx231xx_unregister_media_device(dev);
cx231xx_release_analog_resources(dev);
cx231xx_remove_from_devlist(dev);
@@ -1199,6 +1197,8 @@ void cx231xx_release_resources(struct cx231xx *dev) /* delete v4l2 device */ v4l2_device_unregister(&dev->v4l2_dev);
cx231xx_unregister_media_device(dev);
usb_put_dev(dev->udev);
/* Mark device as unused */
@@ -1237,15 +1237,16 @@ static void cx231xx_media_device_register(struct cx231xx *dev, #endif }
-static void cx231xx_create_media_graph(struct cx231xx *dev) +static int cx231xx_create_media_graph(struct cx231xx *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL;
int ret;
if (!mdev)
return;
return 0;
media_device_for_each_entity(entity, mdev) { switch (entity->type) {
@@ -1261,16 +1262,24 @@ static void cx231xx_create_media_graph(struct cx231xx *dev) /* Analog setup, using tuner as a link */
if (!decoder)
return;
return 0;
- if (tuner)
media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
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);
- if (tuner) {
ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
MEDIA_LNK_FL_ENABLED);
if (ret < 0)
return ret;
- }
- ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
MEDIA_LNK_FL_ENABLED);
- if (ret < 0)
return ret;
- ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
MEDIA_LNK_FL_ENABLED);
- if (ret < 0)
return ret;
#endif
- return 0;
}
/* @@ -1732,9 +1741,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* load other modules required */ request_modules(dev);
- cx231xx_create_media_graph(dev);
- retval = cx231xx_create_media_graph(dev);
- if (retval < 0) {
cx231xx_release_resources(dev);
- }
No need for {}: checkpatch should have reported that.
After changing this:
Acked-by: Hans Verkuil hans.verkuil@cisco.com
- return 0;
- return retval;
err_video_alt: /* cx231xx_uninit_dev: */ cx231xx_close_extension(dev);
If the graph creation fails, don't register the device.
Change-Id: Ifb14721ce56419b712598b8d461987475a6887c6 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/usb/au0828/au0828-core.c | 58 +++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 35c607c35155..399c6712faf9 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -172,9 +172,9 @@ static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) struct au0828_dev *dev = container_of(v4l2_dev, struct au0828_dev, v4l2_dev);
- au0828_usb_v4l2_media_release(dev); v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev); + au0828_usb_v4l2_media_release(dev); au0828_usb_release(dev); } #endif @@ -251,16 +251,16 @@ static void au0828_media_device_register(struct au0828_dev *dev, }
-static void au0828_create_media_graph(struct au0828_dev *dev) +static int au0828_create_media_graph(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL; - int i; + int i, ret;
if (!mdev) - return; + return 0;
media_device_for_each_entity(entity, mdev) { switch (entity->type) { @@ -277,15 +277,23 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
/* Something bad happened! */ if (!decoder) - return; - - if (tuner) - media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0, - 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); + return -EINVAL; + + if (tuner) { + ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, + decoder, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + } + ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; + ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret;
for (i = 0; i < AU0828_MAX_INPUT; i++) { struct media_entity *ent = &dev->input_ent[i]; @@ -297,20 +305,27 @@ static void au0828_create_media_graph(struct au0828_dev *dev) case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB: - if (tuner) - media_create_pad_link(ent, 0, tuner, - TUNER_PAD_RF_INPUT, - MEDIA_LNK_FL_ENABLED); + if (!tuner) + break; + + ret = media_create_pad_link(ent, 0, tuner, + TUNER_PAD_RF_INPUT, + MEDIA_LNK_FL_ENABLED); + if (ret) + return ret; break; case AU0828_VMUX_COMPOSITE: case AU0828_VMUX_SVIDEO: default: /* AU0828_VMUX_DEBUG */ /* FIXME: fix the decoder PAD */ - media_create_pad_link(ent, 0, decoder, 0, 0); + ret = media_create_pad_link(ent, 0, decoder, 0, 0); + if (ret) + return ret; break; } } #endif + return 0; }
static int au0828_usb_probe(struct usb_interface *interface, @@ -425,7 +440,12 @@ static int au0828_usb_probe(struct usb_interface *interface,
mutex_unlock(&dev->lock);
- au0828_create_media_graph(dev); + retval = au0828_create_media_graph(dev); + if (retval) { + pr_err("%s() au0282_dev_register failed to create graph\n", + __func__); + au0828_usb_disconnect(interface); + }
return retval; }
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
If the graph creation fails, don't register the device.
Change-Id: Ifb14721ce56419b712598b8d461987475a6887c6 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/usb/au0828/au0828-core.c | 58 +++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 35c607c35155..399c6712faf9 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -172,9 +172,9 @@ static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) struct au0828_dev *dev = container_of(v4l2_dev, struct au0828_dev, v4l2_dev);
- au0828_usb_v4l2_media_release(dev); v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); v4l2_device_unregister(&dev->v4l2_dev);
- au0828_usb_v4l2_media_release(dev); au0828_usb_release(dev);
} #endif @@ -251,16 +251,16 @@ static void au0828_media_device_register(struct au0828_dev *dev, }
-static void au0828_create_media_graph(struct au0828_dev *dev) +static int au0828_create_media_graph(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev = dev->media_dev; struct media_entity *entity; struct media_entity *tuner = NULL, *decoder = NULL;
- int i;
int i, ret;
if (!mdev)
return;
return 0;
media_device_for_each_entity(entity, mdev) { switch (entity->type) {
@@ -277,15 +277,23 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
/* Something bad happened! */ if (!decoder)
return;
- if (tuner)
media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
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);
return -EINVAL;
if (tuner) {
ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
decoder, 0,
MEDIA_LNK_FL_ENABLED);
if (ret)
return ret;
}
ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
MEDIA_LNK_FL_ENABLED);
if (ret)
return ret;
ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
MEDIA_LNK_FL_ENABLED);
if (ret)
return ret;
for (i = 0; i < AU0828_MAX_INPUT; i++) { struct media_entity *ent = &dev->input_ent[i];
@@ -297,20 +305,27 @@ static void au0828_create_media_graph(struct au0828_dev *dev) case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB:
if (tuner)
media_create_pad_link(ent, 0, tuner,
TUNER_PAD_RF_INPUT,
MEDIA_LNK_FL_ENABLED);
if (!tuner)
break;
ret = media_create_pad_link(ent, 0, tuner,
TUNER_PAD_RF_INPUT,
MEDIA_LNK_FL_ENABLED);
if (ret)
case AU0828_VMUX_COMPOSITE: case AU0828_VMUX_SVIDEO: default: /* AU0828_VMUX_DEBUG */ /* FIXME: fix the decoder PAD */return ret; break;
media_create_pad_link(ent, 0, decoder, 0, 0);
ret = media_create_pad_link(ent, 0, decoder, 0, 0);
if (ret)
} }return ret; break;
#endif
- return 0;
}
static int au0828_usb_probe(struct usb_interface *interface, @@ -425,7 +440,12 @@ static int au0828_usb_probe(struct usb_interface *interface,
mutex_unlock(&dev->lock);
- au0828_create_media_graph(dev);
retval = au0828_create_media_graph(dev);
if (retval) {
pr_err("%s() au0282_dev_register failed to create graph\n",
__func__);
au0828_usb_disconnect(interface);
}
return retval;
}
Drivers should check if media_create_pad_link() actually worked.
Change-Id: I6fe11797973df4f044cda1c9ac07279ba493c1df Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- include/media/media-entity.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 62f882d872b1..8bdc10dcc5e7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -348,8 +348,9 @@ int media_entity_init(struct media_entity *entity, u16 num_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, - struct media_entity *sink, u16 sink_pad, u32 flags); +__must_check int media_create_pad_link(struct media_entity *source, + u16 source_pad, struct media_entity *sink, + u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); void media_entity_remove_links(struct media_entity *entity);
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Drivers should check if media_create_pad_link() actually worked.
Change-Id: I6fe11797973df4f044cda1c9ac07279ba493c1df Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
include/media/media-entity.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 62f882d872b1..8bdc10dcc5e7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -348,8 +348,9 @@ int media_entity_init(struct media_entity *entity, u16 num_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,
struct media_entity *sink, u16 sink_pad, u32 flags);
+__must_check int media_create_pad_link(struct media_entity *source,
u16 source_pad, struct media_entity *sink,
u16 sink_pad, u32 flags);
void __media_entity_remove_links(struct media_entity *entity); void media_entity_remove_links(struct media_entity *entity);
Entities should have one or more functions. Calling it as a type proofed to not be correct, as an entity could eventually have more than one type.
So, rename the field as function.
Please notice that this patch doesn't extend support for multiple function entities. Such change will happen when we have real case drivers using it.
No functional changes.
Change-Id: I30e521e988594ca132a1c42c58130732788313cc Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- Documentation/video4linux/v4l2-framework.txt | 4 ++-- drivers/media/dvb-core/dvbdev.c | 14 +++++++------- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 6 +++--- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- drivers/media/media-device.c | 6 +++--- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/usb/au0828/au0828-core.c | 2 +- drivers/media/usb/au0828/au0828-video.c | 8 ++++---- drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 14 +++++++------- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 6 +++--- include/media/media-entity.h | 9 +++++---- 28 files changed, 55 insertions(+), 54 deletions(-)
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 109cc3792534..2e0fc28fa12f 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -303,8 +303,8 @@ calling media_entity_init(): err = media_entity_init(&sd->entity, npads, pads);
The pads array must have been previously initialized. There is no need to -manually set the struct media_entity type and name fields, but the revision -field must be initialized if needed. +manually set the struct media_entity function and name fields, but the +revision field must be initialized if needed.
A reference to the entity will be automatically acquired/released when the subdev device node (if any) is opened/closed. diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index df2fe4cc2d47..e925909bc99e 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -229,7 +229,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, if (!entity->name) return ret;
- entity->type = MEDIA_ENT_T_DVB_TSOUT; + entity->function = MEDIA_ENT_T_DVB_TSOUT; pads->flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(entity, 1, pads); @@ -302,18 +302,18 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
switch (type) { case DVB_DEVICE_FRONTEND: - dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMOD; + dvbdev->entity->function = 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_DVB_DEMUX; + dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMUX; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; 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; + dvbdev->entity->function = MEDIA_ENT_T_DVB_CA; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; @@ -537,7 +537,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) return 0;
media_device_for_each_entity(entity, mdev) { - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break; @@ -576,7 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) /* 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 (entity->function == MEDIA_ENT_T_DVB_TSOUT) { if (!strncmp(entity->name, DVR_TSOUT, strlen(DVR_TSOUT))) { ret = media_create_pad_link(demux, @@ -621,7 +621,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) }
media_device_for_each_entity(entity, mdev) { - if (entity->type == MEDIA_ENT_T_DVB_TSOUT) { + if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { if (!strcmp(entity->name, DVR_TSOUT)) { link = media_create_intf_link(entity, intf, diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 55cd42a584a5..a6fbe78a70e3 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -775,7 +775,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 5f76997f6e07..2b8f72ac0f7d 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -516,7 +516,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret < 0) goto free_and_quit;
- flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
return 0;
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index 9d579a836f79..a49ef7d6df18 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -831,7 +831,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done;
- flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
mutex_init(&flash->power_lock);
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 270135d06b32..d48a3a4df96b 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5208,7 +5208,7 @@ static int cx25840_probe(struct i2c_client *client, state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 9bd9def0852c..7c1abdca39d0 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -368,7 +368,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led[led_no].entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
return rval;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index 4160e18af607..d609f2fa8e6c 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -285,7 +285,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; return rval;
err_out: diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index f718a1009e4c..206319b88d7a 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -978,7 +978,7 @@ static int m5mols_probe(struct i2c_client *client, ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
init_waitqueue_head(&info->irq_waitq); mutex_init(&info->lock); diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index a9761251b970..6cd407bcfddf 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -779,7 +779,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err;
info->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 6bce9832ab7b..c085dec69201 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1445,7 +1445,7 @@ static int ov2659_probe(struct i2c_client *client,
#if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls); diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 8a8eb593fc23..2862244a6488 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1500,7 +1500,7 @@ static int ov965x_probe(struct i2c_client *client, return ret;
ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index abae37321c0c..3f55168cce47 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads); @@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; - oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + oif_sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads); diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index d207ddce31b6..45f6e6f2585a 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -961,7 +961,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
priv->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &priv->pad); if (ret) return ret; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 0513196bd48c..22dfeadf7672 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -408,7 +408,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd) { - return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + return sd->entity.function == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; }
static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd) @@ -1904,7 +1904,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err; @@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
if (!ret) diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 39a461f9d9bb..71162c02d6d7 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1577,7 +1577,7 @@ static int s5k6aa_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 938201789ebc..dd2626c8ae53 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2763,7 +2763,7 @@ static int smiapp_init(struct smiapp_sensor *sensor)
dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
- sensor->pixel_array->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sensor->pixel_array->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
/* final steps */ smiapp_read_frame_fmt(sensor); diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 97eb97d9b662..ccef9621d147 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -108,7 +108,7 @@ static long media_device_enum_entities(struct media_device *mdev, u_ent.id = media_entity_id(ent); if (ent->name) strlcpy(u_ent.name, ent->name, sizeof(u_ent.name)); - u_ent.type = ent->type; + u_ent.type = ent->function; u_ent.revision = ent->revision; u_ent.flags = ent->flags; u_ent.group_id = ent->group_id; @@ -614,8 +614,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || - entity->type == MEDIA_ENT_T_UNKNOWN) + if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || + entity->function == MEDIA_ENT_T_UNKNOWN) dev_warn(mdev->dev, "Entity type for entity %s was not initialized!\n", entity->name); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 8e14841bf445..8bee7313a497 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -191,7 +191,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_V4L2_VIDEO) + if (entity->function != MEDIA_ENT_T_V4L2_VIDEO) continue;
dma = to_xvip_dma(media_entity_to_video_device(entity)); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 399c6712faf9..44a2ab3c85ab 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -263,7 +263,7 @@ static int au0828_create_media_graph(struct au0828_dev *dev) return 0;
media_device_for_each_entity(entity, mdev) { - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break; diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 806b8d320bae..5c01f37cd0b8 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1830,18 +1830,18 @@ static void au0828_analog_create_entities(struct au0828_dev *dev)
switch(AUVI_INPUT(i).type) { case AU0828_VMUX_COMPOSITE: - ent->type = MEDIA_ENT_T_CONN_COMPOSITE; + ent->function = MEDIA_ENT_T_CONN_COMPOSITE; break; case AU0828_VMUX_SVIDEO: - ent->type = MEDIA_ENT_T_CONN_SVIDEO; + ent->function = MEDIA_ENT_T_CONN_SVIDEO; break; case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB: - ent->type = MEDIA_ENT_T_CONN_RF; + ent->function = MEDIA_ENT_T_CONN_RF; break; default: /* AU0828_VMUX_DEBUG */ - ent->type = MEDIA_ENT_T_CONN_TEST; + ent->function = MEDIA_ENT_T_CONN_TEST; break; }
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index c05aaef85491..b01d6bce3cf6 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1249,7 +1249,7 @@ static int cx231xx_create_media_graph(struct cx231xx *dev) return 0;
media_device_for_each_entity(entity, mdev) { - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index e8baff4d6290..ed4a49c850c7 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -119,7 +119,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) * this should be enough for the actual needs. */ media_device_for_each_entity(entity, mdev) { - if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { + if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { decoder = entity; break; } diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index b90f2a52db96..e8fc5ec8fc35 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -698,7 +698,7 @@ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; - t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; + t->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; t->sd.entity.name = t->name;
ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 8429da66754a..2446b2d8fe66 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -197,7 +197,7 @@ static void v4l2_device_release(struct device *cd) if (v4l2_dev->mdev) { /* Remove interfaces and interface links */ media_devnode_remove(vdev->intf_devnode); - if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) + if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) media_device_unregister_entity(&vdev->entity); } #endif @@ -726,20 +726,20 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0;
- vdev->entity.type = MEDIA_ENT_T_UNKNOWN; + vdev->entity.function = MEDIA_ENT_T_UNKNOWN;
switch (type) { case VFL_TYPE_GRABBER: intf_type = MEDIA_INTF_T_V4L_VIDEO; - vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO; + vdev->entity.function = MEDIA_ENT_T_V4L2_VIDEO; break; case VFL_TYPE_VBI: intf_type = MEDIA_INTF_T_V4L_VBI; - vdev->entity.type = MEDIA_ENT_T_V4L2_VBI; + vdev->entity.function = MEDIA_ENT_T_V4L2_VBI; break; case VFL_TYPE_SDR: intf_type = MEDIA_INTF_T_V4L_SWRADIO; - vdev->entity.type = MEDIA_ENT_T_V4L2_SWRADIO; + vdev->entity.function = MEDIA_ENT_T_V4L2_SWRADIO; break; case VFL_TYPE_RADIO: intf_type = MEDIA_INTF_T_V4L_RADIO; @@ -757,7 +757,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return 0; }
- if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { vdev->entity.name = vdev->name;
/* Needed just for backward compatibility with legacy MC API */ @@ -784,7 +784,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return -ENOMEM; }
- if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { struct media_link *link;
link = media_create_intf_link(&vdev->entity, diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 34c489fed55e..cf7b3cb9a373 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -655,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init( if (ret < 0) return ERR_PTR(ret);
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
ret = v4l2_flash_init_controls(v4l2_flash, config); if (ret < 0) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b3bcc8253182..b440cb66669c 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -535,9 +535,9 @@ 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_V4L2_VIDEO, + WARN(pad->entity->function != MEDIA_ENT_T_V4L2_VIDEO, "Driver bug! Wrong media entity type 0x%08x, entity %s\n", - pad->entity->type, pad->entity->name); + pad->entity->function, pad->entity->name);
return -EINVAL; } @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; - sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; #endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 8bdc10dcc5e7..10f7d5f0eb66 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -152,7 +152,8 @@ struct media_entity_operations { * * @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_*) + * @function: Entity main function, as defined at uapi/media.h + * (MEDIA_ENT_F_*) * @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. @@ -179,7 +180,7 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; - u32 type; + u32 function; u32 revision; unsigned long flags; u32 group_id; @@ -277,7 +278,7 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) if (!entity) return false;
- switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_VIDEO: case MEDIA_ENT_T_V4L2_VBI: case MEDIA_ENT_T_V4L2_SWRADIO: @@ -292,7 +293,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) if (!entity) return false;
- switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: case MEDIA_ENT_T_V4L2_SUBDEV_LENS:
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Entities should have one or more functions. Calling it as a type proofed to not be correct, as an entity could eventually
s/proofed/proved/
have more than one type.
So, rename the field as function.
Please notice that this patch doesn't extend support for multiple function entities. Such change will happen when we have real case drivers using it.
No functional changes.
Change-Id: I30e521e988594ca132a1c42c58130732788313cc Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
Documentation/video4linux/v4l2-framework.txt | 4 ++-- drivers/media/dvb-core/dvbdev.c | 14 +++++++------- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 ++-- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 6 +++--- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- drivers/media/media-device.c | 6 +++--- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/usb/au0828/au0828-core.c | 2 +- drivers/media/usb/au0828/au0828-video.c | 8 ++++---- drivers/media/usb/cx231xx/cx231xx-cards.c | 2 +- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 14 +++++++------- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 6 +++--- include/media/media-entity.h | 9 +++++---- 28 files changed, 55 insertions(+), 54 deletions(-)
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 109cc3792534..2e0fc28fa12f 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -303,8 +303,8 @@ calling media_entity_init(): err = media_entity_init(&sd->entity, npads, pads);
The pads array must have been previously initialized. There is no need to -manually set the struct media_entity type and name fields, but the revision -field must be initialized if needed. +manually set the struct media_entity function and name fields, but the +revision field must be initialized if needed.
A reference to the entity will be automatically acquired/released when the subdev device node (if any) is opened/closed. diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index df2fe4cc2d47..e925909bc99e 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -229,7 +229,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, if (!entity->name) return ret;
entity->type = MEDIA_ENT_T_DVB_TSOUT;
entity->function = MEDIA_ENT_T_DVB_TSOUT;
pads->flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(entity, 1, pads);
@@ -302,18 +302,18 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
switch (type) { case DVB_DEVICE_FRONTEND:
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->function = MEDIA_ENT_T_DVB_DEMOD;
dvbdev->entity->type = MEDIA_ENT_T_DVB_DEMUX;
dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; for (i = 1; i < npads; i++) dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA:dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMUX;
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;dvbdev->entity->function = MEDIA_ENT_T_DVB_CA;
@@ -537,7 +537,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) return 0;
media_device_for_each_entity(entity, mdev) {
switch (entity->type) {
case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break;switch (entity->function) {
@@ -576,7 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) /* 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 (entity->function == MEDIA_ENT_T_DVB_TSOUT) { if (!strncmp(entity->name, DVR_TSOUT, strlen(DVR_TSOUT))) { ret = media_create_pad_link(demux,
@@ -621,7 +621,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) }
media_device_for_each_entity(entity, mdev) {
if (entity->type == MEDIA_ENT_T_DVB_TSOUT) {
if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { if (!strcmp(entity->name, DVR_TSOUT)) { link = media_create_intf_link(entity, intf,
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 55cd42a584a5..a6fbe78a70e3 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -775,7 +775,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads);
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 5f76997f6e07..2b8f72ac0f7d 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -516,7 +516,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret < 0) goto free_and_quit;
- flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
return 0;
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index 9d579a836f79..a49ef7d6df18 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -831,7 +831,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done;
- flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
mutex_init(&flash->power_lock);
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 270135d06b32..d48a3a4df96b 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5208,7 +5208,7 @@ static int cx25840_probe(struct i2c_client *client, state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads);
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 9bd9def0852c..7c1abdca39d0 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -368,7 +368,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out;
- flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
flash->subdev_led[led_no].entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
return rval;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index 4160e18af607..d609f2fa8e6c 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -285,7 +285,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out;
- flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
- flash->subdev_led.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; return rval;
err_out: diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index f718a1009e4c..206319b88d7a 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -978,7 +978,7 @@ static int m5mols_probe(struct i2c_client *client, ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
init_waitqueue_head(&info->irq_waitq); mutex_init(&info->lock);
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index a9761251b970..6cd407bcfddf 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -779,7 +779,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err;
info->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err;
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 6bce9832ab7b..c085dec69201 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1445,7 +1445,7 @@ static int ov2659_probe(struct i2c_client *client,
#if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls);
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 8a8eb593fc23..2862244a6488 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1500,7 +1500,7 @@ static int ov965x_probe(struct i2c_client *client, return ret;
ov965x->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret;
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index abae37321c0c..3f55168cce47 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads);
@@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE;
- oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
oif_sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads);
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index d207ddce31b6..45f6e6f2585a 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -961,7 +961,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
priv->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &priv->pad); if (ret) return ret;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 0513196bd48c..22dfeadf7672 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -408,7 +408,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd) {
- return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- return sd->entity.function == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
}
static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd) @@ -1904,7 +1904,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err;
@@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
if (!ret)
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 39a461f9d9bb..71162c02d6d7 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1577,7 +1577,7 @@ static int s5k6aa_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret;
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 938201789ebc..dd2626c8ae53 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2763,7 +2763,7 @@ static int smiapp_init(struct smiapp_sensor *sensor)
dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
- sensor->pixel_array->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sensor->pixel_array->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
/* final steps */ smiapp_read_frame_fmt(sensor);
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 97eb97d9b662..ccef9621d147 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -108,7 +108,7 @@ static long media_device_enum_entities(struct media_device *mdev, u_ent.id = media_entity_id(ent); if (ent->name) strlcpy(u_ent.name, ent->name, sizeof(u_ent.name));
- u_ent.type = ent->type;
- u_ent.type = ent->function; u_ent.revision = ent->revision; u_ent.flags = ent->flags; u_ent.group_id = ent->group_id;
@@ -614,8 +614,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->type == MEDIA_ENT_T_UNKNOWN)
- if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
dev_warn(mdev->dev, "Entity type for entity %s was not initialized!\n", entity->name);entity->function == MEDIA_ENT_T_UNKNOWN)
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 8e14841bf445..8bee7313a497 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -191,7 +191,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_V4L2_VIDEO)
if (entity->function != MEDIA_ENT_T_V4L2_VIDEO) continue;
dma = to_xvip_dma(media_entity_to_video_device(entity));
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 399c6712faf9..44a2ab3c85ab 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -263,7 +263,7 @@ static int au0828_create_media_graph(struct au0828_dev *dev) return 0;
media_device_for_each_entity(entity, mdev) {
switch (entity->type) {
case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break;switch (entity->function) {
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 806b8d320bae..5c01f37cd0b8 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1830,18 +1830,18 @@ static void au0828_analog_create_entities(struct au0828_dev *dev)
switch(AUVI_INPUT(i).type) { case AU0828_VMUX_COMPOSITE:
ent->type = MEDIA_ENT_T_CONN_COMPOSITE;
case AU0828_VMUX_SVIDEO:ent->function = MEDIA_ENT_T_CONN_COMPOSITE; break;
ent->type = MEDIA_ENT_T_CONN_SVIDEO;
case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB:ent->function = MEDIA_ENT_T_CONN_SVIDEO; break;
ent->type = MEDIA_ENT_T_CONN_RF;
default: /* AU0828_VMUX_DEBUG */ent->function = MEDIA_ENT_T_CONN_RF; break;
ent->type = MEDIA_ENT_T_CONN_TEST;
}ent->function = MEDIA_ENT_T_CONN_TEST; break;
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index c05aaef85491..b01d6bce3cf6 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1249,7 +1249,7 @@ static int cx231xx_create_media_graph(struct cx231xx *dev) return 0;
media_device_for_each_entity(entity, mdev) {
switch (entity->type) {
case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: tuner = entity; break;switch (entity->function) {
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index e8baff4d6290..ed4a49c850c7 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -119,7 +119,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) * this should be enough for the actual needs. */ media_device_for_each_entity(entity, mdev) {
if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) {
}if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { decoder = entity; break;
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index b90f2a52db96..e8fc5ec8fc35 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -698,7 +698,7 @@ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
- t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER;
t->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; t->sd.entity.name = t->name;
ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 8429da66754a..2446b2d8fe66 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -197,7 +197,7 @@ static void v4l2_device_release(struct device *cd) if (v4l2_dev->mdev) { /* Remove interfaces and interface links */ media_devnode_remove(vdev->intf_devnode);
if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN)
}if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) media_device_unregister_entity(&vdev->entity);
#endif @@ -726,20 +726,20 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0;
- vdev->entity.type = MEDIA_ENT_T_UNKNOWN;
vdev->entity.function = MEDIA_ENT_T_UNKNOWN;
switch (type) { case VFL_TYPE_GRABBER: intf_type = MEDIA_INTF_T_V4L_VIDEO;
vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
break; case VFL_TYPE_VBI: intf_type = MEDIA_INTF_T_V4L_VBI;vdev->entity.function = MEDIA_ENT_T_V4L2_VIDEO;
vdev->entity.type = MEDIA_ENT_T_V4L2_VBI;
break; case VFL_TYPE_SDR: intf_type = MEDIA_INTF_T_V4L_SWRADIO;vdev->entity.function = MEDIA_ENT_T_V4L2_VBI;
vdev->entity.type = MEDIA_ENT_T_V4L2_SWRADIO;
break; case VFL_TYPE_RADIO: intf_type = MEDIA_INTF_T_V4L_RADIO;vdev->entity.function = MEDIA_ENT_T_V4L2_SWRADIO;
@@ -757,7 +757,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return 0; }
- if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) {
if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { vdev->entity.name = vdev->name;
/* Needed just for backward compatibility with legacy MC API */
@@ -784,7 +784,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return -ENOMEM; }
- if (vdev->entity.type != MEDIA_ENT_T_UNKNOWN) {
if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { struct media_link *link;
link = media_create_intf_link(&vdev->entity,
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 34c489fed55e..cf7b3cb9a373 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -655,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init( if (ret < 0) return ERR_PTR(ret);
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
ret = v4l2_flash_init_controls(v4l2_flash, config); if (ret < 0)
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b3bcc8253182..b440cb66669c 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -535,9 +535,9 @@ 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_V4L2_VIDEO,
- WARN(pad->entity->function != MEDIA_ENT_T_V4L2_VIDEO, "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
pad->entity->type, pad->entity->name);
pad->entity->function, pad->entity->name);
return -EINVAL;
} @@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name;
- sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
#endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 8bdc10dcc5e7..10f7d5f0eb66 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -152,7 +152,8 @@ struct media_entity_operations {
- @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_*)
- @function: Entity main function, as defined at uapi/media.h
(MEDIA_ENT_F_*)
- @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.
@@ -179,7 +180,7 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name;
- u32 type;
- u32 function; u32 revision; unsigned long flags; u32 group_id;
@@ -277,7 +278,7 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) if (!entity) return false;
- switch (entity->type) {
- switch (entity->function) { case MEDIA_ENT_T_V4L2_VIDEO: case MEDIA_ENT_T_V4L2_VBI: case MEDIA_ENT_T_V4L2_SWRADIO:
@@ -292,7 +293,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) if (!entity) return false;
- switch (entity->type) {
- switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: case MEDIA_ENT_T_V4L2_SUBDEV_LENS:
Now that entities have a main function, expose it via MEDIA_IOC_G_TOPOLOGY ioctl.
Change-Id: I52c9968e3b8ad766f714cabc31a6b7505ba4801d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 1 + include/uapi/linux/media.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index ccef9621d147..32090030c342 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -263,6 +263,7 @@ static long __media_device_get_topology(struct media_device *mdev, /* Copy fields to userspace struct if not error */ memset(&uentity, 0, sizeof(uentity)); uentity.id = entity->graph_obj.id; + uentity.function = entity->function; strncpy(uentity.name, entity->name, sizeof(uentity.name));
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 69433405aec2..d232cc680c67 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -284,7 +284,8 @@ struct media_links_enum { struct media_v2_entity { __u32 id; char name[64]; /* FIXME: move to a property? (RFC says so) */ - __u16 reserved[14]; + __u32 function; /* Main function of the entity */ + __u16 reserved[12]; };
/* Should match the specific fields at media_intf_devnode */
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Now that entities have a main function, expose it via MEDIA_IOC_G_TOPOLOGY ioctl.
Change-Id: I52c9968e3b8ad766f714cabc31a6b7505ba4801d Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/media-device.c | 1 + include/uapi/linux/media.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index ccef9621d147..32090030c342 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -263,6 +263,7 @@ static long __media_device_get_topology(struct media_device *mdev, /* Copy fields to userspace struct if not error */ memset(&uentity, 0, sizeof(uentity)); uentity.id = entity->graph_obj.id;
strncpy(uentity.name, entity->name, sizeof(uentity.name));uentity.function = entity->function;
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 69433405aec2..d232cc680c67 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -284,7 +284,8 @@ struct media_links_enum { struct media_v2_entity { __u32 id; char name[64]; /* FIXME: move to a property? (RFC says so) */
- __u16 reserved[14];
- __u32 function; /* Main function of the entity */
- __u16 reserved[12];
};
/* Should match the specific fields at media_intf_devnode */
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits.
The changes at the .c files was generated by the following coccinelle script:
@@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO @@ @@ -MEDIA_ENT_T_V4L2_VBI +MEDIA_ENT_F_V4L2_VBI @@ @@ -MEDIA_ENT_T_V4L2_SWRADIO +MEDIA_ENT_F_V4L2_SWRADIO @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN +MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN @@ @@ -MEDIA_ENT_T_CONN_RF +MEDIA_ENT_F_CONN_RF @@ @@ -MEDIA_ENT_T_CONN_SVIDEO +MEDIA_ENT_F_CONN_SVIDEO @@ @@ -MEDIA_ENT_T_CONN_COMPOSITE +MEDIA_ENT_F_CONN_COMPOSITE @@ @@ -MEDIA_ENT_T_CONN_TEST +MEDIA_ENT_F_CONN_TEST @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_SENSOR +MEDIA_ENT_F_CAM_SENSOR @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_FLASH +MEDIA_ENT_F_FLASH @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_LENS +MEDIA_ENT_F_LENS @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_DECODER +MEDIA_ENT_F_ATV_DECODER @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_TUNER +MEDIA_ENT_F_TUNER @@ @@ -MEDIA_ENT_T_DVB_DEMOD +MEDIA_ENT_F_DTV_DEMOD @@ @@ -MEDIA_ENT_T_DVB_DEMUX +MEDIA_ENT_F_MPEG_TS_DEMUX @@ @@ -MEDIA_ENT_T_DVB_TSOUT +MEDIA_ENT_F_DTV_TSOUT @@ @@ -MEDIA_ENT_T_DVB_CA +MEDIA_ENT_F_DTV_CA @@ @@ -MEDIA_ENT_T_DVB_NET_DECAP +MEDIA_ENT_F_DTV_NET_DECAP
Change-Id: I1cffa67df764a5c76c31393311551ecc005f9956 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 20 ++-- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/adv7180.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 +- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 6 +- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- drivers/media/i2c/tvp514x.c | 2 +- drivers/media/i2c/tvp7002.c | 2 +- drivers/media/media-device.c | 4 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/usb/au0828/au0828-core.c | 4 +- drivers/media/usb/au0828/au0828-video.c | 8 +- drivers/media/usb/cx231xx/cx231xx-cards.c | 4 +- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 14 +-- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 4 +- include/media/media-entity.h | 14 ++- include/uapi/linux/media.h | 127 ++++++++++++------------- 31 files changed, 123 insertions(+), 126 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index e925909bc99e..8527fc40e6a0 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -229,7 +229,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, if (!entity->name) return ret;
- entity->function = MEDIA_ENT_T_DVB_TSOUT; + entity->function = MEDIA_ENT_F_IO; pads->flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(entity, 1, pads); @@ -302,18 +302,18 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
switch (type) { case DVB_DEVICE_FRONTEND: - dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMOD; + dvbdev->entity->function = MEDIA_ENT_F_DTV_DEMOD; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_DEMUX: - dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMUX; + dvbdev->entity->function = MEDIA_ENT_F_MPEG_TS_DEMUX; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; for (i = 1; i < npads; i++) dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA: - dvbdev->entity->function = MEDIA_ENT_T_DVB_CA; + dvbdev->entity->function = MEDIA_ENT_F_DTV_CA; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; @@ -538,16 +538,16 @@ int dvb_create_media_graph(struct dvb_adapter *adap)
media_device_for_each_entity(entity, mdev) { switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_TUNER: tuner = entity; break; - case MEDIA_ENT_T_DVB_DEMOD: + case MEDIA_ENT_F_DTV_DEMOD: demod = entity; break; - case MEDIA_ENT_T_DVB_DEMUX: + case MEDIA_ENT_F_MPEG_TS_DEMUX: demux = entity; break; - case MEDIA_ENT_T_DVB_CA: + case MEDIA_ENT_F_DTV_CA: ca = entity; break; } @@ -576,7 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) /* Create demux links for each ringbuffer/pad */ if (demux) { media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { + if (entity->function == MEDIA_ENT_F_IO) { if (!strncmp(entity->name, DVR_TSOUT, strlen(DVR_TSOUT))) { ret = media_create_pad_link(demux, @@ -621,7 +621,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) }
media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_T_DVB_TSOUT) { + if (entity->function == MEDIA_ENT_F_IO) { if (!strcmp(entity->name, DVR_TSOUT)) { link = media_create_intf_link(entity, intf, diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index a6fbe78a70e3..39fab1ab921c 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -775,7 +775,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 2b8f72ac0f7d..0ce7a8426d59 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -516,7 +516,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret < 0) goto free_and_quit;
- flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
return 0;
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index bab91a1e1525..af888f6c1de0 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1213,7 +1213,7 @@ static int adv7180_probe(struct i2c_client *client, goto err_unregister_vpp_client;
state->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.flags |= MEDIA_ENT_F_ATV_DECODER; ret = media_entity_init(&sd->entity, 1, &state->pad); if (ret) goto err_free_ctrl; diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index a49ef7d6df18..c5462fd9c0fb 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -831,7 +831,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done;
- flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
mutex_init(&flash->power_lock);
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index d48a3a4df96b..479b3efc3f3d 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5208,7 +5208,7 @@ static int cx25840_probe(struct i2c_client *client, state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads); diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 7c1abdca39d0..8c7b4a2d465e 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -368,7 +368,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led[led_no].entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH;
return rval;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index d609f2fa8e6c..71344c6596a3 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -285,7 +285,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out; - flash->subdev_led.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH; return rval;
err_out: diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 206319b88d7a..08dad1140a07 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -978,7 +978,7 @@ static int m5mols_probe(struct i2c_client *client, ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
init_waitqueue_head(&info->irq_waitq); mutex_init(&info->lock); diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 6cd407bcfddf..aff081324d76 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -779,7 +779,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err;
info->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index c085dec69201..e49254f4341d 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1445,7 +1445,7 @@ static int ov2659_probe(struct i2c_client *client,
#if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls); diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 2862244a6488..b133464f3b73 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1500,7 +1500,7 @@ static int ov965x_probe(struct i2c_client *client, return ret;
ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret; diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 3f55168cce47..456899fe9cb0 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads); @@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; - oif_sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + oif_sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads); diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 45f6e6f2585a..c5001d5ab4ca 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -961,7 +961,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
priv->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &priv->pad); if (ret) return ret; diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 22dfeadf7672..3a10e50b3620 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -408,7 +408,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd) { - return sd->entity.function == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + return sd->entity.function == MEDIA_ENT_F_CAM_SENSOR; }
static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd) @@ -1904,7 +1904,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err; @@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
if (!ret) diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 71162c02d6d7..95c1951bc9df 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1577,7 +1577,7 @@ static int s5k6aa_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret; diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index dd2626c8ae53..11c1c442e680 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2763,7 +2763,7 @@ static int smiapp_init(struct smiapp_sensor *sensor)
dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
- sensor->pixel_array->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; + sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
/* final steps */ smiapp_read_frame_fmt(sensor); diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 11801636d901..fad7fcb49e9c 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -1095,7 +1095,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) #if defined(CONFIG_MEDIA_CONTROLLER) decoder->pad.flags = MEDIA_PAD_FL_SOURCE; decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + decoder->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER;
ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad); if (ret < 0) { diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 3630f3e2a4c7..765781ae8613 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -1012,7 +1012,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) #if defined(CONFIG_MEDIA_CONTROLLER) device->pad.flags = MEDIA_PAD_FL_SOURCE; device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; + device->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER;
error = media_entity_init(&device->sd.entity, 1, &device->pad); if (error < 0) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 32090030c342..13987710e5bc 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -615,8 +615,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN || - entity->function == MEDIA_ENT_T_UNKNOWN) + if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || + entity->function == MEDIA_ENT_F_UNKNOWN) dev_warn(mdev->dev, "Entity type for entity %s was not initialized!\n", entity->name); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 8bee7313a497..bc244a0049bd 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -191,7 +191,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, while ((entity = media_entity_graph_walk_next(&graph))) { struct xvip_dma *dma;
- if (entity->function != MEDIA_ENT_T_V4L2_VIDEO) + if (entity->function != MEDIA_ENT_F_IO) continue;
dma = to_xvip_dma(media_entity_to_video_device(entity)); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 44a2ab3c85ab..1c12285428fe 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -264,10 +264,10 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
media_device_for_each_entity(entity, mdev) { switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_TUNER: tuner = entity; break; - case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + case MEDIA_ENT_F_ATV_DECODER: decoder = entity; break; } diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 5c01f37cd0b8..f041433f2334 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1830,18 +1830,18 @@ static void au0828_analog_create_entities(struct au0828_dev *dev)
switch(AUVI_INPUT(i).type) { case AU0828_VMUX_COMPOSITE: - ent->function = MEDIA_ENT_T_CONN_COMPOSITE; + ent->function = MEDIA_ENT_F_CONN_COMPOSITE; break; case AU0828_VMUX_SVIDEO: - ent->function = MEDIA_ENT_T_CONN_SVIDEO; + ent->function = MEDIA_ENT_F_CONN_SVIDEO; break; case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB: - ent->function = MEDIA_ENT_T_CONN_RF; + ent->function = MEDIA_ENT_F_CONN_RF; break; default: /* AU0828_VMUX_DEBUG */ - ent->function = MEDIA_ENT_T_CONN_TEST; + ent->function = MEDIA_ENT_F_CONN_TEST; break; }
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index b01d6bce3cf6..022b30099a89 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1250,10 +1250,10 @@ static int cx231xx_create_media_graph(struct cx231xx *dev)
media_device_for_each_entity(entity, mdev) { switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_TUNER: tuner = entity; break; - case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + case MEDIA_ENT_F_ATV_DECODER: decoder = entity; break; } diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index ed4a49c850c7..7e67b1096012 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -119,7 +119,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) * this should be enough for the actual needs. */ media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { + if (entity->function == MEDIA_ENT_F_ATV_DECODER) { decoder = entity; break; } diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index e8fc5ec8fc35..05fc4df61b85 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -698,7 +698,7 @@ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE; - t->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; + t->sd.entity.function = MEDIA_ENT_F_TUNER; t->sd.entity.name = t->name;
ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]); diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 2446b2d8fe66..430aa2330d07 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -197,7 +197,7 @@ static void v4l2_device_release(struct device *cd) if (v4l2_dev->mdev) { /* Remove interfaces and interface links */ media_devnode_remove(vdev->intf_devnode); - if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) + if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) media_device_unregister_entity(&vdev->entity); } #endif @@ -726,20 +726,20 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0;
- vdev->entity.function = MEDIA_ENT_T_UNKNOWN; + vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
switch (type) { case VFL_TYPE_GRABBER: intf_type = MEDIA_INTF_T_V4L_VIDEO; - vdev->entity.function = MEDIA_ENT_T_V4L2_VIDEO; + vdev->entity.function = MEDIA_ENT_F_IO; break; case VFL_TYPE_VBI: intf_type = MEDIA_INTF_T_V4L_VBI; - vdev->entity.function = MEDIA_ENT_T_V4L2_VBI; + vdev->entity.function = MEDIA_ENT_F_IO; break; case VFL_TYPE_SDR: intf_type = MEDIA_INTF_T_V4L_SWRADIO; - vdev->entity.function = MEDIA_ENT_T_V4L2_SWRADIO; + vdev->entity.function = MEDIA_ENT_F_IO; break; case VFL_TYPE_RADIO: intf_type = MEDIA_INTF_T_V4L_RADIO; @@ -757,7 +757,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return 0; }
- if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) { vdev->entity.name = vdev->name;
/* Needed just for backward compatibility with legacy MC API */ @@ -784,7 +784,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return -ENOMEM; }
- if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) { + if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) { struct media_link *link;
link = media_create_intf_link(&vdev->entity, diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index cf7b3cb9a373..5c686a24712b 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -655,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init( if (ret < 0) return ERR_PTR(ret);
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; + sd->entity.function = MEDIA_ENT_F_FLASH;
ret = v4l2_flash_init_controls(v4l2_flash, config); if (ret < 0) diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b440cb66669c..d70aedc75998 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -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->function != MEDIA_ENT_T_V4L2_VIDEO, + WARN(pad->entity->function != MEDIA_ENT_F_IO, "Driver bug! Wrong media entity type 0x%08x, entity %s\n", pad->entity->function, pad->entity->name);
@@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name; - sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN; + sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; #endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 10f7d5f0eb66..9cbb10079024 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -279,9 +279,7 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) return false;
switch (entity->function) { - case MEDIA_ENT_T_V4L2_VIDEO: - case MEDIA_ENT_T_V4L2_VBI: - case MEDIA_ENT_T_V4L2_SWRADIO: + case MEDIA_ENT_F_IO: return true; default: return false; @@ -294,11 +292,11 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) return false;
switch (entity->function) { - 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: + case MEDIA_ENT_F_CAM_SENSOR: + case MEDIA_ENT_F_FLASH: + case MEDIA_ENT_F_LENS: + case MEDIA_ENT_F_ATV_DECODER: + case MEDIA_ENT_F_TUNER: return true;
default: diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index d232cc680c67..90e90a6e62bf 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -46,87 +46,86 @@ struct media_device_info { * Initial value to be used when a new entity is created * Drivers should change it to something useful */ -#define MEDIA_ENT_T_UNKNOWN 0x00000000 +#define MEDIA_ENT_F_UNKNOWN 0x00000000
/* - * Base numbers for entity types + * Base number ranges for entity functions * - * 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. + * NOTE: those ranges and entity function number are spased just to + * make easier to maintain this file. Userspace should not rely on + * the ranges to identify a group of function types, as newer + * functions can be added with any name within the full u32 range. */ -#define MEDIA_ENT_T_DVB_BASE 0x00000000 -#define MEDIA_ENT_T_V4L2_BASE 0x00010000 -#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 -#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000 +#define MEDIA_ENT_F_BASE 0x00000000 +#define MEDIA_ENT_F_OLD_BASE 0x00010000 +#define MEDIA_ENT_F_OLD_SUBDEV_BASE 0x00020000
/* - * V4L2 entities - Those are used for DMA (mmap/DMABUF) and - * read()/write() data I/O associated with the V4L2 devnodes. + * DVB entities */ -#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, - * in the case of having some userspace application using the old - * symbols. - */ -#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) -#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) - -/* V4L2 Sub-device entities */ - - /* - * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, - * in order to preserve backward compatibility. - * Drivers should change to the proper subdev type before - * registering the entity. - */ -#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) - /* 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 + 1) -#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) -#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) -#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) -#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) - -/* Connectors */ -#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE) -#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 1) -#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 2) +#define MEDIA_ENT_F_DTV_DEMOD (MEDIA_ENT_F_BASE + 1) +#define MEDIA_ENT_F_MPEG_TS_DEMUX (MEDIA_ENT_F_BASE + 2) +#define MEDIA_ENT_F_DTV_CA (MEDIA_ENT_F_BASE + 3) +#define MEDIA_ENT_F_DTV_NET_DECAP (MEDIA_ENT_F_BASE + 4) + +/* + * Connectors + */ +#define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 21) +#define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 22) +#define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 23) /* For internal test signal generators and other debug connectors */ -#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 3) +#define MEDIA_ENT_F_CONN_TEST (MEDIA_ENT_F_BASE + 24) + +/* + * Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and + * MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility + * with the legacy v1 API.The number range is out of range by purpose: + * several previously reserved numbers got excluded from this range. + * + * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, + * in order to preserve backward compatibility. + * Drivers should change to the proper subdev type before + * registering the entity. + */ + +#define MEDIA_ENT_F_IO (MEDIA_ENT_F_OLD_BASE + 1) + +#define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1) +#define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) +#define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) +#define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) +#define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5) + +#define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE
#ifndef __KERNEL__ -/* Legacy symbols used to avoid userspace compilation breakages */ + +/* + * Legacy symbols used to avoid userspace compilation breakages + * + * Those symbols map the entity function into types and should be + * used only on legacy programs for legacy hardware. Don't rely + * on those for MEDIA_IOC_G_TOPOLOGY. + */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff
-#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 MEDIA_ENT_F_OLD_BASE +#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_F_IO #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 (MEDIA_ENT_T_DEVNODE + 4) + +#define MEDIA_ENT_T_UNKNOWN MEDIA_ENT_F_UNKNOWN +#define MEDIA_ENT_T_V4L2_VIDEO MEDIA_ENT_F_IO +#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR MEDIA_ENT_F_CAM_SENSOR +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH MEDIA_ENT_F_FLASH +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER #endif
/* Entity flags */
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits.
The changes at the .c files was generated by the following coccinelle script:
@@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO @@ @@ -MEDIA_ENT_T_V4L2_VBI +MEDIA_ENT_F_V4L2_VBI @@ @@ -MEDIA_ENT_T_V4L2_SWRADIO +MEDIA_ENT_F_V4L2_SWRADIO @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN +MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN @@ @@ -MEDIA_ENT_T_CONN_RF +MEDIA_ENT_F_CONN_RF @@ @@ -MEDIA_ENT_T_CONN_SVIDEO +MEDIA_ENT_F_CONN_SVIDEO @@ @@ -MEDIA_ENT_T_CONN_COMPOSITE +MEDIA_ENT_F_CONN_COMPOSITE @@ @@ -MEDIA_ENT_T_CONN_TEST +MEDIA_ENT_F_CONN_TEST @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_SENSOR +MEDIA_ENT_F_CAM_SENSOR @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_FLASH +MEDIA_ENT_F_FLASH @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_LENS +MEDIA_ENT_F_LENS @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_DECODER +MEDIA_ENT_F_ATV_DECODER @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_TUNER +MEDIA_ENT_F_TUNER @@ @@ -MEDIA_ENT_T_DVB_DEMOD +MEDIA_ENT_F_DTV_DEMOD @@ @@ -MEDIA_ENT_T_DVB_DEMUX +MEDIA_ENT_F_MPEG_TS_DEMUX @@ @@ -MEDIA_ENT_T_DVB_TSOUT +MEDIA_ENT_F_DTV_TSOUT @@ @@ -MEDIA_ENT_T_DVB_CA +MEDIA_ENT_F_DTV_CA @@ @@ -MEDIA_ENT_T_DVB_NET_DECAP +MEDIA_ENT_F_DTV_NET_DECAP
Change-Id: I1cffa67df764a5c76c31393311551ecc005f9956 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
drivers/media/dvb-core/dvbdev.c | 20 ++-- drivers/media/dvb-frontends/au8522_decoder.c | 2 +- drivers/media/i2c/adp1653.c | 2 +- drivers/media/i2c/adv7180.c | 2 +- drivers/media/i2c/as3645a.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/lm3560.c | 2 +- drivers/media/i2c/lm3646.c | 2 +- drivers/media/i2c/m5mols/m5mols_core.c | 2 +- drivers/media/i2c/noon010pc30.c | 2 +- drivers/media/i2c/ov2659.c | 2 +- drivers/media/i2c/ov9650.c | 2 +- drivers/media/i2c/s5c73m3/s5c73m3-core.c | 4 +- drivers/media/i2c/s5k4ecgx.c | 2 +- drivers/media/i2c/s5k5baf.c | 6 +- drivers/media/i2c/s5k6aa.c | 2 +- drivers/media/i2c/smiapp/smiapp-core.c | 2 +- drivers/media/i2c/tvp514x.c | 2 +- drivers/media/i2c/tvp7002.c | 2 +- drivers/media/media-device.c | 4 +- drivers/media/platform/xilinx/xilinx-dma.c | 2 +- drivers/media/usb/au0828/au0828-core.c | 4 +- drivers/media/usb/au0828/au0828-video.c | 8 +- drivers/media/usb/cx231xx/cx231xx-cards.c | 4 +- drivers/media/usb/cx231xx/cx231xx-video.c | 2 +- drivers/media/v4l2-core/tuner-core.c | 2 +- drivers/media/v4l2-core/v4l2-dev.c | 14 +-- drivers/media/v4l2-core/v4l2-flash-led-class.c | 2 +- drivers/media/v4l2-core/v4l2-subdev.c | 4 +- include/media/media-entity.h | 14 ++- include/uapi/linux/media.h | 127 ++++++++++++------------- 31 files changed, 123 insertions(+), 126 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index e925909bc99e..8527fc40e6a0 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -229,7 +229,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, if (!entity->name) return ret;
entity->function = MEDIA_ENT_T_DVB_TSOUT;
entity->function = MEDIA_ENT_F_IO;
pads->flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(entity, 1, pads);
@@ -302,18 +302,18 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
switch (type) { case DVB_DEVICE_FRONTEND:
dvbdev->entity->function = 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->function = MEDIA_ENT_F_DTV_DEMOD;
dvbdev->entity->function = MEDIA_ENT_T_DVB_DEMUX;
dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; for (i = 1; i < npads; i++) dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA:dvbdev->entity->function = MEDIA_ENT_F_MPEG_TS_DEMUX;
dvbdev->entity->function = MEDIA_ENT_T_DVB_CA;
dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break;dvbdev->entity->function = MEDIA_ENT_F_DTV_CA;
@@ -538,16 +538,16 @@ int dvb_create_media_graph(struct dvb_adapter *adap)
media_device_for_each_entity(entity, mdev) { switch (entity->function) {
case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
case MEDIA_ENT_F_TUNER: tuner = entity; break;
case MEDIA_ENT_T_DVB_DEMOD:
case MEDIA_ENT_F_DTV_DEMOD: demod = entity; break;
case MEDIA_ENT_T_DVB_DEMUX:
case MEDIA_ENT_F_MPEG_TS_DEMUX: demux = entity; break;
case MEDIA_ENT_T_DVB_CA:
}case MEDIA_ENT_F_DTV_CA: ca = entity; break;
@@ -576,7 +576,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) /* Create demux links for each ringbuffer/pad */ if (demux) { media_device_for_each_entity(entity, mdev) {
if (entity->function == MEDIA_ENT_T_DVB_TSOUT) {
if (entity->function == MEDIA_ENT_F_IO) { if (!strncmp(entity->name, DVR_TSOUT, strlen(DVR_TSOUT))) { ret = media_create_pad_link(demux,
@@ -621,7 +621,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) }
media_device_for_each_entity(entity, mdev) {
if (entity->function == MEDIA_ENT_T_DVB_TSOUT) {
if (entity->function == MEDIA_ENT_F_IO) { if (!strcmp(entity->name, DVR_TSOUT)) { link = media_create_intf_link(entity, intf,
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index a6fbe78a70e3..39fab1ab921c 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -775,7 +775,7 @@ static int au8522_probe(struct i2c_client *client, state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads);
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 2b8f72ac0f7d..0ce7a8426d59 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -516,7 +516,7 @@ static int adp1653_probe(struct i2c_client *client, if (ret < 0) goto free_and_quit;
- flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
return 0;
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index bab91a1e1525..af888f6c1de0 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -1213,7 +1213,7 @@ static int adv7180_probe(struct i2c_client *client, goto err_unregister_vpp_client;
state->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
- sd->entity.flags |= MEDIA_ENT_F_ATV_DECODER; ret = media_entity_init(&sd->entity, 1, &state->pad); if (ret) goto err_free_ctrl;
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c index a49ef7d6df18..c5462fd9c0fb 100644 --- a/drivers/media/i2c/as3645a.c +++ b/drivers/media/i2c/as3645a.c @@ -831,7 +831,7 @@ static int as3645a_probe(struct i2c_client *client, if (ret < 0) goto done;
- flash->subdev.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
mutex_init(&flash->power_lock);
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index d48a3a4df96b..479b3efc3f3d 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -5208,7 +5208,7 @@ static int cx25840_probe(struct i2c_client *client, state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), state->pads);
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 7c1abdca39d0..8c7b4a2d465e 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -368,7 +368,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash, rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL); if (rval < 0) goto err_out;
- flash->subdev_led[led_no].entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH;
return rval;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c index d609f2fa8e6c..71344c6596a3 100644 --- a/drivers/media/i2c/lm3646.c +++ b/drivers/media/i2c/lm3646.c @@ -285,7 +285,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash) rval = media_entity_init(&flash->subdev_led.entity, 0, NULL); if (rval < 0) goto err_out;
- flash->subdev_led.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
- flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH; return rval;
err_out: diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c index 206319b88d7a..08dad1140a07 100644 --- a/drivers/media/i2c/m5mols/m5mols_core.c +++ b/drivers/media/i2c/m5mols/m5mols_core.c @@ -978,7 +978,7 @@ static int m5mols_probe(struct i2c_client *client, ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) return ret;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
init_waitqueue_head(&info->irq_waitq); mutex_init(&info->lock);
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c index 6cd407bcfddf..aff081324d76 100644 --- a/drivers/media/i2c/noon010pc30.c +++ b/drivers/media/i2c/noon010pc30.c @@ -779,7 +779,7 @@ static int noon010_probe(struct i2c_client *client, goto np_err;
info->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &info->pad); if (ret < 0) goto np_err;
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index c085dec69201..e49254f4341d 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1445,7 +1445,7 @@ static int ov2659_probe(struct i2c_client *client,
#if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov2659->pad); if (ret < 0) { v4l2_ctrl_handler_free(&ov2659->ctrls);
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 2862244a6488..b133464f3b73 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -1500,7 +1500,7 @@ static int ov965x_probe(struct i2c_client *client, return ret;
ov965x->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &ov965x->pad); if (ret < 0) return ret;
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 3f55168cce47..456899fe9cb0 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1688,7 +1688,7 @@ static int s5c73m3_probe(struct i2c_client *client,
state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->sensor_pads);
@@ -1704,7 +1704,7 @@ static int s5c73m3_probe(struct i2c_client *client, state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE;
- oif_sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
oif_sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, state->oif_pads);
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index 45f6e6f2585a..c5001d5ab4ca 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -961,7 +961,7 @@ static int s5k4ecgx_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
priv->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &priv->pad); if (ret) return ret;
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 22dfeadf7672..3a10e50b3620 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -408,7 +408,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd) {
- return sd->entity.function == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- return sd->entity.function == MEDIA_ENT_F_CAM_SENSOR;
}
static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd) @@ -1904,7 +1904,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad); if (ret < 0) goto err;
@@ -1919,7 +1919,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
if (!ret)
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 71162c02d6d7..95c1951bc9df 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -1577,7 +1577,7 @@ static int s5k6aa_probe(struct i2c_client *client, sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
- sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad); if (ret) return ret;
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index dd2626c8ae53..11c1c442e680 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -2763,7 +2763,7 @@ static int smiapp_init(struct smiapp_sensor *sensor)
dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
- sensor->pixel_array->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
/* final steps */ smiapp_read_frame_fmt(sensor);
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index 11801636d901..fad7fcb49e9c 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -1095,7 +1095,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) #if defined(CONFIG_MEDIA_CONTROLLER) decoder->pad.flags = MEDIA_PAD_FL_SOURCE; decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
decoder->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER;
ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad); if (ret < 0) {
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c index 3630f3e2a4c7..765781ae8613 100644 --- a/drivers/media/i2c/tvp7002.c +++ b/drivers/media/i2c/tvp7002.c @@ -1012,7 +1012,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id) #if defined(CONFIG_MEDIA_CONTROLLER) device->pad.flags = MEDIA_PAD_FL_SOURCE; device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
device->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER;
error = media_entity_init(&device->sd.entity, 1, &device->pad); if (error < 0)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 32090030c342..13987710e5bc 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -615,8 +615,8 @@ int __must_check media_device_register_entity(struct media_device *mdev, { int i;
- if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN ||
entity->function == MEDIA_ENT_T_UNKNOWN)
- if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN ||
dev_warn(mdev->dev, "Entity type for entity %s was not initialized!\n", entity->name);entity->function == MEDIA_ENT_F_UNKNOWN)
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index 8bee7313a497..bc244a0049bd 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -191,7 +191,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe, while ((entity = media_entity_graph_walk_next(&graph))) { struct xvip_dma *dma;
if (entity->function != MEDIA_ENT_T_V4L2_VIDEO)
if (entity->function != MEDIA_ENT_F_IO) continue;
dma = to_xvip_dma(media_entity_to_video_device(entity));
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 44a2ab3c85ab..1c12285428fe 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -264,10 +264,10 @@ static int au0828_create_media_graph(struct au0828_dev *dev)
media_device_for_each_entity(entity, mdev) { switch (entity->function) {
case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
case MEDIA_ENT_F_TUNER: tuner = entity; break;
case MEDIA_ENT_T_V4L2_SUBDEV_DECODER:
}case MEDIA_ENT_F_ATV_DECODER: decoder = entity; break;
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 5c01f37cd0b8..f041433f2334 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1830,18 +1830,18 @@ static void au0828_analog_create_entities(struct au0828_dev *dev)
switch(AUVI_INPUT(i).type) { case AU0828_VMUX_COMPOSITE:
ent->function = MEDIA_ENT_T_CONN_COMPOSITE;
case AU0828_VMUX_SVIDEO:ent->function = MEDIA_ENT_F_CONN_COMPOSITE; break;
ent->function = MEDIA_ENT_T_CONN_SVIDEO;
case AU0828_VMUX_CABLE: case AU0828_VMUX_TELEVISION: case AU0828_VMUX_DVB:ent->function = MEDIA_ENT_F_CONN_SVIDEO; break;
ent->function = MEDIA_ENT_T_CONN_RF;
default: /* AU0828_VMUX_DEBUG */ent->function = MEDIA_ENT_F_CONN_RF; break;
ent->function = MEDIA_ENT_T_CONN_TEST;
}ent->function = MEDIA_ENT_F_CONN_TEST; break;
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index b01d6bce3cf6..022b30099a89 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1250,10 +1250,10 @@ static int cx231xx_create_media_graph(struct cx231xx *dev)
media_device_for_each_entity(entity, mdev) { switch (entity->function) {
case MEDIA_ENT_T_V4L2_SUBDEV_TUNER:
case MEDIA_ENT_F_TUNER: tuner = entity; break;
case MEDIA_ENT_T_V4L2_SUBDEV_DECODER:
}case MEDIA_ENT_F_ATV_DECODER: decoder = entity; break;
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index ed4a49c850c7..7e67b1096012 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -119,7 +119,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev) * this should be enough for the actual needs. */ media_device_for_each_entity(entity, mdev) {
if (entity->function == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) {
}if (entity->function == MEDIA_ENT_F_ATV_DECODER) { decoder = entity; break;
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index e8fc5ec8fc35..05fc4df61b85 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -698,7 +698,7 @@ register_client: #if defined(CONFIG_MEDIA_CONTROLLER) t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
- t->sd.entity.function = MEDIA_ENT_T_V4L2_SUBDEV_TUNER;
t->sd.entity.function = MEDIA_ENT_F_TUNER; t->sd.entity.name = t->name;
ret = media_entity_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 2446b2d8fe66..430aa2330d07 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -197,7 +197,7 @@ static void v4l2_device_release(struct device *cd) if (v4l2_dev->mdev) { /* Remove interfaces and interface links */ media_devnode_remove(vdev->intf_devnode);
if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN)
}if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) media_device_unregister_entity(&vdev->entity);
#endif @@ -726,20 +726,20 @@ static int video_register_media_controller(struct video_device *vdev, int type) if (!vdev->v4l2_dev->mdev) return 0;
- vdev->entity.function = MEDIA_ENT_T_UNKNOWN;
vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
switch (type) { case VFL_TYPE_GRABBER: intf_type = MEDIA_INTF_T_V4L_VIDEO;
vdev->entity.function = MEDIA_ENT_T_V4L2_VIDEO;
break; case VFL_TYPE_VBI: intf_type = MEDIA_INTF_T_V4L_VBI;vdev->entity.function = MEDIA_ENT_F_IO;
vdev->entity.function = MEDIA_ENT_T_V4L2_VBI;
break; case VFL_TYPE_SDR: intf_type = MEDIA_INTF_T_V4L_SWRADIO;vdev->entity.function = MEDIA_ENT_F_IO;
vdev->entity.function = MEDIA_ENT_T_V4L2_SWRADIO;
break; case VFL_TYPE_RADIO: intf_type = MEDIA_INTF_T_V4L_RADIO;vdev->entity.function = MEDIA_ENT_F_IO;
@@ -757,7 +757,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return 0; }
- if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) {
if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) { vdev->entity.name = vdev->name;
/* Needed just for backward compatibility with legacy MC API */
@@ -784,7 +784,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) return -ENOMEM; }
- if (vdev->entity.function != MEDIA_ENT_T_UNKNOWN) {
if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) { struct media_link *link;
link = media_create_intf_link(&vdev->entity,
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index cf7b3cb9a373..5c686a24712b 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -655,7 +655,7 @@ struct v4l2_flash *v4l2_flash_init( if (ret < 0) return ERR_PTR(ret);
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
sd->entity.function = MEDIA_ENT_F_FLASH;
ret = v4l2_flash_init_controls(v4l2_flash, config); if (ret < 0)
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index b440cb66669c..d70aedc75998 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -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->function != MEDIA_ENT_T_V4L2_VIDEO,
- WARN(pad->entity->function != MEDIA_ENT_F_IO, "Driver bug! Wrong media entity type 0x%08x, entity %s\n", pad->entity->function, pad->entity->name);
@@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) sd->host_priv = NULL; #if defined(CONFIG_MEDIA_CONTROLLER) sd->entity.name = sd->name;
- sd->entity.function = MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN;
- sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
#endif } EXPORT_SYMBOL(v4l2_subdev_init); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 10f7d5f0eb66..9cbb10079024 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -279,9 +279,7 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) return false;
switch (entity->function) {
- case MEDIA_ENT_T_V4L2_VIDEO:
- case MEDIA_ENT_T_V4L2_VBI:
- case MEDIA_ENT_T_V4L2_SWRADIO:
- case MEDIA_ENT_F_IO: return true; default: return false;
@@ -294,11 +292,11 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) return false;
switch (entity->function) {
- 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:
case MEDIA_ENT_F_CAM_SENSOR:
case MEDIA_ENT_F_FLASH:
case MEDIA_ENT_F_LENS:
case MEDIA_ENT_F_ATV_DECODER:
case MEDIA_ENT_F_TUNER: return true;
default:
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index d232cc680c67..90e90a6e62bf 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -46,87 +46,86 @@ struct media_device_info {
- Initial value to be used when a new entity is created
- Drivers should change it to something useful
*/ -#define MEDIA_ENT_T_UNKNOWN 0x00000000 +#define MEDIA_ENT_F_UNKNOWN 0x00000000
/*
- Base numbers for entity types
- Base number ranges for entity functions
- 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.
- NOTE: those ranges and entity function number are spased just to
- make easier to maintain this file. Userspace should not rely on
- the ranges to identify a group of function types, as newer
*/
- functions can be added with any name within the full u32 range.
-#define MEDIA_ENT_T_DVB_BASE 0x00000000 -#define MEDIA_ENT_T_V4L2_BASE 0x00010000 -#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 -#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000 +#define MEDIA_ENT_F_BASE 0x00000000 +#define MEDIA_ENT_F_OLD_BASE 0x00010000 +#define MEDIA_ENT_F_OLD_SUBDEV_BASE 0x00020000
/*
- V4L2 entities - Those are used for DMA (mmap/DMABUF) and
- read()/write() data I/O associated with the V4L2 devnodes.
*/
- DVB entities
-#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,
* in the case of having some userspace application using the old
* symbols.
*/
-#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) -#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6)
-/* V4L2 Sub-device entities */
- /*
* Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN,
* in order to preserve backward compatibility.
* Drivers should change to the proper subdev type before
* registering the entity.
*/
-#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)
- /* 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 + 1) -#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) -#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) -#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) -#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5)
-/* Connectors */ -#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE) -#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 1) -#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 2) +#define MEDIA_ENT_F_DTV_DEMOD (MEDIA_ENT_F_BASE + 1) +#define MEDIA_ENT_F_MPEG_TS_DEMUX (MEDIA_ENT_F_BASE + 2) +#define MEDIA_ENT_F_DTV_CA (MEDIA_ENT_F_BASE + 3) +#define MEDIA_ENT_F_DTV_NET_DECAP (MEDIA_ENT_F_BASE + 4)
+/*
- Connectors
- */
+#define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 21) +#define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 22) +#define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 23) /* For internal test signal generators and other debug connectors */ -#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 3) +#define MEDIA_ENT_F_CONN_TEST (MEDIA_ENT_F_BASE + 24)
+/*
- Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and
- MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility
- with the legacy v1 API.The number range is out of range by purpose:
- several previously reserved numbers got excluded from this range.
- Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN,
- in order to preserve backward compatibility.
- Drivers should change to the proper subdev type before
- registering the entity.
- */
+#define MEDIA_ENT_F_IO (MEDIA_ENT_F_OLD_BASE + 1)
+#define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1) +#define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) +#define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) +#define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) +#define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5)
+#define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE
#ifndef __KERNEL__ -/* Legacy symbols used to avoid userspace compilation breakages */
+/*
- Legacy symbols used to avoid userspace compilation breakages
- Those symbols map the entity function into types and should be
- used only on legacy programs for legacy hardware. Don't rely
- on those for MEDIA_IOC_G_TOPOLOGY.
- */
#define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff
-#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 MEDIA_ENT_F_OLD_BASE +#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_F_IO #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 (MEDIA_ENT_T_DEVNODE + 4)
+#define MEDIA_ENT_T_UNKNOWN MEDIA_ENT_F_UNKNOWN +#define MEDIA_ENT_T_V4L2_VIDEO MEDIA_ENT_F_IO +#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR MEDIA_ENT_F_CAM_SENSOR +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH MEDIA_ENT_F_FLASH +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER #endif
/* Entity flags */
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits.
The changes at the .c files was generated by the following coccinelle script:
@@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO
I have to agree with a comment from Shuah that F_IO is too generic. Why not keep it V4L2_VIDEO? Especially since it remains specific for video IO (VBI and SWRADIO still have their own 'function' define).
I might be missing something. I believe I suggested using F_IO, but I think Shuah is right and that that wasn't a good idea.
Shuah's comment from the 'Topics for workshop' thread:
- ENT_F_IO appears to be too generic, requiring additional steps to determine what kind of IO function it is really is. I propose preserving and allowing enough uniqueness to enable drivers to tag the functions when they create them. For example, if AUDIO functions are all tagged ENT_F_IO, bridge driver has to determine what kind of IO it really is. This requires finding the Interface entity associated with the function entity or comparing entity name strings. Instead, if a function can be tagged as Audio Capture when it gets created, these additional steps aren't necessary.
Regards,
Hans
@@ @@ -MEDIA_ENT_T_V4L2_VBI +MEDIA_ENT_F_V4L2_VBI @@ @@ -MEDIA_ENT_T_V4L2_SWRADIO +MEDIA_ENT_F_V4L2_SWRADIO
Em Mon, 19 Oct 2015 13:05:23 +0200 Hans Verkuil hverkuil@xs4all.nl escreveu:
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits.
The changes at the .c files was generated by the following coccinelle script:
@@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO
I have to agree with a comment from Shuah that F_IO is too generic.
Huh? You're the one that requested to change it to use a single function for all I/O, and determining the API type via the associated interface.
In the past, we had different IO functions for VIDEO, SWRADIO, VBI and DVB.
Why not keep it V4L2_VIDEO? Especially since it remains specific for video IO (VBI and SWRADIO still have their own 'function' define).
V4L2 is a Linux Kernel interface. We should not mess interfaces with entities.
That's said, the I/O "entities" is actually somewhat messy. This is not a hardware block, but a software block, as we use those IO functions to actually represent an interface that would be handling data input/output from/to userspace.
In the specific case of webcam SoC, such I/O interface matches a hardware block (DMA), but this is not true for ALSA (on non-mmap mode, with is currently a requirement for pulseaudio to work, afait) or for DVB with the current read() API.
On both ALSA and DVB, the I/O is implemented by FIFO buffers, in software.
So, it would likely be better to represent them as interfaces (MEDIA_INTF_V4L2_VIDEO), but this won't be backward compatible.
I'm not against using MEDIA_ENT_F_IO_function. That was actually my proposal, but you nacked it (on IRC, i guess).
Yet, I have to confess that the graphs look cleaner using just I/O instead of IO_type.
See the graphs I have so far at: https://mchehab.fedorapeople.org/mc-next-gen/
I might be missing something. I believe I suggested using F_IO, but I think Shuah is right and that that wasn't a good idea.
Shuah's comment from the 'Topics for workshop' thread:
- ENT_F_IO appears to be too generic, requiring additional steps to determine what kind of IO function it is really is. I propose preserving and allowing enough uniqueness to enable drivers to tag the functions when they create them. For example, if AUDIO functions are all tagged ENT_F_IO, bridge driver has to determine what kind of IO it really is. This requires finding the Interface entity associated with the function entity or comparing entity name strings. Instead, if a function can be tagged as Audio Capture when it gets created, these additional steps aren't necessary.
If we get an agreement before MC, we can certainly drop this topic from the agenda.
Regards, Mauro
Hi Mauro,
On Mon, Oct 19, 2015 at 10:54:11AM -0200, Mauro Carvalho Chehab wrote:
Em Mon, 19 Oct 2015 13:05:23 +0200 Hans Verkuil hverkuil@xs4all.nl escreveu:
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits.
The changes at the .c files was generated by the following coccinelle script:
@@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO
I have to agree with a comment from Shuah that F_IO is too generic.
Huh? You're the one that requested to change it to use a single function for all I/O, and determining the API type via the associated interface.
In the past, we had different IO functions for VIDEO, SWRADIO, VBI and DVB.
Why not keep it V4L2_VIDEO? Especially since it remains specific for video IO (VBI and SWRADIO still have their own 'function' define).
V4L2 is a Linux Kernel interface. We should not mess interfaces with entities.
That's said, the I/O "entities" is actually somewhat messy. This is not a hardware block, but a software block, as we use those IO functions to actually represent an interface that would be handling data input/output from/to userspace.
In the specific case of webcam SoC, such I/O interface matches a hardware block (DMA), but this is not true for ALSA (on non-mmap mode, with is currently a requirement for pulseaudio to work, afait) or for DVB with the current read() API.
On both ALSA and DVB, the I/O is implemented by FIFO buffers, in software.
So, it would likely be better to represent them as interfaces (MEDIA_INTF_V4L2_VIDEO), but this won't be backward compatible.
I'm not against using MEDIA_ENT_F_IO_function. That was actually my proposal, but you nacked it (on IRC, i guess).
Could there be an I/O entity which exposes multiple different interfaces?
I think referring to the entity (that corresponds to a piece of hardware, with some exceptions) by a (Linux) software interface looks hackish.
Em Fri, 30 Oct 2015 00:40:14 +0200 Sakari Ailus sakari.ailus@iki.fi escreveu:
Hi Mauro,
On Mon, Oct 19, 2015 at 10:54:11AM -0200, Mauro Carvalho Chehab wrote:
Em Mon, 19 Oct 2015 13:05:23 +0200 Hans Verkuil hverkuil@xs4all.nl escreveu:
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits.
The changes at the .c files was generated by the following coccinelle script:
@@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO
I have to agree with a comment from Shuah that F_IO is too generic.
Huh? You're the one that requested to change it to use a single function for all I/O, and determining the API type via the associated interface.
In the past, we had different IO functions for VIDEO, SWRADIO, VBI and DVB.
Why not keep it V4L2_VIDEO? Especially since it remains specific for video IO (VBI and SWRADIO still have their own 'function' define).
V4L2 is a Linux Kernel interface. We should not mess interfaces with entities.
That's said, the I/O "entities" is actually somewhat messy. This is not a hardware block, but a software block, as we use those IO functions to actually represent an interface that would be handling data input/output from/to userspace.
In the specific case of webcam SoC, such I/O interface matches a hardware block (DMA), but this is not true for ALSA (on non-mmap mode, with is currently a requirement for pulseaudio to work, afait) or for DVB with the current read() API.
On both ALSA and DVB, the I/O is implemented by FIFO buffers, in software.
So, it would likely be better to represent them as interfaces (MEDIA_INTF_V4L2_VIDEO), but this won't be backward compatible.
I'm not against using MEDIA_ENT_F_IO_function. That was actually my proposal, but you nacked it (on IRC, i guess).
Could there be an I/O entity which exposes multiple different interfaces?
Technically, yes. We used to have that with some devices that could/can export audio I/O either via /dev/video or via ALSA (pvrusb2 and ivtv drivers).
Not sure if, in such cases, we should export the two I/O endpoints as two separate entities or just one. I guess exporting it as two separate I/O endpoints make more sense, as the interface to control the I/O will be different, and it will very likely use different ringbuffers on the different interfaces.
I think referring to the entity (that corresponds to a piece of hardware, with some exceptions) by a (Linux) software interface looks hackish.
Well, technically speaking, the I/O graph elements are actually a Linux software interface.
Ok, on most cases, it could be associated with a DMA hardware block, but still the DMA engine is controlled via the Linux API - QBUF/DQBUF or via read()/write()/poll() syscalls.
Also, except for DMA engines, the I/O is actually done via some sort of ringbuffer. That is the case of V4L2 read()/write(), ALSA[1] and DVB.
We could, instead, map such graph elements as interfaces, but then we'll have troubles with old API support. Also, the I/O block.
[1] ALSA might use DMA, but, last time I checked, pulseaudio doesn't support mmap. So, AFAIK, the usual API is to receive a buffer via read() syscall.
Regards, Mauro
On 10/19/2015 01:05 PM, Hans Verkuil wrote:
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits.
The changes at the .c files was generated by the following coccinelle script:
@@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO
I have to agree with a comment from Shuah that F_IO is too generic. Why not keep it V4L2_VIDEO? Especially since it remains specific for video IO (VBI and SWRADIO still have their own 'function' define).
Never mind, see my comment at the end of this mail.
I might be missing something. I believe I suggested using F_IO, but I think Shuah is right and that that wasn't a good idea.
Shuah's comment from the 'Topics for workshop' thread:
- ENT_F_IO appears to be too generic, requiring additional steps to determine what kind of IO function it is really is. I propose preserving and allowing enough uniqueness to enable drivers to tag the functions when they create them. For example, if AUDIO functions are all tagged ENT_F_IO, bridge driver has to determine what kind of IO it really is. This requires finding the Interface entity associated with the function entity or comparing entity name strings. Instead, if a function can be tagged as Audio Capture when it gets created, these additional steps aren't necessary.
Regards,
Hans
@@ @@ -MEDIA_ENT_T_V4L2_VBI +MEDIA_ENT_F_V4L2_VBI @@ @@ -MEDIA_ENT_T_V4L2_SWRADIO +MEDIA_ENT_F_V4L2_SWRADIO
This text from the commit log of this patch is wrong if I understand it correctly: T_V4L2_VBI/SWRADIO are both replaced by ENT_F_IO and not by F_V4L2_VBI/SWRADIO, right?
So that log text confused the hell out of me :-)
That said, I think it is good to discuss this a bit more since we're all at the workshop anyway. The idea has always been that one entity can support multiple functions (even though we don't do that today). If we support more than one function, then we can use that to specify which type of IO the entity supports. Or we go back to the original idea of F_IO_VIDEO, F_IO_AUDIO, F_IO_VBI, F_IO_SWRADIO.
Yes, I know I wanted just F_IO, but I think Shuah has a point here.
Regards,
Hans
Due to the rename, the documentation became outdated.
Update it to reflect what's there at media.h.
Change-Id: I77267bfc0d984badccf63cf4e11dff242ae21137 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- .../DocBook/media/v4l/media-ioc-enum-entities.xml | 58 ++++++++++++---------- 1 file changed, 32 insertions(+), 26 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index bc101516e372..f9bfe8094d6d 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -179,54 +179,60 @@ <colspec colname="c2"/> <tbody valign="top"> <row> - <entry><constant>MEDIA_ENT_T_UNKNOWN</constant> and <constant>MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN</constant></entry> + <entry><constant>MEDIA_ENT_F_UNKNOWN</constant> and <constant>MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN</constant></entry> <entry>Unknown entity. That generally indicates that a driver didn't initialize properly the entity, with is a Kernel bug</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry> - <entry>V4L video streaming input or output entity</entry> + <entry><constant>MEDIA_ENT_F_IO</constant></entry> + <entry>Data streaming input and/or output entity.</entry> </row> - <entry><constant>MEDIA_ENT_T_V4L2_VBI</constant></entry> - <entry>V4L VBI streaming input or output entity</entry> + <row> + <entry><constant>MEDIA_ENT_F_DTV_DEMOD</constant></entry> + <entry>Digital TV demodulator entity.</entry> + </row> + <row> + <entry><constant>MEDIA_ENT_F_MPEG_TS_DEMUX</constant></entry> + <entry>MPEG Transport stream demux entity. Could be implemented on hardware or in Kernelspace by the Linux DVB subsystem.</entry> </row> - <entry><constant>MEDIA_ENT_T_V4L2_SWRADIO</constant></entry> - <entry>V4L Sofware Digital Radio (SDR) streaming input or output entity</entry> + <row> + <entry><constant>MEDIA_ENT_F_DTV_CA</constant></entry> + <entry>Digital TV Conditional Access module (CAM) entity</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry> - <entry>DVB demodulator entity</entry> + <entry><constant>MEDIA_ENT_F_DTV_NET_DECAP</constant></entry> + <entry>Digital TV network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry> - <entry>DVB demux entity. Could be implemented on hardware or in Kernelspace</entry> + <entry><constant>MEDIA_ENT_F_CONN_RF</constant></entry> + <entry>Connector for a Radio Frequency (RF) signal.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry> - <entry>DVB Transport Stream output entity</entry> + <entry><constant>MEDIA_ENT_F_CONN_SVIDEO</constant></entry> + <entry>Connector for a S-Video signal.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry> - <entry>DVB Conditional Access module (CAM) entity</entry> + <entry><constant>MEDIA_ENT_F_CONN_COMPOSITE</constant></entry> + <entry>Connector for a RGB composite signal.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry> - <entry>DVB network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry> + <entry><constant>MEDIA_ENT_F_CONN_TEST</constant></entry> + <entry>Connector for a test generator.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry> - <entry>Camera video sensor entity</entry> + <entry><constant>MEDIA_ENT_F_CAM_SENSOR</constant></entry> + <entry>Camera video sensor entity.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry> - <entry>Flash controller entity</entry> + <entry><constant>MEDIA_ENT_F_FLASH</constant></entry> + <entry>Flash controller entity.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry> - <entry>Lens controller entity</entry> + <entry><constant>MEDIA_ENT_F_LENS</constant></entry> + <entry>Lens controller entity.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_DECODER</constant></entry> + <entry><constant>MEDIA_ENT_F_ATV_DECODER</constant></entry> <entry>Analog video decoder, the basic function of the video decoder is to accept analogue video from a wide variety of sources such as broadcast, DVD players, cameras and video cassette recorders, in @@ -236,8 +242,8 @@ signals.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry> - <entry>Digital TV, analog TV, radio and/or software radio tuner</entry> + <entry><constant>MEDIA_ENT_F_TUNER</constant></entry> + <entry>Digital TV, analog TV, radio and/or software radio tuner.</entry> </row> </tbody> </tgroup>
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Due to the rename, the documentation became outdated.
Update it to reflect what's there at media.h.
Change-Id: I77267bfc0d984badccf63cf4e11dff242ae21137 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
Acked-by: Hans Verkuil hans.verkuil@cisco.com
.../DocBook/media/v4l/media-ioc-enum-entities.xml | 58 ++++++++++++---------- 1 file changed, 32 insertions(+), 26 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml index bc101516e372..f9bfe8094d6d 100644 --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml @@ -179,54 +179,60 @@ <colspec colname="c2"/>
<tbody valign="top"> <row> - <entry><constant>MEDIA_ENT_T_UNKNOWN</constant> and <constant>MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN</constant></entry> + <entry><constant>MEDIA_ENT_F_UNKNOWN</constant> and <constant>MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN</constant></entry> <entry>Unknown entity. That generally indicates that a driver didn't initialize properly the entity, with is a Kernel bug</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry> - <entry>V4L video streaming input or output entity</entry> + <entry><constant>MEDIA_ENT_F_IO</constant></entry> + <entry>Data streaming input and/or output entity.</entry> </row> - <entry><constant>MEDIA_ENT_T_V4L2_VBI</constant></entry> - <entry>V4L VBI streaming input or output entity</entry> + <row> + <entry><constant>MEDIA_ENT_F_DTV_DEMOD</constant></entry> + <entry>Digital TV demodulator entity.</entry> + </row> + <row> + <entry><constant>MEDIA_ENT_F_MPEG_TS_DEMUX</constant></entry> + <entry>MPEG Transport stream demux entity. Could be implemented on hardware or in Kernelspace by the Linux DVB subsystem.</entry> </row> - <entry><constant>MEDIA_ENT_T_V4L2_SWRADIO</constant></entry> - <entry>V4L Sofware Digital Radio (SDR) streaming input or output entity</entry> + <row> + <entry><constant>MEDIA_ENT_F_DTV_CA</constant></entry> + <entry>Digital TV Conditional Access module (CAM) entity</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_DEMOD</constant></entry> - <entry>DVB demodulator entity</entry> + <entry><constant>MEDIA_ENT_F_DTV_NET_DECAP</constant></entry> + <entry>Digital TV network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_DEMUX</constant></entry> - <entry>DVB demux entity. Could be implemented on hardware or in Kernelspace</entry> + <entry><constant>MEDIA_ENT_F_CONN_RF</constant></entry> + <entry>Connector for a Radio Frequency (RF) signal.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_TSOUT</constant></entry> - <entry>DVB Transport Stream output entity</entry> + <entry><constant>MEDIA_ENT_F_CONN_SVIDEO</constant></entry> + <entry>Connector for a S-Video signal.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_CA</constant></entry> - <entry>DVB Conditional Access module (CAM) entity</entry> + <entry><constant>MEDIA_ENT_F_CONN_COMPOSITE</constant></entry> + <entry>Connector for a RGB composite signal.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_DVB_DEMOD_NET_DECAP</constant></entry> - <entry>DVB network ULE/MLE desencapsulation entity. Could be implemented on hardware or in Kernelspace</entry> + <entry><constant>MEDIA_ENT_F_CONN_TEST</constant></entry> + <entry>Connector for a test generator.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry> - <entry>Camera video sensor entity</entry> + <entry><constant>MEDIA_ENT_F_CAM_SENSOR</constant></entry> + <entry>Camera video sensor entity.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry> - <entry>Flash controller entity</entry> + <entry><constant>MEDIA_ENT_F_FLASH</constant></entry> + <entry>Flash controller entity.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry> - <entry>Lens controller entity</entry> + <entry><constant>MEDIA_ENT_F_LENS</constant></entry> + <entry>Lens controller entity.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_DECODER</constant></entry> + <entry><constant>MEDIA_ENT_F_ATV_DECODER</constant></entry> <entry>Analog video decoder, the basic function of the video decoder is to accept analogue video from a wide variety of sources such as broadcast, DVD players, cameras and video cassette recorders, in @@ -236,8 +242,8 @@ signals.</entry> </row> <row> - <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_TUNER</constant></entry> - <entry>Digital TV, analog TV, radio and/or software radio tuner</entry> + <entry><constant>MEDIA_ENT_F_TUNER</constant></entry> + <entry>Digital TV, analog TV, radio and/or software radio tuner.</entry> </row> </tbody> </tgroup>
Cleanup the code a little bit by moving the routine that creates links between DVR and demux to the I/O entitis into a separate function.
While here, fix the code to use strncmp() instead of strcmp().
Change-Id: I52c36d65d972027413107410cf3ba53511ec17ac Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 50 +++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 8527fc40e6a0..ea76fe54e0e4 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -522,6 +522,28 @@ EXPORT_SYMBOL(dvb_unregister_device);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB + +static int dvb_create_io_intf_links(struct dvb_adapter *adap, + struct media_interface *intf, + char *name) +{ + struct media_device *mdev = adap->mdev; + struct media_entity *entity; + struct media_link *link; + + media_device_for_each_entity(entity, mdev) { + if (entity->function == MEDIA_ENT_F_IO) { + if (strncmp(entity->name, name, strlen(name))) + continue; + link = media_create_intf_link(entity, intf, + MEDIA_LNK_FL_ENABLED); + if (!link) + return -ENOMEM; + } + } + return 0; +} + int dvb_create_media_graph(struct dvb_adapter *adap) { struct media_device *mdev = adap->mdev; @@ -619,25 +641,15 @@ int dvb_create_media_graph(struct dvb_adapter *adap) if (!link) return -ENOMEM; } - - media_device_for_each_entity(entity, mdev) { - if (entity->function == MEDIA_ENT_F_IO) { - if (!strcmp(entity->name, DVR_TSOUT)) { - link = media_create_intf_link(entity, - intf, - MEDIA_LNK_FL_ENABLED); - if (!link) - return -ENOMEM; - } - if (!strcmp(entity->name, DEMUX_TSOUT)) { - link = media_create_intf_link(entity, - intf, - MEDIA_LNK_FL_ENABLED); - if (!link) - return -ENOMEM; - } - break; - } + if (intf->type == MEDIA_INTF_T_DVB_DVR) { + ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT); + if (ret) + return ret; + } + if (intf->type == MEDIA_INTF_T_DVB_DEMUX) { + ret = dvb_create_io_intf_links(adap, intf, DEMUX_TSOUT); + if (ret) + return ret; } } return 0;
Indirect links are those whose the interface indirectly controls other functions.
There are two interfaces that have indirect controls at the DVB side: - the network interface, with also controls the demux; - the DVR interface with also controls the demux.
One could argue that the frontend control to the tuner is indirect. Well, that's debateable. There's no way to create subdef interfaces for tuner and demod, as those devices are tightly coupled. So, it was decided that just one interface is the best to control both entities, and there's no plan (or easy way) to decouple both. So, the DVB frontend interface should link to both entities.
Change-Id: I6d0da412b7aabaf358c782a93080949d29688806 Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index ea76fe54e0e4..e9f24c1479dd 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -619,7 +619,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap) } }
- /* Create indirect interface links for FE->tuner, DVR->demux and CA->ca */ + /* Create interface links for FE->tuner, DVR->demux and CA->ca */ media_device_for_each_intf(intf, mdev) { if (intf->type == MEDIA_INTF_T_DVB_CA && ca) { link = media_create_intf_link(ca, intf, @@ -634,13 +634,19 @@ int dvb_create_media_graph(struct dvb_adapter *adap) if (!link) return -ENOMEM; } - +#if 0 + /* + * Indirect link - let's not create yet, as we don't know how + * to handle indirect links, nor if this will + * actually be needed. + */ if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) { link = media_create_intf_link(demux, intf, MEDIA_LNK_FL_ENABLED); if (!link) return -ENOMEM; } +#endif if (intf->type == MEDIA_INTF_T_DVB_DVR) { ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT); if (ret)
We should not be creating device nodes at IRQ contexts. So, the only flags we'll be using will be GFP_KERNEL. Let's remove the gfp_flags, in order to make the interface simpler.
If we ever need it, it would be easy to revert those changes.
While here, remove an extra blank line.
Change-Id: I43c5e15d3d87e0ef9b7916216f197d9b0ea1b18c Suggested-by: Sakari Ailus sakari.ailus@iki.fi Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/dvb-core/dvbdev.c | 3 +-- drivers/media/media-entity.c | 5 ++--- drivers/media/v4l2-core/v4l2-dev.c | 3 +-- include/media/media-entity.h | 4 +--- 4 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index e9f24c1479dd..60828a9537a0 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -379,8 +379,7 @@ static int dvb_register_media_device(struct dvb_device *dvbdev,
dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev, intf_type, 0, - DVB_MAJOR, minor, - GFP_KERNEL); + DVB_MAJOR, minor);
if (!dvbdev->intf_devnode) return -ENOMEM; diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 4868b8269204..f28265864b76 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -887,12 +887,11 @@ static void media_interface_init(struct media_device *mdev,
struct media_intf_devnode *media_devnode_create(struct media_device *mdev, u32 type, u32 flags, - u32 major, u32 minor, - gfp_t gfp_flags) + u32 major, u32 minor) { struct media_intf_devnode *devnode;
- devnode = kzalloc(sizeof(*devnode), gfp_flags); + devnode = kzalloc(sizeof(*devnode), GFP_KERNEL); if (!devnode) return NULL;
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 430aa2330d07..982255d2063f 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -777,8 +777,7 @@ static int video_register_media_controller(struct video_device *vdev, int type) vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev, intf_type, 0, VIDEO_MAJOR, - vdev->minor, - GFP_KERNEL); + vdev->minor); if (!vdev->intf_devnode) { media_device_unregister_entity(&vdev->entity); return -ENOMEM; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 9cbb10079024..44ab153c37fc 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -71,7 +71,6 @@ struct media_gobj { struct list_head list; };
- struct media_pipeline { };
@@ -373,8 +372,7 @@ void media_entity_pipeline_stop(struct media_entity *entity); struct media_intf_devnode * __must_check media_devnode_create(struct media_device *mdev, u32 type, u32 flags, - u32 major, u32 minor, - gfp_t gfp_flags); + u32 major, u32 minor); void media_devnode_remove(struct media_intf_devnode *devnode); struct media_link * __must_check media_create_intf_link(struct media_entity *entity,
The entity->num_pads are defined as u16. So, better to use an unsigned int, as this prevents additional warnings when W=2 (or W=1 on some architectures).
The "i" counter at __media_device_get_topology() is also a monotonic counter that should never be below zero. So, make it unsigned too.
Change-Id: Ie926b51b1781bdaee1fd0a2303151caa22a874e6 Suggested-by: Sakari Ailus sakari.ailus@iki.fi Acked-by: Hans Verkuil hans.verkuil@cisco.com Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-device.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index 13987710e5bc..1312e93ebd6e 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -243,7 +243,8 @@ static long __media_device_get_topology(struct media_device *mdev, struct media_v2_interface uintf; struct media_v2_pad upad; struct media_v2_link ulink; - int ret = 0, i; + int ret = 0; + unsigned int i;
topo->topology_version = mdev->topology_version;
@@ -613,7 +614,7 @@ EXPORT_SYMBOL_GPL(media_device_unregister); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity) { - int i; + unsigned int i;
if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || entity->function == MEDIA_ENT_F_UNKNOWN) @@ -650,9 +651,9 @@ EXPORT_SYMBOL_GPL(media_device_register_entity); */ void media_device_unregister_entity(struct media_entity *entity) { - int i; struct media_device *mdev = entity->graph_obj.mdev; struct media_link *link, *tmp; + unsigned int i;
if (mdev == NULL) return;
From: Javier Martinez Canillas javier@osg.samsung.com
If an entity is registered with a media device before is initialized with media_device_register_entity(), the number of pads won't be set so media_device_register_entity() won't create pad objects and add it to the media device pads list.
Do this at entity initialization time if the entity was registered before so the graph is complete and correct regardless of the order in which the entities are initialized and registered.
Suggested-by: Mauro Carvalho Chehab mchehab@osg.samsung.com Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/media/media-entity.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index f28265864b76..2c984fb7d497 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -238,6 +238,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads) { + struct media_device *mdev = entity->graph_obj.mdev; unsigned int i;
entity->group_id = 0; @@ -246,11 +247,20 @@ media_entity_init(struct media_entity *entity, u16 num_pads, entity->num_pads = num_pads; entity->pads = pads;
+ if (mdev) + spin_lock(&mdev->lock); + for (i = 0; i < num_pads; i++) { pads[i].entity = entity; pads[i].index = i; + if (mdev) + media_gobj_init(mdev, MEDIA_GRAPH_PAD, + &entity->pads[i].graph_obj); }
+ if (mdev) + spin_unlock(&mdev->lock); + return 0; } EXPORT_SYMBOL_GPL(media_entity_init);
From: Javier Martinez Canillas javier@osg.samsung.com
The media_entity_cleanup() function only cleans up the entity links list but this operation is already made in media_device_unregister_entity().
In most cases this should be harmless (besides having duplicated code) since the links list would be empty so the iteration would not happen but the links list is initialized in media_device_register_entity() so if a driver fails to register an entity with a media device and clean up the entity in the error path, a NULL deference pointer error will happen.
So don't try to empty the links list in media_entity_cleanup() since is either done already or haven't been initialized yet.
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com --- drivers/media/media-entity.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 2c984fb7d497..eaeda2589ce5 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -268,13 +268,6 @@ EXPORT_SYMBOL_GPL(media_entity_init); void media_entity_cleanup(struct media_entity *entity) { - 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);
Hello Javier,
Thank you for the patch.
On Monday 12 October 2015 13:44:11 Mauro Carvalho Chehab wrote:
From: Javier Martinez Canillas javier@osg.samsung.com
The media_entity_cleanup() function only cleans up the entity links list but this operation is already made in media_device_unregister_entity().
In most cases this should be harmless (besides having duplicated code) since the links list would be empty so the iteration would not happen but the links list is initialized in media_device_register_entity() so if a driver fails to register an entity with a media device and clean up the entity in the error path, a NULL deference pointer error will happen.
So don't try to empty the links list in media_entity_cleanup() since is either done already or haven't been initialized yet.
Does this mean that it's an invalid usage of the API to create links before registering entities ? If so it should be clearly documented somewhere, such as in the kerneldoc of the media_create_pad_link() function.
And yes, that means that all exported API functions need kerneldoc. Sorry for being a killjoy :-)
On a related note, we need to solve the userspace API race caused by registering the MC devnode before all entities and links are created an registered. It's not a new issue so I won't call for fixing it as part of this patch series, but we'll need to fix that with the dynamic graph update implementation at the latest. It will likely require reworking the initialization and registration sequences.
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com
drivers/media/media-entity.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 2c984fb7d497..eaeda2589ce5 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -268,13 +268,6 @@ EXPORT_SYMBOL_GPL(media_entity_init); void media_entity_cleanup(struct media_entity *entity) {
- 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);
As media_entity_cleanup is now empty I'd turn it into a static inline. We need to keep the function in case cleanup ends up being needed later, but there's no reason not to optimize the call away for now.
Hello Laurent,
On 11/23/2015 10:41 AM, Laurent Pinchart wrote:
Hello Javier,
Thank you for the patch.
Thanks a lot for your review and feedback.
On Monday 12 October 2015 13:44:11 Mauro Carvalho Chehab wrote:
From: Javier Martinez Canillas javier@osg.samsung.com
The media_entity_cleanup() function only cleans up the entity links list but this operation is already made in media_device_unregister_entity().
In most cases this should be harmless (besides having duplicated code) since the links list would be empty so the iteration would not happen but the links list is initialized in media_device_register_entity() so if a driver fails to register an entity with a media device and clean up the entity in the error path, a NULL deference pointer error will happen.
So don't try to empty the links list in media_entity_cleanup() since is either done already or haven't been initialized yet.
Does this mean that it's an invalid usage of the API to create links before
Yes, with the changes in the MC core, the links can't be created before registering the entities with the media device (because the mdev object IDs are needed when creating the links).
registering entities ? If so it should be clearly documented somewhere, such as in the kerneldoc of the media_create_pad_link() function.
And yes, that means that all exported API functions need kerneldoc. Sorry for being a killjoy :-)
Agreed, it was decided to leave the documentation out for now until the MC next gen changes settle to avoid having to re-work it on every spin.
But for sure this new behavior will be clearly documented once the changes are agreed upon.
On a related note, we need to solve the userspace API race caused by registering the MC devnode before all entities and links are created an registered. It's not a new issue so I won't call for fixing it as part of this patch series, but we'll need to fix that with the dynamic graph update implementation at the latest. It will likely require reworking the initialization and registration sequences.
Yes, that user-space API race has been already fixed by the series:
[PATCH v4 0/2] [media] Fix race between graph enumeration and entities registration
https://lkml.org/lkml/2015/9/15/371
but as you said, is not part of the series and can be picked as a follow up (although I added this series as a dependency just to avoid merge conflicts).
Signed-off-by: Javier Martinez Canillas javier@osg.samsung.com
drivers/media/media-entity.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 2c984fb7d497..eaeda2589ce5 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -268,13 +268,6 @@ EXPORT_SYMBOL_GPL(media_entity_init); void media_entity_cleanup(struct media_entity *entity) {
- 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);
As media_entity_cleanup is now empty I'd turn it into a static inline. We need to keep the function in case cleanup ends up being needed later, but there's no reason not to optimize the call away for now.
Agreed.
Best regards,
Fix those sparse warnings: drivers/media/media-entity.c:238:17: warning: Variable length array is used. drivers/media/media-entity.c:239:17: warning: Variable length array is used.
That allows sparse and other code check tools to verify if the function is using more stack than allowed.
It also solves a bad Kernel pratice of using var length arrays at the stack.
Change-Id: Ida2fd36bfd4031b1b6a40db37353db2af0b9bc7a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com --- drivers/media/media-entity.c | 4 ++-- include/media/media-entity.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index eaeda2589ce5..064020ddac94 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -424,8 +424,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, media_entity_graph_walk_start(&graph, entity);
while ((entity = media_entity_graph_walk_next(&graph))) { - DECLARE_BITMAP(active, entity->num_pads); - DECLARE_BITMAP(has_no_links, entity->num_pads); + DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); + DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
entity->stream_count++; WARN_ON(entity->pipe && entity->pipe != pipe); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 44ab153c37fc..a02b1bd3e45e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -306,6 +306,13 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64
+/* + * The number of pads can't be bigger than the number of entities, + * as the worse-case scenario is to have one entity linked up to + * MEDIA_ENTITY_ENUM_MAX_ID - 1 entities. + */ +#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1) + struct media_entity_graph { struct { struct media_entity *entity;
The active and has_no_links arrays will overrun in media_entity_pipeline_start() if there's an entity which has more than MEDIA_ENTITY_MAX_PAD pads. Ensure in media_entity_init() that there are fewer pads than that.
Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com --- Hi Mauro,
Could you apply this before "media-entity.c: get rid of var length arrays", please?
Regards, Sakari
drivers/media/media-entity.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 064020d..66b8db0 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -241,6 +241,9 @@ media_entity_init(struct media_entity *entity, u16 num_pads, struct media_device *mdev = entity->graph_obj.mdev; unsigned int i;
+ if (num_pads >= MEDIA_ENTITY_MAX_PADS) + return -E2BIG; + entity->group_id = 0; entity->num_links = 0; entity->num_backlinks = 0;
On 10/12/2015 06:44 PM, Mauro Carvalho Chehab wrote:
Fix those sparse warnings: drivers/media/media-entity.c:238:17: warning: Variable length array is used. drivers/media/media-entity.c:239:17: warning: Variable length array is used.
That allows sparse and other code check tools to verify if the function is using more stack than allowed.
It also solves a bad Kernel pratice of using var length arrays at the stack.
Change-Id: Ida2fd36bfd4031b1b6a40db37353db2af0b9bc7a Signed-off-by: Mauro Carvalho Chehab mchehab@osg.samsung.com
drivers/media/media-entity.c | 4 ++-- include/media/media-entity.h | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index eaeda2589ce5..064020ddac94 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -424,8 +424,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, media_entity_graph_walk_start(&graph, entity);
while ((entity = media_entity_graph_walk_next(&graph))) {
DECLARE_BITMAP(active, entity->num_pads);
DECLARE_BITMAP(has_no_links, entity->num_pads);
DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS);
DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
entity->stream_count++; WARN_ON(entity->pipe && entity->pipe != pipe);
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 44ab153c37fc..a02b1bd3e45e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -306,6 +306,13 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64
+/*
- The number of pads can't be bigger than the number of entities,
- as the worse-case scenario is to have one entity linked up to
- MEDIA_ENTITY_ENUM_MAX_ID - 1 entities.
- */
I don't think this is true at all. The number of pads an entity has is defined by the number of inputs and outputs of the hardware and is independent of how many of those inputs/outputs are actually hooked up.
This patch basically imposes a limitation (that is quite reasonable at the moment) on the number of pads to prevent a sparse warning.
But we will see devices with more than 64 pads in the future, so this is a band-aid.
Regards,
Hans
+#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1)
struct media_entity_graph { struct { struct media_entity *entity;
Hi Mauro,
Mauro Carvalho Chehab wrote:
As requested by Sakari and Hans, I'm re-sending the entire 83 patch series that were already sent to the media ML.
NOTE: as agreed on IRC, after getting the ack for those patches, eventually adding newer fixups where needed, we should add this to the media-controller topic branch of our devel tree.
You can add
Tested-by: Sakari Ailus sakari.ailus@linux.intel.com
on the following patches (see comments below as well):
Patches 1--17, 22, 23, 25--29, 31, 33, 37 (with the agreed fixes), 38 (for omap3isp), 44--46, 48, 50--57, 59, 60, 64, 65, 69, 72--76 and 79--82.
Patch 24 depends on "v4l: subdev: Register the entity before calling subdev's registered op" which I sent as a follow-up to that patch.
Patch 36 depends on "media: Correctly determine whether an entity is a sub-device", or the latter could be merged to the former.
Patch 83 should be merged with "media: Check for active and has_no_links overrun".
How about the reserved fields in patch 49 ("uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl")? I think those do require some fixing before merging.