aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-13 14:46:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-13 14:46:37 -0500
commit77a76b04d2be1c45b8fd746b7ef754525029340c (patch)
treeef5db67c07d538a43d160847acefe80f3c049dba /drivers
parent50ae833e471fe1a1a906a0342bdaa690e69fcc19 (diff)
parentbe0270ec89e6b9b49de7e533dd1f3a89ad34d205 (diff)
Merge tag 'media/v4.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull second batch of media updates from Mauro Carvalho Chehab: "This is the second part of the media patches. It contains the media controller next generation patches, with is the result of one year of discussions and development. It also contains patches to enable media controller support at the DVB subsystem. The goal is to improve the media controller to allow proper support for other types of Video4Linux devices (radio and TV ones) and to extend the media controller functionality to allow it to be used by other subsystems like DVB, ALSA and IIO. In order to use the new functionality, a new ioctl is needed (MEDIA_IOC_G_TOPOLOGY). As we're still discussing how to pack the struct fields of this ioctl in order to avoid compat32 issues, I decided to add a patch at the end of this series commenting out the new ioctl, in order to postpone the addition of the new ioctl to the next Kernel version (4.6). With that, no userspace visible changes should happen at the media controller API, as the existing ioctls are untouched. Yet, it helps DVB, ALSA and IIO developers to develop and test the patches adding media controller support there, as the core will contain all required internal changes to allow adding support for devices that belong to those subsystems" * tag 'media/v4.5-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (177 commits) [media] Postpone the addition of MEDIA_IOC_G_TOPOLOGY [media] mxl111sf: Add a tuner entity [media] dvbdev: create links on devices with multiple frontends [media] media-entitiy: add a function to create multiple links [media] dvb-usb-v2: postpone removal of media_device [media] dvbdev: Add RF connector if needed [media] dvbdev: remove two dead functions if !CONFIG_MEDIA_CONTROLLER_DVB [media] call media_device_init() before registering the V4L2 device [media] uapi/media.h: Use u32 for the number of graph objects [media] media-entity: don't sleep at media_device_register_entity() [media] media-entity: increase max number of PADs [media] media-entity.h: document the remaining functions [media] media-device.h: use just one u32 counter for object ID [media] media-entity.h fix documentation for several parameters [media] DocBook: document media_entity_graph_walk_cleanup() [media] move documentation to the header files [media] media: Move MEDIA_ENTITY_MAX_PADS from media-entity.h to media-entity.c [media] media: Remove pre-allocated entity enumeration bitmap [media] staging: v4l: davinci_vpbe: Use the new media graph walk interface [media] staging: v4l: omap4iss: Use the new media graph walk interface ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/Kconfig1
-rw-r--r--drivers/media/common/siano/smsdvb-main.c7
-rw-r--r--drivers/media/dvb-core/dmxdev.c4
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c2
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c11
-rw-r--r--drivers/media/dvb-core/dvb_net.c2
-rw-r--r--drivers/media/dvb-core/dvbdev.c488
-rw-r--r--drivers/media/dvb-core/dvbdev.h58
-rw-r--r--drivers/media/dvb-frontends/au8522_decoder.c17
-rw-r--r--drivers/media/dvb-frontends/au8522_priv.h12
-rw-r--r--drivers/media/firewire/firedtv-ci.c2
-rw-r--r--drivers/media/i2c/ad9389b.c2
-rw-r--r--drivers/media/i2c/adp1653.c4
-rw-r--r--drivers/media/i2c/adv7180.c4
-rw-r--r--drivers/media/i2c/adv7511.c2
-rw-r--r--drivers/media/i2c/adv7604.c4
-rw-r--r--drivers/media/i2c/adv7842.c2
-rw-r--r--drivers/media/i2c/as3645a.c4
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.c6
-rw-r--r--drivers/media/i2c/lm3560.c4
-rw-r--r--drivers/media/i2c/lm3646.c4
-rw-r--r--drivers/media/i2c/m5mols/m5mols_core.c4
-rw-r--r--drivers/media/i2c/mt9m032.c2
-rw-r--r--drivers/media/i2c/mt9p031.c2
-rw-r--r--drivers/media/i2c/mt9t001.c2
-rw-r--r--drivers/media/i2c/mt9v032.c2
-rw-r--r--drivers/media/i2c/noon010pc30.c4
-rw-r--r--drivers/media/i2c/ov2659.c4
-rw-r--r--drivers/media/i2c/ov9650.c4
-rw-r--r--drivers/media/i2c/s5c73m3/s5c73m3-core.c16
-rw-r--r--drivers/media/i2c/s5k4ecgx.c4
-rw-r--r--drivers/media/i2c/s5k5baf.c12
-rw-r--r--drivers/media/i2c/s5k6a3.c2
-rw-r--r--drivers/media/i2c/s5k6aa.c4
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c32
-rw-r--r--drivers/media/i2c/tc358743.c2
-rw-r--r--drivers/media/i2c/tvp514x.c4
-rw-r--r--drivers/media/i2c/tvp7002.c4
-rw-r--r--drivers/media/media-device.c441
-rw-r--r--drivers/media/media-devnode.c24
-rw-r--r--drivers/media/media-entity.c724
-rw-r--r--drivers/media/pci/bt8xx/dst_ca.c3
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-core.c2
-rw-r--r--drivers/media/pci/ngene/ngene-core.c2
-rw-r--r--drivers/media/pci/ttpci/av7110.c2
-rw-r--r--drivers/media/pci/ttpci/av7110_av.c4
-rw-r--r--drivers/media/pci/ttpci/av7110_ca.c2
-rw-r--r--drivers/media/platform/exynos4-is/common.c3
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c11
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp-video.c11
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.c4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c24
-rw-r--r--drivers/media/platform/exynos4-is/fimc-m2m.c2
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.c73
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.h9
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c4
-rw-r--r--drivers/media/platform/omap3isp/isp.c306
-rw-r--r--drivers/media/platform/omap3isp/isp.h9
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c31
-rw-r--r--drivers/media/platform/omap3isp/ispccp2.c27
-rw-r--r--drivers/media/platform/omap3isp/ispcsi2.c21
-rw-r--r--drivers/media/platform/omap3isp/isppreview.c30
-rw-r--r--drivers/media/platform/omap3isp/ispresizer.c28
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c2
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c49
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.h5
-rw-r--r--drivers/media/platform/s3c-camif/camif-capture.c8
-rw-r--r--drivers/media/platform/s3c-camif/camif-core.c21
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c50
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c4
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c29
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h5
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c64
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c40
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.c21
-rw-r--r--drivers/media/platform/xilinx/xilinx-tpg.c2
-rw-r--r--drivers/media/platform/xilinx/xilinx-vipp.c16
-rw-r--r--drivers/media/usb/au0828/au0828-cards.c4
-rw-r--r--drivers/media/usb/au0828/au0828-core.c171
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c12
-rw-r--r--drivers/media/usb/au0828/au0828-video.c126
-rw-r--r--drivers/media/usb/au0828/au0828.h10
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c81
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c6
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c14
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c42
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c20
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.h5
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-dvb.c43
-rw-r--r--drivers/media/usb/siano/smsusb.c5
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c11
-rw-r--r--drivers/media/usb/uvc/uvc_entity.c38
-rw-r--r--drivers/media/v4l2-core/tuner-core.c10
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c111
-rw-r--r--drivers/media/v4l2-core/v4l2-device.c39
-rw-r--r--drivers/media/v4l2-core/v4l2-flash-led-class.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c8
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe.c11
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipeif.c17
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_isif.c17
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_resizer.c39
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c10
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.c58
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_video.h1
-rw-r--r--drivers/staging/media/omap4iss/iss.c199
-rw-r--r--drivers/staging/media/omap4iss/iss.h8
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.c48
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.h1
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipe.c11
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipeif.c44
-rw-r--r--drivers/staging/media/omap4iss/iss_ipipeif.h1
-rw-r--r--drivers/staging/media/omap4iss/iss_resizer.c42
-rw-r--r--drivers/staging/media/omap4iss/iss_resizer.h1
-rw-r--r--drivers/staging/media/omap4iss/iss_video.c61
-rw-r--r--drivers/staging/media/omap4iss/iss_video.h5
115 files changed, 2979 insertions, 1212 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 9264ea73b3be..a8518fb3bca7 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -97,7 +97,6 @@ config MEDIA_CONTROLLER
97config MEDIA_CONTROLLER_DVB 97config MEDIA_CONTROLLER_DVB
98 bool "Enable Media controller for DVB (EXPERIMENTAL)" 98 bool "Enable Media controller for DVB (EXPERIMENTAL)"
99 depends on MEDIA_CONTROLLER 99 depends on MEDIA_CONTROLLER
100 depends on BROKEN
101 ---help--- 100 ---help---
102 Enable the media controller API support for DVB. 101 Enable the media controller API support for DVB.
103 102
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
index f4305ae800f4..d31f468830cf 100644
--- a/drivers/media/common/siano/smsdvb-main.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -617,6 +617,7 @@ static void smsdvb_media_device_unregister(struct smsdvb_client_t *client)
617 if (!coredev->media_dev) 617 if (!coredev->media_dev)
618 return; 618 return;
619 media_device_unregister(coredev->media_dev); 619 media_device_unregister(coredev->media_dev);
620 media_device_cleanup(coredev->media_dev);
620 kfree(coredev->media_dev); 621 kfree(coredev->media_dev);
621 coredev->media_dev = NULL; 622 coredev->media_dev = NULL;
622#endif 623#endif
@@ -1183,7 +1184,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
1183 if (smsdvb_debugfs_create(client) < 0) 1184 if (smsdvb_debugfs_create(client) < 0)
1184 pr_info("failed to create debugfs node\n"); 1185 pr_info("failed to create debugfs node\n");
1185 1186
1186 dvb_create_media_graph(&client->adapter); 1187 rc = dvb_create_media_graph(&client->adapter, true);
1188 if (rc < 0) {
1189 pr_err("dvb_create_media_graph failed %d\n", rc);
1190 goto client_error;
1191 }
1187 1192
1188 pr_info("DVB interface registered.\n"); 1193 pr_info("DVB interface registered.\n");
1189 return 0; 1194 return 0;
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index ea9abde902e9..a168cbe1c998 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -1244,9 +1244,9 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
1244 } 1244 }
1245 1245
1246 dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, 1246 dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
1247 DVB_DEVICE_DEMUX); 1247 DVB_DEVICE_DEMUX, dmxdev->filternum);
1248 dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, 1248 dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
1249 dmxdev, DVB_DEVICE_DVR); 1249 dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
1250 1250
1251 dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); 1251 dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
1252 1252
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,
1695 pubca->private = ca; 1695 pubca->private = ca;
1696 1696
1697 /* register the DVB device */ 1697 /* register the DVB device */
1698 ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA); 1698 ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA, 0);
1699 if (ret) 1699 if (ret)
1700 goto free_slot_info; 1700 goto free_slot_info;
1701 1701
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index b64f33776b74..40080645341e 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)
622 struct media_device *mdev = adapter->mdev; 622 struct media_device *mdev = adapter->mdev;
623 struct media_entity *entity, *source; 623 struct media_entity *entity, *source;
624 struct media_link *link, *found_link = NULL; 624 struct media_link *link, *found_link = NULL;
625 int i, ret, n_links = 0, active_links = 0; 625 int ret, n_links = 0, active_links = 0;
626 626
627 fepriv->pipe_start_entity = NULL; 627 fepriv->pipe_start_entity = NULL;
628 628
@@ -632,8 +632,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)
632 entity = fepriv->dvbdev->entity; 632 entity = fepriv->dvbdev->entity;
633 fepriv->pipe_start_entity = entity; 633 fepriv->pipe_start_entity = entity;
634 634
635 for (i = 0; i < entity->num_links; i++) { 635 list_for_each_entry(link, &entity->links, list) {
636 link = &entity->links[i];
637 if (link->sink->entity == entity) { 636 if (link->sink->entity == entity) {
638 found_link = link; 637 found_link = link;
639 n_links++; 638 n_links++;
@@ -659,13 +658,11 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)
659 658
660 source = found_link->source->entity; 659 source = found_link->source->entity;
661 fepriv->pipe_start_entity = source; 660 fepriv->pipe_start_entity = source;
662 for (i = 0; i < source->num_links; i++) { 661 list_for_each_entry(link, &source->links, list) {
663 struct media_entity *sink; 662 struct media_entity *sink;
664 int flags = 0; 663 int flags = 0;
665 664
666 link = &source->links[i];
667 sink = link->sink->entity; 665 sink = link->sink->entity;
668
669 if (sink == entity) 666 if (sink == entity)
670 flags = MEDIA_LNK_FL_ENABLED; 667 flags = MEDIA_LNK_FL_ENABLED;
671 668
@@ -2762,7 +2759,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
2762 fe->dvb->num, fe->id, fe->ops.info.name); 2759 fe->dvb->num, fe->id, fe->ops.info.name);
2763 2760
2764 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, 2761 dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
2765 fe, DVB_DEVICE_FRONTEND); 2762 fe, DVB_DEVICE_FRONTEND, 0);
2766 2763
2767 /* 2764 /*
2768 * Initialize the cache to the proper values according with the 2765 * 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 ce4332e80a91..ce6a711b42d4 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -1502,6 +1502,6 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
1502 dvbnet->state[i] = 0; 1502 dvbnet->state[i] = 0;
1503 1503
1504 return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net, 1504 return dvb_register_device(adap, &dvbnet->dvbdev, &dvbdev_net,
1505 dvbnet, DVB_DEVICE_NET); 1505 dvbnet, DVB_DEVICE_NET, 0);
1506} 1506}
1507EXPORT_SYMBOL(dvb_net_init); 1507EXPORT_SYMBOL(dvb_net_init);
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 13bb57f0457f..560450a0b32a 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -34,6 +34,9 @@
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include "dvbdev.h" 35#include "dvbdev.h"
36 36
37/* Due to enum tuner_pad_index */
38#include <media/tuner.h>
39
37static DEFINE_MUTEX(dvbdev_mutex); 40static DEFINE_MUTEX(dvbdev_mutex);
38static int dvbdev_debug; 41static int dvbdev_debug;
39 42
@@ -180,102 +183,255 @@ skip:
180 return -ENFILE; 183 return -ENFILE;
181} 184}
182 185
183static void dvb_register_media_device(struct dvb_device *dvbdev, 186static void dvb_media_device_free(struct dvb_device *dvbdev)
184 int type, int minor)
185{ 187{
186#if defined(CONFIG_MEDIA_CONTROLLER_DVB) 188#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
187 int ret = 0, npads; 189 if (dvbdev->entity) {
190 media_device_unregister_entity(dvbdev->entity);
191 kfree(dvbdev->entity);
192 kfree(dvbdev->pads);
193 dvbdev->entity = NULL;
194 dvbdev->pads = NULL;
195 }
188 196
189 if (!dvbdev->adapter->mdev) 197 if (dvbdev->tsout_entity) {
190 return; 198 int i;
191 199
192 dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL); 200 for (i = 0; i < dvbdev->tsout_num_entities; i++) {
193 if (!dvbdev->entity) 201 media_device_unregister_entity(&dvbdev->tsout_entity[i]);
194 return; 202 kfree(dvbdev->tsout_entity[i].name);
203 }
204 kfree(dvbdev->tsout_entity);
205 kfree(dvbdev->tsout_pads);
206 dvbdev->tsout_entity = NULL;
207 dvbdev->tsout_pads = NULL;
195 208
196 dvbdev->entity->info.dev.major = DVB_MAJOR; 209 dvbdev->tsout_num_entities = 0;
197 dvbdev->entity->info.dev.minor = minor; 210 }
198 dvbdev->entity->name = dvbdev->name; 211
212 if (dvbdev->intf_devnode) {
213 media_devnode_remove(dvbdev->intf_devnode);
214 dvbdev->intf_devnode = NULL;
215 }
216
217 if (dvbdev->adapter->conn) {
218 media_device_unregister_entity(dvbdev->adapter->conn);
219 dvbdev->adapter->conn = NULL;
220 kfree(dvbdev->adapter->conn_pads);
221 dvbdev->adapter->conn_pads = NULL;
222 }
223#endif
224}
225
226#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
227static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
228 const char *name, int npads)
229{
230 int i, ret = 0;
231
232 dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
233 GFP_KERNEL);
234 if (!dvbdev->tsout_pads)
235 return -ENOMEM;
236
237 dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity),
238 GFP_KERNEL);
239 if (!dvbdev->tsout_entity)
240 return -ENOMEM;
241
242 dvbdev->tsout_num_entities = npads;
243
244 for (i = 0; i < npads; i++) {
245 struct media_pad *pads = &dvbdev->tsout_pads[i];
246 struct media_entity *entity = &dvbdev->tsout_entity[i];
247
248 entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
249 if (!entity->name)
250 return -ENOMEM;
251
252 entity->function = MEDIA_ENT_F_IO_DTV;
253 pads->flags = MEDIA_PAD_FL_SINK;
254
255 ret = media_entity_pads_init(entity, 1, pads);
256 if (ret < 0)
257 return ret;
258
259 ret = media_device_register_entity(dvbdev->adapter->mdev,
260 entity);
261 if (ret < 0)
262 return ret;
263 }
264 return 0;
265}
266
267#define DEMUX_TSOUT "demux-tsout"
268#define DVR_TSOUT "dvr-tsout"
269
270static int dvb_create_media_entity(struct dvb_device *dvbdev,
271 int type, int demux_sink_pads)
272{
273 int i, ret, npads;
199 274
200 switch (type) { 275 switch (type) {
201 case DVB_DEVICE_CA:
202 case DVB_DEVICE_DEMUX:
203 case DVB_DEVICE_FRONTEND: 276 case DVB_DEVICE_FRONTEND:
204 npads = 2; 277 npads = 2;
205 break; 278 break;
206 case DVB_DEVICE_NET: 279 case DVB_DEVICE_DVR:
207 npads = 0; 280 ret = dvb_create_tsout_entity(dvbdev, DVR_TSOUT,
281 demux_sink_pads);
282 return ret;
283 case DVB_DEVICE_DEMUX:
284 npads = 1 + demux_sink_pads;
285 ret = dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT,
286 demux_sink_pads);
287 if (ret < 0)
288 return ret;
289 break;
290 case DVB_DEVICE_CA:
291 npads = 2;
208 break; 292 break;
293 case DVB_DEVICE_NET:
294 /*
295 * We should be creating entities for the MPE/ULE
296 * decapsulation hardware (or software implementation).
297 *
298 * However, the number of for the MPE/ULE decaps may not be
299 * fixed. As we don't have yet dynamic support for PADs at
300 * the Media Controller, let's not create the decap
301 * entities yet.
302 */
303 return 0;
209 default: 304 default:
210 npads = 1; 305 return 0;
211 } 306 }
212 307
308 dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL);
309 if (!dvbdev->entity)
310 return -ENOMEM;
311
312 dvbdev->entity->name = dvbdev->name;
313
213 if (npads) { 314 if (npads) {
214 dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), 315 dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
215 GFP_KERNEL); 316 GFP_KERNEL);
216 if (!dvbdev->pads) { 317 if (!dvbdev->pads)
217 kfree(dvbdev->entity); 318 return -ENOMEM;
218 return;
219 }
220 } 319 }
221 320
222 switch (type) { 321 switch (type) {
223 case DVB_DEVICE_FRONTEND: 322 case DVB_DEVICE_FRONTEND:
224 dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_FE; 323 dvbdev->entity->function = MEDIA_ENT_F_DTV_DEMOD;
225 dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; 324 dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
226 dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; 325 dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
227 break; 326 break;
228 case DVB_DEVICE_DEMUX: 327 case DVB_DEVICE_DEMUX:
229 dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DEMUX; 328 dvbdev->entity->function = MEDIA_ENT_F_TS_DEMUX;
230 dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
231 dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
232 break;
233 case DVB_DEVICE_DVR:
234 dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_DVR;
235 dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; 329 dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
330 for (i = 1; i < npads; i++)
331 dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE;
236 break; 332 break;
237 case DVB_DEVICE_CA: 333 case DVB_DEVICE_CA:
238 dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_CA; 334 dvbdev->entity->function = MEDIA_ENT_F_DTV_CA;
239 dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; 335 dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK;
240 dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; 336 dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE;
241 break; 337 break;
242 case DVB_DEVICE_NET:
243 dvbdev->entity->type = MEDIA_ENT_T_DEVNODE_DVB_NET;
244 break;
245 default: 338 default:
339 /* Should never happen, as the first switch prevents it */
246 kfree(dvbdev->entity); 340 kfree(dvbdev->entity);
341 kfree(dvbdev->pads);
247 dvbdev->entity = NULL; 342 dvbdev->entity = NULL;
248 return; 343 dvbdev->pads = NULL;
344 return 0;
249 } 345 }
250 346
251 if (npads) 347 if (npads) {
252 ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0); 348 ret = media_entity_pads_init(dvbdev->entity, npads, dvbdev->pads);
253 if (!ret) 349 if (ret)
254 ret = media_device_register_entity(dvbdev->adapter->mdev, 350 return ret;
255 dvbdev->entity);
256 if (ret < 0) {
257 printk(KERN_ERR
258 "%s: media_device_register_entity failed for %s\n",
259 __func__, dvbdev->entity->name);
260 kfree(dvbdev->pads);
261 kfree(dvbdev->entity);
262 dvbdev->entity = NULL;
263 return;
264 } 351 }
352 ret = media_device_register_entity(dvbdev->adapter->mdev,
353 dvbdev->entity);
354 if (ret)
355 return (ret);
265 356
266 printk(KERN_DEBUG "%s: media device '%s' registered.\n", 357 printk(KERN_DEBUG "%s: media entity '%s' registered.\n",
267 __func__, dvbdev->entity->name); 358 __func__, dvbdev->entity->name);
359
360 return 0;
361}
362#endif
363
364static int dvb_register_media_device(struct dvb_device *dvbdev,
365 int type, int minor,
366 unsigned demux_sink_pads)
367{
368#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
369 struct media_link *link;
370 u32 intf_type;
371 int ret;
372
373 if (!dvbdev->adapter->mdev)
374 return 0;
375
376 ret = dvb_create_media_entity(dvbdev, type, demux_sink_pads);
377 if (ret)
378 return ret;
379
380 switch (type) {
381 case DVB_DEVICE_FRONTEND:
382 intf_type = MEDIA_INTF_T_DVB_FE;
383 break;
384 case DVB_DEVICE_DEMUX:
385 intf_type = MEDIA_INTF_T_DVB_DEMUX;
386 break;
387 case DVB_DEVICE_DVR:
388 intf_type = MEDIA_INTF_T_DVB_DVR;
389 break;
390 case DVB_DEVICE_CA:
391 intf_type = MEDIA_INTF_T_DVB_CA;
392 break;
393 case DVB_DEVICE_NET:
394 intf_type = MEDIA_INTF_T_DVB_NET;
395 break;
396 default:
397 return 0;
398 }
399
400 dvbdev->intf_devnode = media_devnode_create(dvbdev->adapter->mdev,
401 intf_type, 0,
402 DVB_MAJOR, minor);
403
404 if (!dvbdev->intf_devnode)
405 return -ENOMEM;
406
407 /*
408 * Create the "obvious" link, e. g. the ones that represent
409 * a direct association between an interface and an entity.
410 * Other links should be created elsewhere, like:
411 * DVB FE intf -> tuner
412 * DVB demux intf -> dvr
413 */
414
415 if (!dvbdev->entity)
416 return 0;
417
418 link = media_create_intf_link(dvbdev->entity, &dvbdev->intf_devnode->intf,
419 MEDIA_LNK_FL_ENABLED);
420 if (!link)
421 return -ENOMEM;
268#endif 422#endif
423 return 0;
269} 424}
270 425
271int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, 426int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
272 const struct dvb_device *template, void *priv, int type) 427 const struct dvb_device *template, void *priv, int type,
428 int demux_sink_pads)
273{ 429{
274 struct dvb_device *dvbdev; 430 struct dvb_device *dvbdev;
275 struct file_operations *dvbdevfops; 431 struct file_operations *dvbdevfops;
276 struct device *clsdev; 432 struct device *clsdev;
277 int minor; 433 int minor;
278 int id; 434 int id, ret;
279 435
280 mutex_lock(&dvbdev_register_lock); 436 mutex_lock(&dvbdev_register_lock);
281 437
@@ -286,7 +442,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
286 return -ENFILE; 442 return -ENFILE;
287 } 443 }
288 444
289 *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); 445 *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
290 446
291 if (!dvbdev){ 447 if (!dvbdev){
292 mutex_unlock(&dvbdev_register_lock); 448 mutex_unlock(&dvbdev_register_lock);
@@ -335,6 +491,20 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
335 dvb_minors[minor] = dvbdev; 491 dvb_minors[minor] = dvbdev;
336 up_write(&minor_rwsem); 492 up_write(&minor_rwsem);
337 493
494 ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
495 if (ret) {
496 printk(KERN_ERR
497 "%s: dvb_register_media_device failed to create the mediagraph\n",
498 __func__);
499
500 dvb_media_device_free(dvbdev);
501 kfree(dvbdevfops);
502 kfree(dvbdev);
503 up_write(&minor_rwsem);
504 mutex_unlock(&dvbdev_register_lock);
505 return ret;
506 }
507
338 mutex_unlock(&dvbdev_register_lock); 508 mutex_unlock(&dvbdev_register_lock);
339 509
340 clsdev = device_create(dvb_class, adap->device, 510 clsdev = device_create(dvb_class, adap->device,
@@ -348,8 +518,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
348 dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", 518 dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
349 adap->num, dnames[type], id, minor, minor); 519 adap->num, dnames[type], id, minor, minor);
350 520
351 dvb_register_media_device(dvbdev, type, minor);
352
353 return 0; 521 return 0;
354} 522}
355EXPORT_SYMBOL(dvb_register_device); 523EXPORT_SYMBOL(dvb_register_device);
@@ -364,15 +532,9 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
364 dvb_minors[dvbdev->minor] = NULL; 532 dvb_minors[dvbdev->minor] = NULL;
365 up_write(&minor_rwsem); 533 up_write(&minor_rwsem);
366 534
367 device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); 535 dvb_media_device_free(dvbdev);
368 536
369#if defined(CONFIG_MEDIA_CONTROLLER_DVB) 537 device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
370 if (dvbdev->entity) {
371 media_device_unregister_entity(dvbdev->entity);
372 kfree(dvbdev->entity);
373 kfree(dvbdev->pads);
374 }
375#endif
376 538
377 list_del (&dvbdev->list_head); 539 list_del (&dvbdev->list_head);
378 kfree (dvbdev->fops); 540 kfree (dvbdev->fops);
@@ -382,46 +544,212 @@ EXPORT_SYMBOL(dvb_unregister_device);
382 544
383 545
384#ifdef CONFIG_MEDIA_CONTROLLER_DVB 546#ifdef CONFIG_MEDIA_CONTROLLER_DVB
385void dvb_create_media_graph(struct dvb_adapter *adap) 547
548static int dvb_create_io_intf_links(struct dvb_adapter *adap,
549 struct media_interface *intf,
550 char *name)
551{
552 struct media_device *mdev = adap->mdev;
553 struct media_entity *entity;
554 struct media_link *link;
555
556 media_device_for_each_entity(entity, mdev) {
557 if (entity->function == MEDIA_ENT_F_IO_DTV) {
558 if (strncmp(entity->name, name, strlen(name)))
559 continue;
560 link = media_create_intf_link(entity, intf,
561 MEDIA_LNK_FL_ENABLED);
562 if (!link)
563 return -ENOMEM;
564 }
565 }
566 return 0;
567}
568
569int dvb_create_media_graph(struct dvb_adapter *adap,
570 bool create_rf_connector)
386{ 571{
387 struct media_device *mdev = adap->mdev; 572 struct media_device *mdev = adap->mdev;
388 struct media_entity *entity, *tuner = NULL, *fe = NULL; 573 struct media_entity *entity, *tuner = NULL, *demod = NULL, *conn;
389 struct media_entity *demux = NULL, *dvr = NULL, *ca = NULL; 574 struct media_entity *demux = NULL, *ca = NULL;
575 struct media_link *link;
576 struct media_interface *intf;
577 unsigned demux_pad = 0;
578 unsigned dvr_pad = 0;
579 unsigned ntuner = 0, ndemod = 0;
580 int ret;
581 static const char *connector_name = "Television";
390 582
391 if (!mdev) 583 if (!mdev)
392 return; 584 return 0;
393 585
394 media_device_for_each_entity(entity, mdev) { 586 media_device_for_each_entity(entity, mdev) {
395 switch (entity->type) { 587 switch (entity->function) {
396 case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: 588 case MEDIA_ENT_F_TUNER:
397 tuner = entity; 589 tuner = entity;
590 ntuner++;
398 break; 591 break;
399 case MEDIA_ENT_T_DEVNODE_DVB_FE: 592 case MEDIA_ENT_F_DTV_DEMOD:
400 fe = entity; 593 demod = entity;
594 ndemod++;
401 break; 595 break;
402 case MEDIA_ENT_T_DEVNODE_DVB_DEMUX: 596 case MEDIA_ENT_F_TS_DEMUX:
403 demux = entity; 597 demux = entity;
404 break; 598 break;
405 case MEDIA_ENT_T_DEVNODE_DVB_DVR: 599 case MEDIA_ENT_F_DTV_CA:
406 dvr = entity;
407 break;
408 case MEDIA_ENT_T_DEVNODE_DVB_CA:
409 ca = entity; 600 ca = entity;
410 break; 601 break;
411 } 602 }
412 } 603 }
413 604
414 if (tuner && fe) 605 /*
415 media_entity_create_link(tuner, 0, fe, 0, 0); 606 * Prepare to signalize to media_create_pad_links() that multiple
607 * entities of the same type exists and a 1:n or n:1 links need to be
608 * created.
609 * NOTE: if both tuner and demod have multiple instances, it is up
610 * to the caller driver to create such links.
611 */
612 if (ntuner > 1)
613 tuner = NULL;
614 if (ndemod > 1)
615 demod = NULL;
616
617 if (create_rf_connector) {
618 conn = kzalloc(sizeof(*conn), GFP_KERNEL);
619 if (!conn)
620 return -ENOMEM;
621 adap->conn = conn;
622
623 adap->conn_pads = kcalloc(1, sizeof(*adap->conn_pads),
624 GFP_KERNEL);
625 if (!adap->conn_pads)
626 return -ENOMEM;
627
628 conn->flags = MEDIA_ENT_FL_CONNECTOR;
629 conn->function = MEDIA_ENT_F_CONN_RF;
630 conn->name = connector_name;
631 adap->conn_pads->flags = MEDIA_PAD_FL_SOURCE;
632
633 ret = media_entity_pads_init(conn, 1, adap->conn_pads);
634 if (ret)
635 return ret;
636
637 ret = media_device_register_entity(mdev, conn);
638 if (ret)
639 return ret;
640
641 if (!ntuner)
642 ret = media_create_pad_links(mdev,
643 MEDIA_ENT_F_CONN_RF,
644 conn, 0,
645 MEDIA_ENT_F_DTV_DEMOD,
646 demod, 0,
647 MEDIA_LNK_FL_ENABLED,
648 false);
649 else
650 ret = media_create_pad_links(mdev,
651 MEDIA_ENT_F_CONN_RF,
652 conn, 0,
653 MEDIA_ENT_F_TUNER,
654 tuner, TUNER_PAD_RF_INPUT,
655 MEDIA_LNK_FL_ENABLED,
656 false);
657 if (ret)
658 return ret;
659 }
660
661 if (ntuner && ndemod) {
662 ret = media_create_pad_links(mdev,
663 MEDIA_ENT_F_TUNER,
664 tuner, TUNER_PAD_IF_OUTPUT,
665 MEDIA_ENT_F_DTV_DEMOD,
666 demod, 0, MEDIA_LNK_FL_ENABLED,
667 false);
668 if (ret)
669 return ret;
670 }
671
672 if (ndemod && demux) {
673 ret = media_create_pad_links(mdev,
674 MEDIA_ENT_F_DTV_DEMOD,
675 demod, 1,
676 MEDIA_ENT_F_TS_DEMUX,
677 demux, 0, MEDIA_LNK_FL_ENABLED,
678 false);
679 if (ret)
680 return -ENOMEM;
681 }
682 if (demux && ca) {
683 ret = media_create_pad_link(demux, 1, ca,
684 0, MEDIA_LNK_FL_ENABLED);
685 if (!ret)
686 return -ENOMEM;
687 }
416 688
417 if (fe && demux) 689 /* Create demux links for each ringbuffer/pad */
418 media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED); 690 if (demux) {
691 media_device_for_each_entity(entity, mdev) {
692 if (entity->function == MEDIA_ENT_F_IO_DTV) {
693 if (!strncmp(entity->name, DVR_TSOUT,
694 strlen(DVR_TSOUT))) {
695 ret = media_create_pad_link(demux,
696 ++dvr_pad,
697 entity, 0, 0);
698 if (ret)
699 return ret;
700 }
701 if (!strncmp(entity->name, DEMUX_TSOUT,
702 strlen(DEMUX_TSOUT))) {
703 ret = media_create_pad_link(demux,
704 ++demux_pad,
705 entity, 0, 0);
706 if (ret)
707 return ret;
708 }
709 }
710 }
711 }
419 712
420 if (demux && dvr) 713 /* Create interface links for FE->tuner, DVR->demux and CA->ca */
421 media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED); 714 media_device_for_each_intf(intf, mdev) {
715 if (intf->type == MEDIA_INTF_T_DVB_CA && ca) {
716 link = media_create_intf_link(ca, intf,
717 MEDIA_LNK_FL_ENABLED);
718 if (!link)
719 return -ENOMEM;
720 }
422 721
423 if (demux && ca) 722 if (intf->type == MEDIA_INTF_T_DVB_FE && tuner) {
424 media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED); 723 link = media_create_intf_link(tuner, intf,
724 MEDIA_LNK_FL_ENABLED);
725 if (!link)
726 return -ENOMEM;
727 }
728#if 0
729 /*
730 * Indirect link - let's not create yet, as we don't know how
731 * to handle indirect links, nor if this will
732 * actually be needed.
733 */
734 if (intf->type == MEDIA_INTF_T_DVB_DVR && demux) {
735 link = media_create_intf_link(demux, intf,
736 MEDIA_LNK_FL_ENABLED);
737 if (!link)
738 return -ENOMEM;
739 }
740#endif
741 if (intf->type == MEDIA_INTF_T_DVB_DVR) {
742 ret = dvb_create_io_intf_links(adap, intf, DVR_TSOUT);
743 if (ret)
744 return ret;
745 }
746 if (intf->type == MEDIA_INTF_T_DVB_DEMUX) {
747 ret = dvb_create_io_intf_links(adap, intf, DEMUX_TSOUT);
748 if (ret)
749 return ret;
750 }
751 }
752 return 0;
425} 753}
426EXPORT_SYMBOL_GPL(dvb_create_media_graph); 754EXPORT_SYMBOL_GPL(dvb_create_media_graph);
427#endif 755#endif
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h
index 1069a776bbdb..4aff7bd3dea8 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/drivers/media/dvb-core/dvbdev.h
@@ -75,6 +75,9 @@ struct dvb_frontend;
75 * used. 75 * used.
76 * @mdev: pointer to struct media_device, used when the media 76 * @mdev: pointer to struct media_device, used when the media
77 * controller is used. 77 * controller is used.
78 * @conn: RF connector. Used only if the device has no separate
79 * tuner.
80 * @conn_pads: pointer to struct media_pad associated with @conn;
78 */ 81 */
79struct dvb_adapter { 82struct dvb_adapter {
80 int num; 83 int num;
@@ -94,6 +97,8 @@ struct dvb_adapter {
94 97
95#if defined(CONFIG_MEDIA_CONTROLLER_DVB) 98#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
96 struct media_device *mdev; 99 struct media_device *mdev;
100 struct media_entity *conn;
101 struct media_pad *conn_pads;
97#endif 102#endif
98}; 103};
99 104
@@ -120,6 +125,11 @@ struct dvb_adapter {
120 * @entity: pointer to struct media_entity associated with the device node 125 * @entity: pointer to struct media_entity associated with the device node
121 * @pads: pointer to struct media_pad associated with @entity; 126 * @pads: pointer to struct media_pad associated with @entity;
122 * @priv: private data 127 * @priv: private data
128 * @intf_devnode: Pointer to media_intf_devnode. Used by the dvbdev core to
129 * store the MC device node interface
130 * @tsout_num_entities: Number of Transport Stream output entities
131 * @tsout_entity: array with MC entities associated to each TS output node
132 * @tsout_pads: array with the source pads for each @tsout_entity
123 * 133 *
124 * This structure is used by the DVB core (frontend, CA, net, demux) in 134 * This structure is used by the DVB core (frontend, CA, net, demux) in
125 * order to create the device nodes. Usually, driver should not initialize 135 * order to create the device nodes. Usually, driver should not initialize
@@ -148,8 +158,11 @@ struct dvb_device {
148 const char *name; 158 const char *name;
149 159
150 /* Allocated and filled inside dvbdev.c */ 160 /* Allocated and filled inside dvbdev.c */
151 struct media_entity *entity; 161 struct media_intf_devnode *intf_devnode;
152 struct media_pad *pads; 162
163 unsigned tsout_num_entities;
164 struct media_entity *entity, *tsout_entity;
165 struct media_pad *pads, *tsout_pads;
153#endif 166#endif
154 167
155 void *priv; 168 void *priv;
@@ -185,14 +198,18 @@ int dvb_unregister_adapter(struct dvb_adapter *adap);
185 * stored 198 * stored
186 * @template: Template used to create &pdvbdev; 199 * @template: Template used to create &pdvbdev;
187 * @priv: private data 200 * @priv: private data
188 * @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND, 201 * @type: type of the device: %DVB_DEVICE_SEC, %DVB_DEVICE_FRONTEND,
189 * DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET 202 * %DVB_DEVICE_DEMUX, %DVB_DEVICE_DVR, %DVB_DEVICE_CA,
203 * %DVB_DEVICE_NET
204 * @demux_sink_pads: Number of demux outputs, to be used to create the TS
205 * outputs via the Media Controller.
190 */ 206 */
191int dvb_register_device(struct dvb_adapter *adap, 207int dvb_register_device(struct dvb_adapter *adap,
192 struct dvb_device **pdvbdev, 208 struct dvb_device **pdvbdev,
193 const struct dvb_device *template, 209 const struct dvb_device *template,
194 void *priv, 210 void *priv,
195 int type); 211 int type,
212 int demux_sink_pads);
196 213
197/** 214/**
198 * dvb_unregister_device - Unregisters a DVB device 215 * dvb_unregister_device - Unregisters a DVB device
@@ -202,16 +219,43 @@ int dvb_register_device(struct dvb_adapter *adap,
202void dvb_unregister_device(struct dvb_device *dvbdev); 219void dvb_unregister_device(struct dvb_device *dvbdev);
203 220
204#ifdef CONFIG_MEDIA_CONTROLLER_DVB 221#ifdef CONFIG_MEDIA_CONTROLLER_DVB
205void dvb_create_media_graph(struct dvb_adapter *adap); 222/**
223 * dvb_create_media_graph - Creates media graph for the Digital TV part of the
224 * device.
225 *
226 * @adap: pointer to struct dvb_adapter
227 * @create_rf_connector: if true, it creates the RF connector too
228 *
229 * This function checks all DVB-related functions at the media controller
230 * entities and creates the needed links for the media graph. It is
231 * capable of working with multiple tuners or multiple frontends, but it
232 * won't create links if the device has multiple tuners and multiple frontends
233 * or if the device has multiple muxes. In such case, the caller driver should
234 * manually create the remaining links.
235 */
236__must_check int dvb_create_media_graph(struct dvb_adapter *adap,
237 bool create_rf_connector);
238
206static inline void dvb_register_media_controller(struct dvb_adapter *adap, 239static inline void dvb_register_media_controller(struct dvb_adapter *adap,
207 struct media_device *mdev) 240 struct media_device *mdev)
208{ 241{
209 adap->mdev = mdev; 242 adap->mdev = mdev;
210} 243}
211 244
245static inline struct media_device
246*dvb_get_media_controller(struct dvb_adapter *adap)
247{
248 return adap->mdev;
249}
212#else 250#else
213static inline void dvb_create_media_graph(struct dvb_adapter *adap) {} 251static inline
252int dvb_create_media_graph(struct dvb_adapter *adap,
253 bool create_rf_connector)
254{
255 return 0;
256};
214#define dvb_register_media_controller(a, b) {} 257#define dvb_register_media_controller(a, b) {}
258#define dvb_get_media_controller(a) NULL
215#endif 259#endif
216 260
217int dvb_generic_open (struct inode *inode, struct file *file); 261int dvb_generic_open (struct inode *inode, struct file *file);
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index c8f13d8370e5..73612c5353d1 100644
--- a/drivers/media/dvb-frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -730,6 +730,9 @@ static int au8522_probe(struct i2c_client *client,
730 struct v4l2_ctrl_handler *hdl; 730 struct v4l2_ctrl_handler *hdl;
731 struct v4l2_subdev *sd; 731 struct v4l2_subdev *sd;
732 int instance; 732 int instance;
733#ifdef CONFIG_MEDIA_CONTROLLER
734 int ret;
735#endif
733 736
734 /* Check if the adapter supports the needed features */ 737 /* Check if the adapter supports the needed features */
735 if (!i2c_check_functionality(client->adapter, 738 if (!i2c_check_functionality(client->adapter,
@@ -758,6 +761,20 @@ static int au8522_probe(struct i2c_client *client,
758 761
759 sd = &state->sd; 762 sd = &state->sd;
760 v4l2_i2c_subdev_init(sd, client, &au8522_ops); 763 v4l2_i2c_subdev_init(sd, client, &au8522_ops);
764#if defined(CONFIG_MEDIA_CONTROLLER)
765
766 state->pads[AU8522_PAD_INPUT].flags = MEDIA_PAD_FL_SINK;
767 state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
768 state->pads[AU8522_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
769 sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
770
771 ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads),
772 state->pads);
773 if (ret < 0) {
774 v4l_info(client, "failed to initialize media entity!\n");
775 return ret;
776 }
777#endif
761 778
762 hdl = &state->hdl; 779 hdl = &state->hdl;
763 v4l2_ctrl_handler_init(hdl, 4); 780 v4l2_ctrl_handler_init(hdl, 4);
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index ee330c61aa61..404a0cb0ed8d 100644
--- a/drivers/media/dvb-frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -39,6 +39,14 @@
39#define AU8522_DIGITAL_MODE 1 39#define AU8522_DIGITAL_MODE 1
40#define AU8522_SUSPEND_MODE 2 40#define AU8522_SUSPEND_MODE 2
41 41
42enum au8522_media_pads {
43 AU8522_PAD_INPUT,
44 AU8522_PAD_VID_OUT,
45 AU8522_PAD_VBI_OUT,
46
47 AU8522_NUM_PADS
48};
49
42struct au8522_state { 50struct au8522_state {
43 struct i2c_client *c; 51 struct i2c_client *c;
44 struct i2c_adapter *i2c; 52 struct i2c_adapter *i2c;
@@ -68,6 +76,10 @@ struct au8522_state {
68 u32 id; 76 u32 id;
69 u32 rev; 77 u32 rev;
70 struct v4l2_ctrl_handler hdl; 78 struct v4l2_ctrl_handler hdl;
79
80#ifdef CONFIG_MEDIA_CONTROLLER
81 struct media_pad pads[AU8522_NUM_PADS];
82#endif
71}; 83};
72 84
73/* These are routines shared by both the VSB/QAM demodulator and the analog 85/* These are routines shared by both the VSB/QAM demodulator and the analog
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)
241 return -EFAULT; 241 return -EFAULT;
242 242
243 err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, 243 err = dvb_register_device(&fdtv->adapter, &fdtv->cadev,
244 &fdtv_ca, fdtv, DVB_DEVICE_CA); 244 &fdtv_ca, fdtv, DVB_DEVICE_CA, 0);
245 245
246 if (stat.ca_application_info == 0) 246 if (stat.ca_application_info == 0)
247 dev_err(fdtv->device, "CaApplicationInfo is not set\n"); 247 dev_err(fdtv->device, "CaApplicationInfo is not set\n");
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index 0494a7896aa2..788967dadd29 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -1158,7 +1158,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
1158 state->rgb_quantization_range_ctrl->is_private = true; 1158 state->rgb_quantization_range_ctrl->is_private = true;
1159 1159
1160 state->pad.flags = MEDIA_PAD_FL_SINK; 1160 state->pad.flags = MEDIA_PAD_FL_SINK;
1161 err = media_entity_init(&sd->entity, 1, &state->pad, 0); 1161 err = media_entity_pads_init(&sd->entity, 1, &state->pad);
1162 if (err) 1162 if (err)
1163 goto err_hdl; 1163 goto err_hdl;
1164 1164
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
index f00745bbe471..7e9cbf757e95 100644
--- a/drivers/media/i2c/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -512,11 +512,11 @@ static int adp1653_probe(struct i2c_client *client,
512 if (ret) 512 if (ret)
513 goto free_and_quit; 513 goto free_and_quit;
514 514
515 ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0); 515 ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL);
516 if (ret < 0) 516 if (ret < 0)
517 goto free_and_quit; 517 goto free_and_quit;
518 518
519 flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; 519 flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
520 520
521 return 0; 521 return 0;
522 522
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 3c3c4bfe3866..ff57c1dcb8af 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1213,8 +1213,8 @@ static int adv7180_probe(struct i2c_client *client,
1213 goto err_unregister_vpp_client; 1213 goto err_unregister_vpp_client;
1214 1214
1215 state->pad.flags = MEDIA_PAD_FL_SOURCE; 1215 state->pad.flags = MEDIA_PAD_FL_SOURCE;
1216 sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; 1216 sd->entity.flags |= MEDIA_ENT_F_ATV_DECODER;
1217 ret = media_entity_init(&sd->entity, 1, &state->pad, 0); 1217 ret = media_entity_pads_init(&sd->entity, 1, &state->pad);
1218 if (ret) 1218 if (ret)
1219 goto err_free_ctrl; 1219 goto err_free_ctrl;
1220 1220
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index eeb2cd823c4d..471fd23b5c5c 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -1482,7 +1482,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id *
1482 state->rgb_quantization_range_ctrl->is_private = true; 1482 state->rgb_quantization_range_ctrl->is_private = true;
1483 1483
1484 state->pad.flags = MEDIA_PAD_FL_SINK; 1484 state->pad.flags = MEDIA_PAD_FL_SINK;
1485 err = media_entity_init(&sd->entity, 1, &state->pad, 0); 1485 err = media_entity_pads_init(&sd->entity, 1, &state->pad);
1486 if (err) 1486 if (err)
1487 goto err_hdl; 1487 goto err_hdl;
1488 1488
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 745286225655..f8dd7505b529 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3208,8 +3208,8 @@ static int adv76xx_probe(struct i2c_client *client,
3208 state->pads[i].flags = MEDIA_PAD_FL_SINK; 3208 state->pads[i].flags = MEDIA_PAD_FL_SINK;
3209 state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE; 3209 state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE;
3210 3210
3211 err = media_entity_init(&sd->entity, state->source_pad + 1, 3211 err = media_entity_pads_init(&sd->entity, state->source_pad + 1,
3212 state->pads, 0); 3212 state->pads);
3213 if (err) 3213 if (err)
3214 goto err_work_queues; 3214 goto err_work_queues;
3215 3215
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 69378e4914b6..5fbb788e7b59 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -3309,7 +3309,7 @@ static int adv7842_probe(struct i2c_client *client,
3309 adv7842_delayed_work_enable_hotplug); 3309 adv7842_delayed_work_enable_hotplug);
3310 3310
3311 state->pad.flags = MEDIA_PAD_FL_SOURCE; 3311 state->pad.flags = MEDIA_PAD_FL_SOURCE;
3312 err = media_entity_init(&sd->entity, 1, &state->pad, 0); 3312 err = media_entity_pads_init(&sd->entity, 1, &state->pad);
3313 if (err) 3313 if (err)
3314 goto err_work_queues; 3314 goto err_work_queues;
3315 3315
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
index 29a2e7034aa6..2e90e4094b79 100644
--- a/drivers/media/i2c/as3645a.c
+++ b/drivers/media/i2c/as3645a.c
@@ -827,11 +827,11 @@ static int as3645a_probe(struct i2c_client *client,
827 if (ret < 0) 827 if (ret < 0)
828 goto done; 828 goto done;
829 829
830 ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0); 830 ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL);
831 if (ret < 0) 831 if (ret < 0)
832 goto done; 832 goto done;
833 833
834 flash->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; 834 flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
835 835
836 mutex_init(&flash->power_lock); 836 mutex_init(&flash->power_lock);
837 837
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index f2e2c34ddbbd..07a3e7173144 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -5211,10 +5211,10 @@ static int cx25840_probe(struct i2c_client *client,
5211 state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; 5211 state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK;
5212 state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; 5212 state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
5213 state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; 5213 state->pads[CX25840_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
5214 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER; 5214 sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
5215 5215
5216 ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads), 5216 ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads),
5217 state->pads, 0); 5217 state->pads);
5218 if (ret < 0) { 5218 if (ret < 0) {
5219 v4l_info(client, "failed to initialize media entity!\n"); 5219 v4l_info(client, "failed to initialize media entity!\n");
5220 return ret; 5220 return ret;
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index 19ecb8801064..251a2aaf98c3 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -365,10 +365,10 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
365 rval = lm3560_init_controls(flash, led_no); 365 rval = lm3560_init_controls(flash, led_no);
366 if (rval) 366 if (rval)
367 goto err_out; 367 goto err_out;
368 rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0); 368 rval = media_entity_pads_init(&flash->subdev_led[led_no].entity, 0, NULL);
369 if (rval < 0) 369 if (rval < 0)
370 goto err_out; 370 goto err_out;
371 flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; 371 flash->subdev_led[led_no].entity.function = MEDIA_ENT_F_FLASH;
372 372
373 return rval; 373 return rval;
374 374
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c
index 7fbe6ff1c4f4..7e9967af36ec 100644
--- a/drivers/media/i2c/lm3646.c
+++ b/drivers/media/i2c/lm3646.c
@@ -282,10 +282,10 @@ static int lm3646_subdev_init(struct lm3646_flash *flash)
282 rval = lm3646_init_controls(flash); 282 rval = lm3646_init_controls(flash);
283 if (rval) 283 if (rval)
284 goto err_out; 284 goto err_out;
285 rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0); 285 rval = media_entity_pads_init(&flash->subdev_led.entity, 0, NULL);
286 if (rval < 0) 286 if (rval < 0)
287 goto err_out; 287 goto err_out;
288 flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; 288 flash->subdev_led.entity.function = MEDIA_ENT_F_FLASH;
289 return rval; 289 return rval;
290 290
291err_out: 291err_out:
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index f8993933416e..acb804bceccb 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -975,10 +975,10 @@ static int m5mols_probe(struct i2c_client *client,
975 975
976 sd->internal_ops = &m5mols_subdev_internal_ops; 976 sd->internal_ops = &m5mols_subdev_internal_ops;
977 info->pad.flags = MEDIA_PAD_FL_SOURCE; 977 info->pad.flags = MEDIA_PAD_FL_SOURCE;
978 ret = media_entity_init(&sd->entity, 1, &info->pad, 0); 978 ret = media_entity_pads_init(&sd->entity, 1, &info->pad);
979 if (ret < 0) 979 if (ret < 0)
980 return ret; 980 return ret;
981 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 981 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
982 982
983 init_waitqueue_head(&info->irq_waitq); 983 init_waitqueue_head(&info->irq_waitq);
984 mutex_init(&info->lock); 984 mutex_init(&info->lock);
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
index 101cb26f9330..da076796999e 100644
--- a/drivers/media/i2c/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -799,7 +799,7 @@ static int mt9m032_probe(struct i2c_client *client,
799 799
800 sensor->subdev.ctrl_handler = &sensor->ctrls; 800 sensor->subdev.ctrl_handler = &sensor->ctrls;
801 sensor->pad.flags = MEDIA_PAD_FL_SOURCE; 801 sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
802 ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0); 802 ret = media_entity_pads_init(&sensor->subdev.entity, 1, &sensor->pad);
803 if (ret < 0) 803 if (ret < 0)
804 goto error_ctrl; 804 goto error_ctrl;
805 805
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index a3da0e977d0b..237737fec09c 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1112,7 +1112,7 @@ static int mt9p031_probe(struct i2c_client *client,
1112 mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops; 1112 mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
1113 1113
1114 mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE; 1114 mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
1115 ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0); 1115 ret = media_entity_pads_init(&mt9p031->subdev.entity, 1, &mt9p031->pad);
1116 if (ret < 0) 1116 if (ret < 0)
1117 goto done; 1117 goto done;
1118 1118
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index b28fdff1d310..702d562f8e39 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -933,7 +933,7 @@ static int mt9t001_probe(struct i2c_client *client,
933 mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 933 mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
934 934
935 mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE; 935 mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE;
936 ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad, 0); 936 ret = media_entity_pads_init(&mt9t001->subdev.entity, 1, &mt9t001->pad);
937 937
938done: 938done:
939 if (ret < 0) { 939 if (ret < 0) {
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 1dbbd23fdfb0..2e1d116a64e7 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1046,7 +1046,7 @@ static int mt9v032_probe(struct i2c_client *client,
1046 mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1046 mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1047 1047
1048 mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE; 1048 mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
1049 ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0); 1049 ret = media_entity_pads_init(&mt9v032->subdev.entity, 1, &mt9v032->pad);
1050 if (ret < 0) 1050 if (ret < 0)
1051 goto err; 1051 goto err;
1052 1052
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index 69e4f3031d8b..30cb90b88d75 100644
--- a/drivers/media/i2c/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
@@ -779,8 +779,8 @@ static int noon010_probe(struct i2c_client *client,
779 goto np_err; 779 goto np_err;
780 780
781 info->pad.flags = MEDIA_PAD_FL_SOURCE; 781 info->pad.flags = MEDIA_PAD_FL_SOURCE;
782 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 782 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
783 ret = media_entity_init(&sd->entity, 1, &info->pad, 0); 783 ret = media_entity_pads_init(&sd->entity, 1, &info->pad);
784 if (ret < 0) 784 if (ret < 0)
785 goto np_err; 785 goto np_err;
786 786
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 82c7ac1cc88e..02b9a3440557 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1445,8 +1445,8 @@ static int ov2659_probe(struct i2c_client *client,
1445 1445
1446#if defined(CONFIG_MEDIA_CONTROLLER) 1446#if defined(CONFIG_MEDIA_CONTROLLER)
1447 ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; 1447 ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
1448 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 1448 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1449 ret = media_entity_init(&sd->entity, 1, &ov2659->pad, 0); 1449 ret = media_entity_pads_init(&sd->entity, 1, &ov2659->pad);
1450 if (ret < 0) { 1450 if (ret < 0) {
1451 v4l2_ctrl_handler_free(&ov2659->ctrls); 1451 v4l2_ctrl_handler_free(&ov2659->ctrls);
1452 return ret; 1452 return ret;
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 9fe9006474b2..a0b3c9bde53d 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -1500,8 +1500,8 @@ static int ov965x_probe(struct i2c_client *client,
1500 return ret; 1500 return ret;
1501 1501
1502 ov965x->pad.flags = MEDIA_PAD_FL_SOURCE; 1502 ov965x->pad.flags = MEDIA_PAD_FL_SOURCE;
1503 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 1503 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1504 ret = media_entity_init(&sd->entity, 1, &ov965x->pad, 0); 1504 ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad);
1505 if (ret < 0) 1505 if (ret < 0)
1506 return ret; 1506 return ret;
1507 1507
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 25f5e79dc9bc..57b3d27993a4 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)
1482 return ret; 1482 return ret;
1483 } 1483 }
1484 1484
1485 ret = media_entity_create_link(&state->sensor_sd.entity, 1485 ret = media_create_pad_link(&state->sensor_sd.entity,
1486 S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD, 1486 S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD,
1487 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 1487 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
1488 1488
1489 ret = media_entity_create_link(&state->sensor_sd.entity, 1489 ret = media_create_pad_link(&state->sensor_sd.entity,
1490 S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD, 1490 S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
1491 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 1491 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
1492 1492
@@ -1688,10 +1688,10 @@ static int s5c73m3_probe(struct i2c_client *client,
1688 1688
1689 state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE; 1689 state->sensor_pads[S5C73M3_JPEG_PAD].flags = MEDIA_PAD_FL_SOURCE;
1690 state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE; 1690 state->sensor_pads[S5C73M3_ISP_PAD].flags = MEDIA_PAD_FL_SOURCE;
1691 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; 1691 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1692 1692
1693 ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, 1693 ret = media_entity_pads_init(&sd->entity, S5C73M3_NUM_PADS,
1694 state->sensor_pads, 0); 1694 state->sensor_pads);
1695 if (ret < 0) 1695 if (ret < 0)
1696 return ret; 1696 return ret;
1697 1697
@@ -1704,10 +1704,10 @@ static int s5c73m3_probe(struct i2c_client *client,
1704 state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK; 1704 state->oif_pads[OIF_ISP_PAD].flags = MEDIA_PAD_FL_SINK;
1705 state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK; 1705 state->oif_pads[OIF_JPEG_PAD].flags = MEDIA_PAD_FL_SINK;
1706 state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE; 1706 state->oif_pads[OIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE;
1707 oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; 1707 oif_sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
1708 1708
1709 ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS, 1709 ret = media_entity_pads_init(&oif_sd->entity, OIF_NUM_PADS,
1710 state->oif_pads, 0); 1710 state->oif_pads);
1711 if (ret < 0) 1711 if (ret < 0)
1712 return ret; 1712 return ret;
1713 1713
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c
index 6757aca2cdab..8a0f22da590f 100644
--- a/drivers/media/i2c/s5k4ecgx.c
+++ b/drivers/media/i2c/s5k4ecgx.c
@@ -961,8 +961,8 @@ static int s5k4ecgx_probe(struct i2c_client *client,
961 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 961 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
962 962
963 priv->pad.flags = MEDIA_PAD_FL_SOURCE; 963 priv->pad.flags = MEDIA_PAD_FL_SOURCE;
964 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 964 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
965 ret = media_entity_init(&sd->entity, 1, &priv->pad, 0); 965 ret = media_entity_pads_init(&sd->entity, 1, &priv->pad);
966 if (ret) 966 if (ret)
967 return ret; 967 return ret;
968 968
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 774e0d0c94cb..fc3a5a8e6c9c 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)
408 408
409static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd) 409static inline bool s5k5baf_is_cis_subdev(struct v4l2_subdev *sd)
410{ 410{
411 return sd->entity.type == MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 411 return sd->entity.function == MEDIA_ENT_F_CAM_SENSOR;
412} 412}
413 413
414static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd) 414static inline struct s5k5baf *to_s5k5baf(struct v4l2_subdev *sd)
@@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd)
1756 v4l2_err(sd, "failed to register subdev %s\n", 1756 v4l2_err(sd, "failed to register subdev %s\n",
1757 state->cis_sd.name); 1757 state->cis_sd.name);
1758 else 1758 else
1759 ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS, 1759 ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
1760 &state->sd.entity, PAD_CIS, 1760 &state->sd.entity, PAD_CIS,
1761 MEDIA_LNK_FL_IMMUTABLE | 1761 MEDIA_LNK_FL_IMMUTABLE |
1762 MEDIA_LNK_FL_ENABLED); 1762 MEDIA_LNK_FL_ENABLED);
@@ -1904,8 +1904,8 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
1904 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1904 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1905 1905
1906 state->cis_pad.flags = MEDIA_PAD_FL_SOURCE; 1906 state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
1907 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 1907 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1908 ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad, 0); 1908 ret = media_entity_pads_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad);
1909 if (ret < 0) 1909 if (ret < 0)
1910 goto err; 1910 goto err;
1911 1911
@@ -1919,8 +1919,8 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
1919 1919
1920 state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK; 1920 state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
1921 state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; 1921 state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
1922 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; 1922 sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
1923 ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads, 0); 1923 ret = media_entity_pads_init(&sd->entity, NUM_ISP_PADS, state->pads);
1924 1924
1925 if (!ret) 1925 if (!ret)
1926 return 0; 1926 return 0;
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index b1b1574dfb95..b9e43ffa5085 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -333,7 +333,7 @@ static int s5k6a3_probe(struct i2c_client *client,
333 sensor->format.height = S5K6A3_DEFAULT_HEIGHT; 333 sensor->format.height = S5K6A3_DEFAULT_HEIGHT;
334 334
335 sensor->pad.flags = MEDIA_PAD_FL_SOURCE; 335 sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
336 ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0); 336 ret = media_entity_pads_init(&sd->entity, 1, &sensor->pad);
337 if (ret < 0) 337 if (ret < 0)
338 return ret; 338 return ret;
339 339
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index 60aaff7190d2..faee11383cb7 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -1577,8 +1577,8 @@ static int s5k6aa_probe(struct i2c_client *client,
1577 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1577 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1578 1578
1579 s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE; 1579 s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
1580 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 1580 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1581 ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0); 1581 ret = media_entity_pads_init(&sd->entity, 1, &s5k6aa->pad);
1582 if (ret) 1582 if (ret)
1583 return ret; 1583 return ret;
1584 1584
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index fb39dfd55e75..a215efe7a8ba 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2487,31 +2487,31 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
2487 if (!last) 2487 if (!last)
2488 continue; 2488 continue;
2489 2489
2490 rval = media_entity_init(&this->sd.entity, 2490 rval = media_entity_pads_init(&this->sd.entity,
2491 this->npads, this->pads, 0); 2491 this->npads, this->pads);
2492 if (rval) { 2492 if (rval) {
2493 dev_err(&client->dev, 2493 dev_err(&client->dev,
2494 "media_entity_init failed\n"); 2494 "media_entity_pads_init failed\n");
2495 return rval; 2495 return rval;
2496 } 2496 }
2497 2497
2498 rval = media_entity_create_link(&this->sd.entity, 2498 rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev,
2499 this->source_pad, 2499 &this->sd);
2500 &last->sd.entity,
2501 last->sink_pad,
2502 MEDIA_LNK_FL_ENABLED |
2503 MEDIA_LNK_FL_IMMUTABLE);
2504 if (rval) { 2500 if (rval) {
2505 dev_err(&client->dev, 2501 dev_err(&client->dev,
2506 "media_entity_create_link failed\n"); 2502 "v4l2_device_register_subdev failed\n");
2507 return rval; 2503 return rval;
2508 } 2504 }
2509 2505
2510 rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, 2506 rval = media_create_pad_link(&this->sd.entity,
2511 &this->sd); 2507 this->source_pad,
2508 &last->sd.entity,
2509 last->sink_pad,
2510 MEDIA_LNK_FL_ENABLED |
2511 MEDIA_LNK_FL_IMMUTABLE);
2512 if (rval) { 2512 if (rval) {
2513 dev_err(&client->dev, 2513 dev_err(&client->dev,
2514 "v4l2_device_register_subdev failed\n"); 2514 "media_create_pad_link failed\n");
2515 return rval; 2515 return rval;
2516 } 2516 }
2517 } 2517 }
@@ -2763,7 +2763,7 @@ static int smiapp_init(struct smiapp_sensor *sensor)
2763 2763
2764 dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile); 2764 dev_dbg(&client->dev, "profile %d\n", sensor->minfo.smiapp_profile);
2765 2765
2766 sensor->pixel_array->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; 2766 sensor->pixel_array->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
2767 2767
2768 /* final steps */ 2768 /* final steps */
2769 smiapp_read_frame_fmt(sensor); 2769 smiapp_read_frame_fmt(sensor);
@@ -3077,8 +3077,8 @@ static int smiapp_probe(struct i2c_client *client,
3077 sensor->src->sensor = sensor; 3077 sensor->src->sensor = sensor;
3078 3078
3079 sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE; 3079 sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
3080 rval = media_entity_init(&sensor->src->sd.entity, 2, 3080 rval = media_entity_pads_init(&sensor->src->sd.entity, 2,
3081 sensor->src->pads, 0); 3081 sensor->src->pads);
3082 if (rval < 0) 3082 if (rval < 0)
3083 return rval; 3083 return rval;
3084 3084
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 77b801152ea5..3397eb99c67b 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1889,7 +1889,7 @@ static int tc358743_probe(struct i2c_client *client,
1889 } 1889 }
1890 1890
1891 state->pad.flags = MEDIA_PAD_FL_SOURCE; 1891 state->pad.flags = MEDIA_PAD_FL_SOURCE;
1892 err = media_entity_init(&sd->entity, 1, &state->pad, 0); 1892 err = media_entity_pads_init(&sd->entity, 1, &state->pad);
1893 if (err < 0) 1893 if (err < 0)
1894 goto err_hdl; 1894 goto err_hdl;
1895 1895
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index b5dba5b7ce3a..7fa5f1e4fe37 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -1095,9 +1095,9 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
1095#if defined(CONFIG_MEDIA_CONTROLLER) 1095#if defined(CONFIG_MEDIA_CONTROLLER)
1096 decoder->pad.flags = MEDIA_PAD_FL_SOURCE; 1096 decoder->pad.flags = MEDIA_PAD_FL_SOURCE;
1097 decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1097 decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1098 decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; 1098 decoder->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER;
1099 1099
1100 ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0); 1100 ret = media_entity_pads_init(&decoder->sd.entity, 1, &decoder->pad);
1101 if (ret < 0) { 1101 if (ret < 0) {
1102 v4l2_err(sd, "%s decoder driver failed to register !!\n", 1102 v4l2_err(sd, "%s decoder driver failed to register !!\n",
1103 sd->name); 1103 sd->name);
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 772a3043ae3b..83c79fa5f61d 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -1012,9 +1012,9 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1012#if defined(CONFIG_MEDIA_CONTROLLER) 1012#if defined(CONFIG_MEDIA_CONTROLLER)
1013 device->pad.flags = MEDIA_PAD_FL_SOURCE; 1013 device->pad.flags = MEDIA_PAD_FL_SOURCE;
1014 device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1014 device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1015 device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER; 1015 device->sd.entity.flags |= MEDIA_ENT_F_ATV_DECODER;
1016 1016
1017 error = media_entity_init(&device->sd.entity, 1, &device->pad, 0); 1017 error = media_entity_pads_init(&device->sd.entity, 1, &device->pad);
1018 if (error < 0) 1018 if (error < 0)
1019 return error; 1019 return error;
1020#endif 1020#endif
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 7b39440192d6..7dae0ac0f3ae 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -22,14 +22,18 @@
22 22
23#include <linux/compat.h> 23#include <linux/compat.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/idr.h>
25#include <linux/ioctl.h> 26#include <linux/ioctl.h>
26#include <linux/media.h> 27#include <linux/media.h>
28#include <linux/slab.h>
27#include <linux/types.h> 29#include <linux/types.h>
28 30
29#include <media/media-device.h> 31#include <media/media-device.h>
30#include <media/media-devnode.h> 32#include <media/media-devnode.h>
31#include <media/media-entity.h> 33#include <media/media-entity.h>
32 34
35#ifdef CONFIG_MEDIA_CONTROLLER
36
33/* ----------------------------------------------------------------------------- 37/* -----------------------------------------------------------------------------
34 * Userspace API 38 * Userspace API
35 */ 39 */
@@ -75,8 +79,8 @@ static struct media_entity *find_entity(struct media_device *mdev, u32 id)
75 spin_lock(&mdev->lock); 79 spin_lock(&mdev->lock);
76 80
77 media_device_for_each_entity(entity, mdev) { 81 media_device_for_each_entity(entity, mdev) {
78 if ((entity->id == id && !next) || 82 if (((media_entity_id(entity) == id) && !next) ||
79 (entity->id > id && next)) { 83 ((media_entity_id(entity) > id) && next)) {
80 spin_unlock(&mdev->lock); 84 spin_unlock(&mdev->lock);
81 return entity; 85 return entity;
82 } 86 }
@@ -102,13 +106,13 @@ static long media_device_enum_entities(struct media_device *mdev,
102 if (ent == NULL) 106 if (ent == NULL)
103 return -EINVAL; 107 return -EINVAL;
104 108
105 u_ent.id = ent->id; 109 u_ent.id = media_entity_id(ent);
106 if (ent->name) 110 if (ent->name)
107 strlcpy(u_ent.name, ent->name, sizeof(u_ent.name)); 111 strlcpy(u_ent.name, ent->name, sizeof(u_ent.name));
108 u_ent.type = ent->type; 112 u_ent.type = ent->function;
109 u_ent.revision = ent->revision; 113 u_ent.revision = 0; /* Unused */
110 u_ent.flags = ent->flags; 114 u_ent.flags = ent->flags;
111 u_ent.group_id = ent->group_id; 115 u_ent.group_id = 0; /* Unused */
112 u_ent.pads = ent->num_pads; 116 u_ent.pads = ent->num_pads;
113 u_ent.links = ent->num_links - ent->num_backlinks; 117 u_ent.links = ent->num_links - ent->num_backlinks;
114 memcpy(&u_ent.raw, &ent->info, sizeof(ent->info)); 118 memcpy(&u_ent.raw, &ent->info, sizeof(ent->info));
@@ -120,7 +124,7 @@ static long media_device_enum_entities(struct media_device *mdev,
120static void media_device_kpad_to_upad(const struct media_pad *kpad, 124static void media_device_kpad_to_upad(const struct media_pad *kpad,
121 struct media_pad_desc *upad) 125 struct media_pad_desc *upad)
122{ 126{
123 upad->entity = kpad->entity->id; 127 upad->entity = media_entity_id(kpad->entity);
124 upad->index = kpad->index; 128 upad->index = kpad->index;
125 upad->flags = kpad->flags; 129 upad->flags = kpad->flags;
126} 130}
@@ -148,25 +152,25 @@ static long __media_device_enum_links(struct media_device *mdev,
148 } 152 }
149 153
150 if (links->links) { 154 if (links->links) {
151 struct media_link_desc __user *ulink; 155 struct media_link *link;
152 unsigned int l; 156 struct media_link_desc __user *ulink_desc = links->links;
153 157
154 for (l = 0, ulink = links->links; l < entity->num_links; l++) { 158 list_for_each_entry(link, &entity->links, list) {
155 struct media_link_desc link; 159 struct media_link_desc klink_desc;
156 160
157 /* Ignore backlinks. */ 161 /* Ignore backlinks. */
158 if (entity->links[l].source->entity != entity) 162 if (link->source->entity != entity)
159 continue; 163 continue;
160 164 memset(&klink_desc, 0, sizeof(klink_desc));
161 memset(&link, 0, sizeof(link)); 165 media_device_kpad_to_upad(link->source,
162 media_device_kpad_to_upad(entity->links[l].source, 166 &klink_desc.source);
163 &link.source); 167 media_device_kpad_to_upad(link->sink,
164 media_device_kpad_to_upad(entity->links[l].sink, 168 &klink_desc.sink);
165 &link.sink); 169 klink_desc.flags = link->flags;
166 link.flags = entity->links[l].flags; 170 if (copy_to_user(ulink_desc, &klink_desc,
167 if (copy_to_user(ulink, &link, sizeof(*ulink))) 171 sizeof(*ulink_desc)))
168 return -EFAULT; 172 return -EFAULT;
169 ulink++; 173 ulink_desc++;
170 } 174 }
171 } 175 }
172 176
@@ -230,6 +234,164 @@ static long media_device_setup_link(struct media_device *mdev,
230 return ret; 234 return ret;
231} 235}
232 236
237#if 0 /* Let's postpone it to Kernel 4.6 */
238static long __media_device_get_topology(struct media_device *mdev,
239 struct media_v2_topology *topo)
240{
241 struct media_entity *entity;
242 struct media_interface *intf;
243 struct media_pad *pad;
244 struct media_link *link;
245 struct media_v2_entity kentity, *uentity;
246 struct media_v2_interface kintf, *uintf;
247 struct media_v2_pad kpad, *upad;
248 struct media_v2_link klink, *ulink;
249 unsigned int i;
250 int ret = 0;
251
252 topo->topology_version = mdev->topology_version;
253
254 /* Get entities and number of entities */
255 i = 0;
256 uentity = media_get_uptr(topo->ptr_entities);
257 media_device_for_each_entity(entity, mdev) {
258 i++;
259 if (ret || !uentity)
260 continue;
261
262 if (i > topo->num_entities) {
263 ret = -ENOSPC;
264 continue;
265 }
266
267 /* Copy fields to userspace struct if not error */
268 memset(&kentity, 0, sizeof(kentity));
269 kentity.id = entity->graph_obj.id;
270 kentity.function = entity->function;
271 strncpy(kentity.name, entity->name,
272 sizeof(kentity.name));
273
274 if (copy_to_user(uentity, &kentity, sizeof(kentity)))
275 ret = -EFAULT;
276 uentity++;
277 }
278 topo->num_entities = i;
279
280 /* Get interfaces and number of interfaces */
281 i = 0;
282 uintf = media_get_uptr(topo->ptr_interfaces);
283 media_device_for_each_intf(intf, mdev) {
284 i++;
285 if (ret || !uintf)
286 continue;
287
288 if (i > topo->num_interfaces) {
289 ret = -ENOSPC;
290 continue;
291 }
292
293 memset(&kintf, 0, sizeof(kintf));
294
295 /* Copy intf fields to userspace struct */
296 kintf.id = intf->graph_obj.id;
297 kintf.intf_type = intf->type;
298 kintf.flags = intf->flags;
299
300 if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) {
301 struct media_intf_devnode *devnode;
302
303 devnode = intf_to_devnode(intf);
304
305 kintf.devnode.major = devnode->major;
306 kintf.devnode.minor = devnode->minor;
307 }
308
309 if (copy_to_user(uintf, &kintf, sizeof(kintf)))
310 ret = -EFAULT;
311 uintf++;
312 }
313 topo->num_interfaces = i;
314
315 /* Get pads and number of pads */
316 i = 0;
317 upad = media_get_uptr(topo->ptr_pads);
318 media_device_for_each_pad(pad, mdev) {
319 i++;
320 if (ret || !upad)
321 continue;
322
323 if (i > topo->num_pads) {
324 ret = -ENOSPC;
325 continue;
326 }
327
328 memset(&kpad, 0, sizeof(kpad));
329
330 /* Copy pad fields to userspace struct */
331 kpad.id = pad->graph_obj.id;
332 kpad.entity_id = pad->entity->graph_obj.id;
333 kpad.flags = pad->flags;
334
335 if (copy_to_user(upad, &kpad, sizeof(kpad)))
336 ret = -EFAULT;
337 upad++;
338 }
339 topo->num_pads = i;
340
341 /* Get links and number of links */
342 i = 0;
343 ulink = media_get_uptr(topo->ptr_links);
344 media_device_for_each_link(link, mdev) {
345 if (link->is_backlink)
346 continue;
347
348 i++;
349
350 if (ret || !ulink)
351 continue;
352
353 if (i > topo->num_links) {
354 ret = -ENOSPC;
355 continue;
356 }
357
358 memset(&klink, 0, sizeof(klink));
359
360 /* Copy link fields to userspace struct */
361 klink.id = link->graph_obj.id;
362 klink.source_id = link->gobj0->id;
363 klink.sink_id = link->gobj1->id;
364 klink.flags = link->flags;
365
366 if (copy_to_user(ulink, &klink, sizeof(klink)))
367 ret = -EFAULT;
368 ulink++;
369 }
370 topo->num_links = i;
371
372 return ret;
373}
374
375static long media_device_get_topology(struct media_device *mdev,
376 struct media_v2_topology __user *utopo)
377{
378 struct media_v2_topology ktopo;
379 int ret;
380
381 if (copy_from_user(&ktopo, utopo, sizeof(ktopo)))
382 return -EFAULT;
383
384 ret = __media_device_get_topology(mdev, &ktopo);
385 if (ret < 0)
386 return ret;
387
388 if (copy_to_user(utopo, &ktopo, sizeof(*utopo)))
389 return -EFAULT;
390
391 return 0;
392}
393#endif
394
233static long media_device_ioctl(struct file *filp, unsigned int cmd, 395static long media_device_ioctl(struct file *filp, unsigned int cmd,
234 unsigned long arg) 396 unsigned long arg)
235{ 397{
@@ -262,6 +424,14 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
262 mutex_unlock(&dev->graph_mutex); 424 mutex_unlock(&dev->graph_mutex);
263 break; 425 break;
264 426
427#if 0 /* Let's postpone it to Kernel 4.6 */
428 case MEDIA_IOC_G_TOPOLOGY:
429 mutex_lock(&dev->graph_mutex);
430 ret = media_device_get_topology(dev,
431 (struct media_v2_topology __user *)arg);
432 mutex_unlock(&dev->graph_mutex);
433 break;
434#endif
265 default: 435 default:
266 ret = -ENOIOCTLCMD; 436 ret = -ENOIOCTLCMD;
267 } 437 }
@@ -310,6 +480,9 @@ static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
310 case MEDIA_IOC_DEVICE_INFO: 480 case MEDIA_IOC_DEVICE_INFO:
311 case MEDIA_IOC_ENUM_ENTITIES: 481 case MEDIA_IOC_ENUM_ENTITIES:
312 case MEDIA_IOC_SETUP_LINK: 482 case MEDIA_IOC_SETUP_LINK:
483#if 0 /* Let's postpone it to Kernel 4.6 */
484 case MEDIA_IOC_G_TOPOLOGY:
485#endif
313 return media_device_ioctl(filp, cmd, arg); 486 return media_device_ioctl(filp, cmd, arg);
314 487
315 case MEDIA_IOC_ENUM_LINKS32: 488 case MEDIA_IOC_ENUM_LINKS32:
@@ -357,10 +530,107 @@ static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
357 530
358static void media_device_release(struct media_devnode *mdev) 531static void media_device_release(struct media_devnode *mdev)
359{ 532{
533 dev_dbg(mdev->parent, "Media device released\n");
534}
535
536/**
537 * media_device_register_entity - Register an entity with a media device
538 * @mdev: The media device
539 * @entity: The entity
540 */
541int __must_check media_device_register_entity(struct media_device *mdev,
542 struct media_entity *entity)
543{
544 unsigned int i;
545 int ret;
546
547 if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN ||
548 entity->function == MEDIA_ENT_F_UNKNOWN)
549 dev_warn(mdev->dev,
550 "Entity type for entity %s was not initialized!\n",
551 entity->name);
552
553 /* Warn if we apparently re-register an entity */
554 WARN_ON(entity->graph_obj.mdev != NULL);
555 entity->graph_obj.mdev = mdev;
556 INIT_LIST_HEAD(&entity->links);
557 entity->num_links = 0;
558 entity->num_backlinks = 0;
559
560 if (!ida_pre_get(&mdev->entity_internal_idx, GFP_KERNEL))
561 return -ENOMEM;
562
563 spin_lock(&mdev->lock);
564
565 ret = ida_get_new_above(&mdev->entity_internal_idx, 1,
566 &entity->internal_idx);
567 if (ret < 0) {
568 spin_unlock(&mdev->lock);
569 return ret;
570 }
571
572 mdev->entity_internal_idx_max =
573 max(mdev->entity_internal_idx_max, entity->internal_idx);
574
575 /* Initialize media_gobj embedded at the entity */
576 media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
577
578 /* Initialize objects at the pads */
579 for (i = 0; i < entity->num_pads; i++)
580 media_gobj_create(mdev, MEDIA_GRAPH_PAD,
581 &entity->pads[i].graph_obj);
582
583 spin_unlock(&mdev->lock);
584
585 return 0;
586}
587EXPORT_SYMBOL_GPL(media_device_register_entity);
588
589static void __media_device_unregister_entity(struct media_entity *entity)
590{
591 struct media_device *mdev = entity->graph_obj.mdev;
592 struct media_link *link, *tmp;
593 struct media_interface *intf;
594 unsigned int i;
595
596 ida_simple_remove(&mdev->entity_internal_idx, entity->internal_idx);
597
598 /* Remove all interface links pointing to this entity */
599 list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
600 list_for_each_entry_safe(link, tmp, &intf->links, list) {
601 if (link->entity == entity)
602 __media_remove_intf_link(link);
603 }
604 }
605
606 /* Remove all data links that belong to this entity */
607 __media_entity_remove_links(entity);
608
609 /* Remove all pads that belong to this entity */
610 for (i = 0; i < entity->num_pads; i++)
611 media_gobj_destroy(&entity->pads[i].graph_obj);
612
613 /* Remove the entity */
614 media_gobj_destroy(&entity->graph_obj);
615
616 entity->graph_obj.mdev = NULL;
360} 617}
361 618
619void media_device_unregister_entity(struct media_entity *entity)
620{
621 struct media_device *mdev = entity->graph_obj.mdev;
622
623 if (mdev == NULL)
624 return;
625
626 spin_lock(&mdev->lock);
627 __media_device_unregister_entity(entity);
628 spin_unlock(&mdev->lock);
629}
630EXPORT_SYMBOL_GPL(media_device_unregister_entity);
631
362/** 632/**
363 * media_device_register - register a media device 633 * media_device_init() - initialize a media device
364 * @mdev: The media device 634 * @mdev: The media device
365 * 635 *
366 * The caller is responsible for initializing the media device before 636 * The caller is responsible for initializing the media device before
@@ -369,23 +639,41 @@ static void media_device_release(struct media_devnode *mdev)
369 * - dev must point to the parent device 639 * - dev must point to the parent device
370 * - model must be filled with the device model name 640 * - model must be filled with the device model name
371 */ 641 */
372int __must_check __media_device_register(struct media_device *mdev, 642void media_device_init(struct media_device *mdev)
373 struct module *owner)
374{ 643{
375 int ret;
376
377 if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0))
378 return -EINVAL;
379
380 mdev->entity_id = 1;
381 INIT_LIST_HEAD(&mdev->entities); 644 INIT_LIST_HEAD(&mdev->entities);
645 INIT_LIST_HEAD(&mdev->interfaces);
646 INIT_LIST_HEAD(&mdev->pads);
647 INIT_LIST_HEAD(&mdev->links);
382 spin_lock_init(&mdev->lock); 648 spin_lock_init(&mdev->lock);
383 mutex_init(&mdev->graph_mutex); 649 mutex_init(&mdev->graph_mutex);
650 ida_init(&mdev->entity_internal_idx);
651
652 dev_dbg(mdev->dev, "Media device initialized\n");
653}
654EXPORT_SYMBOL_GPL(media_device_init);
655
656void media_device_cleanup(struct media_device *mdev)
657{
658 ida_destroy(&mdev->entity_internal_idx);
659 mdev->entity_internal_idx_max = 0;
660 mutex_destroy(&mdev->graph_mutex);
661}
662EXPORT_SYMBOL_GPL(media_device_cleanup);
663
664int __must_check __media_device_register(struct media_device *mdev,
665 struct module *owner)
666{
667 int ret;
384 668
385 /* Register the device node. */ 669 /* Register the device node. */
386 mdev->devnode.fops = &media_device_fops; 670 mdev->devnode.fops = &media_device_fops;
387 mdev->devnode.parent = mdev->dev; 671 mdev->devnode.parent = mdev->dev;
388 mdev->devnode.release = media_device_release; 672 mdev->devnode.release = media_device_release;
673
674 /* Set version 0 to indicate user-space that the graph is static */
675 mdev->topology_version = 0;
676
389 ret = media_devnode_register(&mdev->devnode, owner); 677 ret = media_devnode_register(&mdev->devnode, owner);
390 if (ret < 0) 678 if (ret < 0)
391 return ret; 679 return ret;
@@ -396,69 +684,74 @@ int __must_check __media_device_register(struct media_device *mdev,
396 return ret; 684 return ret;
397 } 685 }
398 686
687 dev_dbg(mdev->dev, "Media device registered\n");
688
399 return 0; 689 return 0;
400} 690}
401EXPORT_SYMBOL_GPL(__media_device_register); 691EXPORT_SYMBOL_GPL(__media_device_register);
402 692
403/**
404 * media_device_unregister - unregister a media device
405 * @mdev: The media device
406 *
407 */
408void media_device_unregister(struct media_device *mdev) 693void media_device_unregister(struct media_device *mdev)
409{ 694{
410 struct media_entity *entity; 695 struct media_entity *entity;
411 struct media_entity *next; 696 struct media_entity *next;
697 struct media_interface *intf, *tmp_intf;
412 698
413 list_for_each_entry_safe(entity, next, &mdev->entities, list) 699 if (mdev == NULL)
414 media_device_unregister_entity(entity); 700 return;
701
702 spin_lock(&mdev->lock);
703
704 /* Check if mdev was ever registered at all */
705 if (!media_devnode_is_registered(&mdev->devnode)) {
706 spin_unlock(&mdev->lock);
707 return;
708 }
709
710 /* Remove all entities from the media device */
711 list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
712 __media_device_unregister_entity(entity);
713
714 /* Remove all interfaces from the media device */
715 list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
716 graph_obj.list) {
717 __media_remove_intf_links(intf);
718 media_gobj_destroy(&intf->graph_obj);
719 kfree(intf);
720 }
721
722 spin_unlock(&mdev->lock);
415 723
416 device_remove_file(&mdev->devnode.dev, &dev_attr_model); 724 device_remove_file(&mdev->devnode.dev, &dev_attr_model);
417 media_devnode_unregister(&mdev->devnode); 725 media_devnode_unregister(&mdev->devnode);
726
727 dev_dbg(mdev->dev, "Media device unregistered\n");
418} 728}
419EXPORT_SYMBOL_GPL(media_device_unregister); 729EXPORT_SYMBOL_GPL(media_device_unregister);
420 730
421/** 731static void media_device_release_devres(struct device *dev, void *res)
422 * media_device_register_entity - Register an entity with a media device
423 * @mdev: The media device
424 * @entity: The entity
425 */
426int __must_check media_device_register_entity(struct media_device *mdev,
427 struct media_entity *entity)
428{ 732{
429 /* Warn if we apparently re-register an entity */
430 WARN_ON(entity->parent != NULL);
431 entity->parent = mdev;
432
433 spin_lock(&mdev->lock);
434 if (entity->id == 0)
435 entity->id = mdev->entity_id++;
436 else
437 mdev->entity_id = max(entity->id + 1, mdev->entity_id);
438 list_add_tail(&entity->list, &mdev->entities);
439 spin_unlock(&mdev->lock);
440
441 return 0;
442} 733}
443EXPORT_SYMBOL_GPL(media_device_register_entity);
444 734
445/** 735struct media_device *media_device_get_devres(struct device *dev)
446 * media_device_unregister_entity - Unregister an entity
447 * @entity: The entity
448 *
449 * If the entity has never been registered this function will return
450 * immediately.
451 */
452void media_device_unregister_entity(struct media_entity *entity)
453{ 736{
454 struct media_device *mdev = entity->parent; 737 struct media_device *mdev;
455 738
456 if (mdev == NULL) 739 mdev = devres_find(dev, media_device_release_devres, NULL, NULL);
457 return; 740 if (mdev)
741 return mdev;
458 742
459 spin_lock(&mdev->lock); 743 mdev = devres_alloc(media_device_release_devres,
460 list_del(&entity->list); 744 sizeof(struct media_device), GFP_KERNEL);
461 spin_unlock(&mdev->lock); 745 if (!mdev)
462 entity->parent = NULL; 746 return NULL;
747 return devres_get(dev, mdev, NULL, NULL);
463} 748}
464EXPORT_SYMBOL_GPL(media_device_unregister_entity); 749EXPORT_SYMBOL_GPL(media_device_get_devres);
750
751struct media_device *media_device_find_devres(struct device *dev)
752{
753 return devres_find(dev, media_device_release_devres, NULL, NULL);
754}
755EXPORT_SYMBOL_GPL(media_device_find_devres);
756
757#endif /* CONFIG_MEDIA_CONTROLLER */
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
index ebf9626e5ae5..cea35bf20011 100644
--- a/drivers/media/media-devnode.c
+++ b/drivers/media/media-devnode.c
@@ -217,20 +217,6 @@ static const struct file_operations media_devnode_fops = {
217 .llseek = no_llseek, 217 .llseek = no_llseek,
218}; 218};
219 219
220/**
221 * media_devnode_register - register a media device node
222 * @mdev: media device node structure we want to register
223 *
224 * The registration code assigns minor numbers and registers the new device node
225 * with the kernel. An error is returned if no free minor number can be found,
226 * or if the registration of the device node fails.
227 *
228 * Zero is returned on success.
229 *
230 * Note that if the media_devnode_register call fails, the release() callback of
231 * the media_devnode structure is *not* called, so the caller is responsible for
232 * freeing any data.
233 */
234int __must_check media_devnode_register(struct media_devnode *mdev, 220int __must_check media_devnode_register(struct media_devnode *mdev,
235 struct module *owner) 221 struct module *owner)
236{ 222{
@@ -285,16 +271,6 @@ error:
285 return ret; 271 return ret;
286} 272}
287 273
288/**
289 * media_devnode_unregister - unregister a media device node
290 * @mdev: the device node to unregister
291 *
292 * This unregisters the passed device. Future open calls will be met with
293 * errors.
294 *
295 * This function can safely be called if the device node has never been
296 * registered or has already been unregistered.
297 */
298void media_devnode_unregister(struct media_devnode *mdev) 274void media_devnode_unregister(struct media_devnode *mdev)
299{ 275{
300 /* Check if mdev was ever registered at all */ 276 /* Check if mdev was ever registered at all */
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 767fe55ba08e..e89d85a7d31b 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -26,65 +26,198 @@
26#include <media/media-entity.h> 26#include <media/media-entity.h>
27#include <media/media-device.h> 27#include <media/media-device.h>
28 28
29static inline const char *gobj_type(enum media_gobj_type type)
30{
31 switch (type) {
32 case MEDIA_GRAPH_ENTITY:
33 return "entity";
34 case MEDIA_GRAPH_PAD:
35 return "pad";
36 case MEDIA_GRAPH_LINK:
37 return "link";
38 case MEDIA_GRAPH_INTF_DEVNODE:
39 return "intf-devnode";
40 default:
41 return "unknown";
42 }
43}
44
45static inline const char *intf_type(struct media_interface *intf)
46{
47 switch (intf->type) {
48 case MEDIA_INTF_T_DVB_FE:
49 return "frontend";
50 case MEDIA_INTF_T_DVB_DEMUX:
51 return "demux";
52 case MEDIA_INTF_T_DVB_DVR:
53 return "DVR";
54 case MEDIA_INTF_T_DVB_CA:
55 return "CA";
56 case MEDIA_INTF_T_DVB_NET:
57 return "dvbnet";
58 case MEDIA_INTF_T_V4L_VIDEO:
59 return "video";
60 case MEDIA_INTF_T_V4L_VBI:
61 return "vbi";
62 case MEDIA_INTF_T_V4L_RADIO:
63 return "radio";
64 case MEDIA_INTF_T_V4L_SUBDEV:
65 return "v4l2-subdev";
66 case MEDIA_INTF_T_V4L_SWRADIO:
67 return "swradio";
68 default:
69 return "unknown-intf";
70 }
71};
72
73__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum,
74 int idx_max)
75{
76 ent_enum->bmap = kcalloc(DIV_ROUND_UP(idx_max, BITS_PER_LONG),
77 sizeof(long), GFP_KERNEL);
78 if (!ent_enum->bmap)
79 return -ENOMEM;
80
81 bitmap_zero(ent_enum->bmap, idx_max);
82 ent_enum->idx_max = idx_max;
83
84 return 0;
85}
86EXPORT_SYMBOL_GPL(__media_entity_enum_init);
87
88void media_entity_enum_cleanup(struct media_entity_enum *ent_enum)
89{
90 kfree(ent_enum->bmap);
91}
92EXPORT_SYMBOL_GPL(media_entity_enum_cleanup);
93
29/** 94/**
30 * media_entity_init - Initialize a media entity 95 * dev_dbg_obj - Prints in debug mode a change on some object
31 *
32 * @num_pads: Total number of sink and source pads.
33 * @extra_links: Initial estimate of the number of extra links.
34 * @pads: Array of 'num_pads' pads.
35 *
36 * The total number of pads is an intrinsic property of entities known by the
37 * entity driver, while the total number of links depends on hardware design
38 * and is an extrinsic property unknown to the entity driver. However, in most
39 * use cases the entity driver can guess the number of links which can safely
40 * be assumed to be equal to or larger than the number of pads.
41 *
42 * For those reasons the links array can be preallocated based on the entity
43 * driver guess and will be reallocated later if extra links need to be
44 * created.
45 * 96 *
46 * This function allocates a links array with enough space to hold at least 97 * @event_name: Name of the event to report. Could be __func__
47 * 'num_pads' + 'extra_links' elements. The media_entity::max_links field will 98 * @gobj: Pointer to the object
48 * be set to the number of allocated elements.
49 * 99 *
50 * The pads array is managed by the entity driver and passed to 100 * Enabled only if DEBUG or CONFIG_DYNAMIC_DEBUG. Otherwise, it
51 * media_entity_init() where its pointer will be stored in the entity structure. 101 * won't produce any code.
52 */ 102 */
53int 103static void dev_dbg_obj(const char *event_name, struct media_gobj *gobj)
54media_entity_init(struct media_entity *entity, u16 num_pads,
55 struct media_pad *pads, u16 extra_links)
56{ 104{
57 struct media_link *links; 105#if defined(DEBUG) || defined (CONFIG_DYNAMIC_DEBUG)
58 unsigned int max_links = num_pads + extra_links; 106 switch (media_type(gobj)) {
59 unsigned int i; 107 case MEDIA_GRAPH_ENTITY:
108 dev_dbg(gobj->mdev->dev,
109 "%s id %u: entity '%s'\n",
110 event_name, media_id(gobj),
111 gobj_to_entity(gobj)->name);
112 break;
113 case MEDIA_GRAPH_LINK:
114 {
115 struct media_link *link = gobj_to_link(gobj);
116
117 dev_dbg(gobj->mdev->dev,
118 "%s id %u: %s link id %u ==> id %u\n",
119 event_name, media_id(gobj),
120 media_type(link->gobj0) == MEDIA_GRAPH_PAD ?
121 "data" : "interface",
122 media_id(link->gobj0),
123 media_id(link->gobj1));
124 break;
125 }
126 case MEDIA_GRAPH_PAD:
127 {
128 struct media_pad *pad = gobj_to_pad(gobj);
129
130 dev_dbg(gobj->mdev->dev,
131 "%s id %u: %s%spad '%s':%d\n",
132 event_name, media_id(gobj),
133 pad->flags & MEDIA_PAD_FL_SINK ? "sink " : "",
134 pad->flags & MEDIA_PAD_FL_SOURCE ? "source " : "",
135 pad->entity->name, pad->index);
136 break;
137 }
138 case MEDIA_GRAPH_INTF_DEVNODE:
139 {
140 struct media_interface *intf = gobj_to_intf(gobj);
141 struct media_intf_devnode *devnode = intf_to_devnode(intf);
142
143 dev_dbg(gobj->mdev->dev,
144 "%s id %u: intf_devnode %s - major: %d, minor: %d\n",
145 event_name, media_id(gobj),
146 intf_type(intf),
147 devnode->major, devnode->minor);
148 break;
149 }
150 }
151#endif
152}
60 153
61 links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL); 154void media_gobj_create(struct media_device *mdev,
62 if (links == NULL) 155 enum media_gobj_type type,
63 return -ENOMEM; 156 struct media_gobj *gobj)
157{
158 BUG_ON(!mdev);
159
160 gobj->mdev = mdev;
161
162 /* Create a per-type unique object ID */
163 gobj->id = media_gobj_gen_id(type, ++mdev->id);
164
165 switch (type) {
166 case MEDIA_GRAPH_ENTITY:
167 list_add_tail(&gobj->list, &mdev->entities);
168 break;
169 case MEDIA_GRAPH_PAD:
170 list_add_tail(&gobj->list, &mdev->pads);
171 break;
172 case MEDIA_GRAPH_LINK:
173 list_add_tail(&gobj->list, &mdev->links);
174 break;
175 case MEDIA_GRAPH_INTF_DEVNODE:
176 list_add_tail(&gobj->list, &mdev->interfaces);
177 break;
178 }
179
180 mdev->topology_version++;
181
182 dev_dbg_obj(__func__, gobj);
183}
184
185void media_gobj_destroy(struct media_gobj *gobj)
186{
187 dev_dbg_obj(__func__, gobj);
188
189 gobj->mdev->topology_version++;
190
191 /* Remove the object from mdev list */
192 list_del(&gobj->list);
193}
194
195int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
196 struct media_pad *pads)
197{
198 struct media_device *mdev = entity->graph_obj.mdev;
199 unsigned int i;
64 200
65 entity->group_id = 0;
66 entity->max_links = max_links;
67 entity->num_links = 0;
68 entity->num_backlinks = 0;
69 entity->num_pads = num_pads; 201 entity->num_pads = num_pads;
70 entity->pads = pads; 202 entity->pads = pads;
71 entity->links = links; 203
204 if (mdev)
205 spin_lock(&mdev->lock);
72 206
73 for (i = 0; i < num_pads; i++) { 207 for (i = 0; i < num_pads; i++) {
74 pads[i].entity = entity; 208 pads[i].entity = entity;
75 pads[i].index = i; 209 pads[i].index = i;
210 if (mdev)
211 media_gobj_create(mdev, MEDIA_GRAPH_PAD,
212 &entity->pads[i].graph_obj);
76 } 213 }
77 214
78 return 0; 215 if (mdev)
79} 216 spin_unlock(&mdev->lock);
80EXPORT_SYMBOL_GPL(media_entity_init);
81 217
82void 218 return 0;
83media_entity_cleanup(struct media_entity *entity)
84{
85 kfree(entity->links);
86} 219}
87EXPORT_SYMBOL_GPL(media_entity_cleanup); 220EXPORT_SYMBOL_GPL(media_entity_pads_init);
88 221
89/* ----------------------------------------------------------------------------- 222/* -----------------------------------------------------------------------------
90 * Graph traversal 223 * Graph traversal
@@ -108,7 +241,7 @@ static void stack_push(struct media_entity_graph *graph,
108 return; 241 return;
109 } 242 }
110 graph->top++; 243 graph->top++;
111 graph->stack[graph->top].link = 0; 244 graph->stack[graph->top].link = entity->links.next;
112 graph->stack[graph->top].entity = entity; 245 graph->stack[graph->top].entity = entity;
113} 246}
114 247
@@ -125,43 +258,51 @@ static struct media_entity *stack_pop(struct media_entity_graph *graph)
125#define link_top(en) ((en)->stack[(en)->top].link) 258#define link_top(en) ((en)->stack[(en)->top].link)
126#define stack_top(en) ((en)->stack[(en)->top].entity) 259#define stack_top(en) ((en)->stack[(en)->top].entity)
127 260
261/*
262 * TODO: Get rid of this.
263 */
264#define MEDIA_ENTITY_MAX_PADS 512
265
128/** 266/**
129 * media_entity_graph_walk_start - Start walking the media graph at a given entity 267 * media_entity_graph_walk_init - Allocate resources for graph walk
130 * @graph: Media graph structure that will be used to walk the graph 268 * @graph: Media graph structure that will be used to walk the graph
131 * @entity: Starting entity 269 * @mdev: Media device
132 * 270 *
133 * This function initializes the graph traversal structure to walk the entities 271 * Reserve resources for graph walk in media device's current
134 * graph starting at the given entity. The traversal structure must not be 272 * state. The memory must be released using
135 * modified by the caller during graph traversal. When done the structure can 273 * media_entity_graph_walk_free().
136 * safely be freed. 274 *
275 * Returns error on failure, zero on success.
137 */ 276 */
277__must_check int media_entity_graph_walk_init(
278 struct media_entity_graph *graph, struct media_device *mdev)
279{
280 return media_entity_enum_init(&graph->ent_enum, mdev);
281}
282EXPORT_SYMBOL_GPL(media_entity_graph_walk_init);
283
284/**
285 * media_entity_graph_walk_cleanup - Release resources related to graph walking
286 * @graph: Media graph structure that was used to walk the graph
287 */
288void media_entity_graph_walk_cleanup(struct media_entity_graph *graph)
289{
290 media_entity_enum_cleanup(&graph->ent_enum);
291}
292EXPORT_SYMBOL_GPL(media_entity_graph_walk_cleanup);
293
138void media_entity_graph_walk_start(struct media_entity_graph *graph, 294void media_entity_graph_walk_start(struct media_entity_graph *graph,
139 struct media_entity *entity) 295 struct media_entity *entity)
140{ 296{
297 media_entity_enum_zero(&graph->ent_enum);
298 media_entity_enum_set(&graph->ent_enum, entity);
299
141 graph->top = 0; 300 graph->top = 0;
142 graph->stack[graph->top].entity = NULL; 301 graph->stack[graph->top].entity = NULL;
143 bitmap_zero(graph->entities, MEDIA_ENTITY_ENUM_MAX_ID);
144
145 if (WARN_ON(entity->id >= MEDIA_ENTITY_ENUM_MAX_ID))
146 return;
147
148 __set_bit(entity->id, graph->entities);
149 stack_push(graph, entity); 302 stack_push(graph, entity);
150} 303}
151EXPORT_SYMBOL_GPL(media_entity_graph_walk_start); 304EXPORT_SYMBOL_GPL(media_entity_graph_walk_start);
152 305
153/**
154 * media_entity_graph_walk_next - Get the next entity in the graph
155 * @graph: Media graph structure
156 *
157 * Perform a depth-first traversal of the given media entities graph.
158 *
159 * The graph structure must have been previously initialized with a call to
160 * media_entity_graph_walk_start().
161 *
162 * Return the next entity in the graph or NULL if the whole graph have been
163 * traversed.
164 */
165struct media_entity * 306struct media_entity *
166media_entity_graph_walk_next(struct media_entity_graph *graph) 307media_entity_graph_walk_next(struct media_entity_graph *graph)
167{ 308{
@@ -173,30 +314,30 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
173 * top of the stack until no more entities on the level can be 314 * top of the stack until no more entities on the level can be
174 * found. 315 * found.
175 */ 316 */
176 while (link_top(graph) < stack_top(graph)->num_links) { 317 while (link_top(graph) != &stack_top(graph)->links) {
177 struct media_entity *entity = stack_top(graph); 318 struct media_entity *entity = stack_top(graph);
178 struct media_link *link = &entity->links[link_top(graph)]; 319 struct media_link *link;
179 struct media_entity *next; 320 struct media_entity *next;
180 321
322 link = list_entry(link_top(graph), typeof(*link), list);
323
181 /* The link is not enabled so we do not follow. */ 324 /* The link is not enabled so we do not follow. */
182 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { 325 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
183 link_top(graph)++; 326 link_top(graph) = link_top(graph)->next;
184 continue; 327 continue;
185 } 328 }
186 329
187 /* Get the entity in the other end of the link . */ 330 /* Get the entity in the other end of the link . */
188 next = media_entity_other(entity, link); 331 next = media_entity_other(entity, link);
189 if (WARN_ON(next->id >= MEDIA_ENTITY_ENUM_MAX_ID))
190 return NULL;
191 332
192 /* Has the entity already been visited? */ 333 /* Has the entity already been visited? */
193 if (__test_and_set_bit(next->id, graph->entities)) { 334 if (media_entity_enum_test_and_set(&graph->ent_enum, next)) {
194 link_top(graph)++; 335 link_top(graph) = link_top(graph)->next;
195 continue; 336 continue;
196 } 337 }
197 338
198 /* Push the new entity to stack and start over. */ 339 /* Push the new entity to stack and start over. */
199 link_top(graph)++; 340 link_top(graph) = link_top(graph)->next;
200 stack_push(graph, next); 341 stack_push(graph, next);
201 } 342 }
202 343
@@ -208,39 +349,36 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
208 * Pipeline management 349 * Pipeline management
209 */ 350 */
210 351
211/**
212 * media_entity_pipeline_start - Mark a pipeline as streaming
213 * @entity: Starting entity
214 * @pipe: Media pipeline to be assigned to all entities in the pipeline.
215 *
216 * Mark all entities connected to a given entity through enabled links, either
217 * directly or indirectly, as streaming. The given pipeline object is assigned to
218 * every entity in the pipeline and stored in the media_entity pipe field.
219 *
220 * Calls to this function can be nested, in which case the same number of
221 * media_entity_pipeline_stop() calls will be required to stop streaming. The
222 * pipeline pointer must be identical for all nested calls to
223 * media_entity_pipeline_start().
224 */
225__must_check int media_entity_pipeline_start(struct media_entity *entity, 352__must_check int media_entity_pipeline_start(struct media_entity *entity,
226 struct media_pipeline *pipe) 353 struct media_pipeline *pipe)
227{ 354{
228 struct media_device *mdev = entity->parent; 355 struct media_device *mdev = entity->graph_obj.mdev;
229 struct media_entity_graph graph; 356 struct media_entity_graph *graph = &pipe->graph;
230 struct media_entity *entity_err = entity; 357 struct media_entity *entity_err = entity;
358 struct media_link *link;
231 int ret; 359 int ret;
232 360
233 mutex_lock(&mdev->graph_mutex); 361 mutex_lock(&mdev->graph_mutex);
234 362
235 media_entity_graph_walk_start(&graph, entity); 363 if (!pipe->streaming_count++) {
364 ret = media_entity_graph_walk_init(&pipe->graph, mdev);
365 if (ret)
366 goto error_graph_walk_start;
367 }
368
369 media_entity_graph_walk_start(&pipe->graph, entity);
236 370
237 while ((entity = media_entity_graph_walk_next(&graph))) { 371 while ((entity = media_entity_graph_walk_next(graph))) {
238 DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); 372 DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS);
239 DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); 373 DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS);
240 unsigned int i;
241 374
242 entity->stream_count++; 375 entity->stream_count++;
243 WARN_ON(entity->pipe && entity->pipe != pipe); 376
377 if (WARN_ON(entity->pipe && entity->pipe != pipe)) {
378 ret = -EBUSY;
379 goto error;
380 }
381
244 entity->pipe = pipe; 382 entity->pipe = pipe;
245 383
246 /* Already streaming --- no need to check. */ 384 /* Already streaming --- no need to check. */
@@ -253,8 +391,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
253 bitmap_zero(active, entity->num_pads); 391 bitmap_zero(active, entity->num_pads);
254 bitmap_fill(has_no_links, entity->num_pads); 392 bitmap_fill(has_no_links, entity->num_pads);
255 393
256 for (i = 0; i < entity->num_links; i++) { 394 list_for_each_entry(link, &entity->links, list) {
257 struct media_link *link = &entity->links[i];
258 struct media_pad *pad = link->sink->entity == entity 395 struct media_pad *pad = link->sink->entity == entity
259 ? link->sink : link->source; 396 ? link->sink : link->source;
260 397
@@ -280,7 +417,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
280 417
281 ret = entity->ops->link_validate(link); 418 ret = entity->ops->link_validate(link);
282 if (ret < 0 && ret != -ENOIOCTLCMD) { 419 if (ret < 0 && ret != -ENOIOCTLCMD) {
283 dev_dbg(entity->parent->dev, 420 dev_dbg(entity->graph_obj.mdev->dev,
284 "link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n", 421 "link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
285 link->source->entity->name, 422 link->source->entity->name,
286 link->source->index, 423 link->source->index,
@@ -294,7 +431,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
294 431
295 if (!bitmap_full(active, entity->num_pads)) { 432 if (!bitmap_full(active, entity->num_pads)) {
296 ret = -EPIPE; 433 ret = -EPIPE;
297 dev_dbg(entity->parent->dev, 434 dev_dbg(entity->graph_obj.mdev->dev,
298 "\"%s\":%u must be connected by an enabled link\n", 435 "\"%s\":%u must be connected by an enabled link\n",
299 entity->name, 436 entity->name,
300 (unsigned)find_first_zero_bit( 437 (unsigned)find_first_zero_bit(
@@ -312,9 +449,9 @@ error:
312 * Link validation on graph failed. We revert what we did and 449 * Link validation on graph failed. We revert what we did and
313 * return the error. 450 * return the error.
314 */ 451 */
315 media_entity_graph_walk_start(&graph, entity_err); 452 media_entity_graph_walk_start(graph, entity_err);
316 453
317 while ((entity_err = media_entity_graph_walk_next(&graph))) { 454 while ((entity_err = media_entity_graph_walk_next(graph))) {
318 entity_err->stream_count--; 455 entity_err->stream_count--;
319 if (entity_err->stream_count == 0) 456 if (entity_err->stream_count == 0)
320 entity_err->pipe = NULL; 457 entity_err->pipe = NULL;
@@ -327,39 +464,36 @@ error:
327 break; 464 break;
328 } 465 }
329 466
467error_graph_walk_start:
468 if (!--pipe->streaming_count)
469 media_entity_graph_walk_cleanup(graph);
470
330 mutex_unlock(&mdev->graph_mutex); 471 mutex_unlock(&mdev->graph_mutex);
331 472
332 return ret; 473 return ret;
333} 474}
334EXPORT_SYMBOL_GPL(media_entity_pipeline_start); 475EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
335 476
336/**
337 * media_entity_pipeline_stop - Mark a pipeline as not streaming
338 * @entity: Starting entity
339 *
340 * Mark all entities connected to a given entity through enabled links, either
341 * directly or indirectly, as not streaming. The media_entity pipe field is
342 * reset to NULL.
343 *
344 * If multiple calls to media_entity_pipeline_start() have been made, the same
345 * number of calls to this function are required to mark the pipeline as not
346 * streaming.
347 */
348void media_entity_pipeline_stop(struct media_entity *entity) 477void media_entity_pipeline_stop(struct media_entity *entity)
349{ 478{
350 struct media_device *mdev = entity->parent; 479 struct media_device *mdev = entity->graph_obj.mdev;
351 struct media_entity_graph graph; 480 struct media_entity_graph *graph = &entity->pipe->graph;
481 struct media_pipeline *pipe = entity->pipe;
352 482
353 mutex_lock(&mdev->graph_mutex); 483 mutex_lock(&mdev->graph_mutex);
354 484
355 media_entity_graph_walk_start(&graph, entity); 485 WARN_ON(!pipe->streaming_count);
486 media_entity_graph_walk_start(graph, entity);
356 487
357 while ((entity = media_entity_graph_walk_next(&graph))) { 488 while ((entity = media_entity_graph_walk_next(graph))) {
358 entity->stream_count--; 489 entity->stream_count--;
359 if (entity->stream_count == 0) 490 if (entity->stream_count == 0)
360 entity->pipe = NULL; 491 entity->pipe = NULL;
361 } 492 }
362 493
494 if (!--pipe->streaming_count)
495 media_entity_graph_walk_cleanup(graph);
496
363 mutex_unlock(&mdev->graph_mutex); 497 mutex_unlock(&mdev->graph_mutex);
364} 498}
365EXPORT_SYMBOL_GPL(media_entity_pipeline_stop); 499EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
@@ -368,44 +502,26 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
368 * Module use count 502 * Module use count
369 */ 503 */
370 504
371/*
372 * media_entity_get - Get a reference to the parent module
373 * @entity: The entity
374 *
375 * Get a reference to the parent media device module.
376 *
377 * The function will return immediately if @entity is NULL.
378 *
379 * Return a pointer to the entity on success or NULL on failure.
380 */
381struct media_entity *media_entity_get(struct media_entity *entity) 505struct media_entity *media_entity_get(struct media_entity *entity)
382{ 506{
383 if (entity == NULL) 507 if (entity == NULL)
384 return NULL; 508 return NULL;
385 509
386 if (entity->parent->dev && 510 if (entity->graph_obj.mdev->dev &&
387 !try_module_get(entity->parent->dev->driver->owner)) 511 !try_module_get(entity->graph_obj.mdev->dev->driver->owner))
388 return NULL; 512 return NULL;
389 513
390 return entity; 514 return entity;
391} 515}
392EXPORT_SYMBOL_GPL(media_entity_get); 516EXPORT_SYMBOL_GPL(media_entity_get);
393 517
394/*
395 * media_entity_put - Release the reference to the parent module
396 * @entity: The entity
397 *
398 * Release the reference count acquired by media_entity_get().
399 *
400 * The function will return immediately if @entity is NULL.
401 */
402void media_entity_put(struct media_entity *entity) 518void media_entity_put(struct media_entity *entity)
403{ 519{
404 if (entity == NULL) 520 if (entity == NULL)
405 return; 521 return;
406 522
407 if (entity->parent->dev) 523 if (entity->graph_obj.mdev->dev)
408 module_put(entity->parent->dev->driver->owner); 524 module_put(entity->graph_obj.mdev->dev->driver->owner);
409} 525}
410EXPORT_SYMBOL_GPL(media_entity_put); 526EXPORT_SYMBOL_GPL(media_entity_put);
411 527
@@ -413,29 +529,52 @@ EXPORT_SYMBOL_GPL(media_entity_put);
413 * Links management 529 * Links management
414 */ 530 */
415 531
416static struct media_link *media_entity_add_link(struct media_entity *entity) 532static struct media_link *media_add_link(struct list_head *head)
417{ 533{
418 if (entity->num_links >= entity->max_links) { 534 struct media_link *link;
419 struct media_link *links = entity->links; 535
420 unsigned int max_links = entity->max_links + 2; 536 link = kzalloc(sizeof(*link), GFP_KERNEL);
421 unsigned int i; 537 if (link == NULL)
538 return NULL;
422 539
423 links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL); 540 list_add_tail(&link->list, head);
424 if (links == NULL)
425 return NULL;
426 541
427 for (i = 0; i < entity->num_links; i++) 542 return link;
428 links[i].reverse->reverse = &links[i]; 543}
429 544
430 entity->max_links = max_links; 545static void __media_entity_remove_link(struct media_entity *entity,
431 entity->links = links; 546 struct media_link *link)
432 } 547{
548 struct media_link *rlink, *tmp;
549 struct media_entity *remote;
550
551 if (link->source->entity == entity)
552 remote = link->sink->entity;
553 else
554 remote = link->source->entity;
433 555
434 return &entity->links[entity->num_links++]; 556 list_for_each_entry_safe(rlink, tmp, &remote->links, list) {
557 if (rlink != link->reverse)
558 continue;
559
560 if (link->source->entity == entity)
561 remote->num_backlinks--;
562
563 /* Remove the remote link */
564 list_del(&rlink->list);
565 media_gobj_destroy(&rlink->graph_obj);
566 kfree(rlink);
567
568 if (--remote->num_links == 0)
569 break;
570 }
571 list_del(&link->list);
572 media_gobj_destroy(&link->graph_obj);
573 kfree(link);
435} 574}
436 575
437int 576int
438media_entity_create_link(struct media_entity *source, u16 source_pad, 577media_create_pad_link(struct media_entity *source, u16 source_pad,
439 struct media_entity *sink, u16 sink_pad, u32 flags) 578 struct media_entity *sink, u16 sink_pad, u32 flags)
440{ 579{
441 struct media_link *link; 580 struct media_link *link;
@@ -445,68 +584,118 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
445 BUG_ON(source_pad >= source->num_pads); 584 BUG_ON(source_pad >= source->num_pads);
446 BUG_ON(sink_pad >= sink->num_pads); 585 BUG_ON(sink_pad >= sink->num_pads);
447 586
448 link = media_entity_add_link(source); 587 link = media_add_link(&source->links);
449 if (link == NULL) 588 if (link == NULL)
450 return -ENOMEM; 589 return -ENOMEM;
451 590
452 link->source = &source->pads[source_pad]; 591 link->source = &source->pads[source_pad];
453 link->sink = &sink->pads[sink_pad]; 592 link->sink = &sink->pads[sink_pad];
454 link->flags = flags; 593 link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK;
594
595 /* Initialize graph object embedded at the new link */
596 media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
597 &link->graph_obj);
455 598
456 /* Create the backlink. Backlinks are used to help graph traversal and 599 /* Create the backlink. Backlinks are used to help graph traversal and
457 * are not reported to userspace. 600 * are not reported to userspace.
458 */ 601 */
459 backlink = media_entity_add_link(sink); 602 backlink = media_add_link(&sink->links);
460 if (backlink == NULL) { 603 if (backlink == NULL) {
461 source->num_links--; 604 __media_entity_remove_link(source, link);
462 return -ENOMEM; 605 return -ENOMEM;
463 } 606 }
464 607
465 backlink->source = &source->pads[source_pad]; 608 backlink->source = &source->pads[source_pad];
466 backlink->sink = &sink->pads[sink_pad]; 609 backlink->sink = &sink->pads[sink_pad];
467 backlink->flags = flags; 610 backlink->flags = flags;
611 backlink->is_backlink = true;
612
613 /* Initialize graph object embedded at the new link */
614 media_gobj_create(sink->graph_obj.mdev, MEDIA_GRAPH_LINK,
615 &backlink->graph_obj);
468 616
469 link->reverse = backlink; 617 link->reverse = backlink;
470 backlink->reverse = link; 618 backlink->reverse = link;
471 619
472 sink->num_backlinks++; 620 sink->num_backlinks++;
621 sink->num_links++;
622 source->num_links++;
473 623
474 return 0; 624 return 0;
475} 625}
476EXPORT_SYMBOL_GPL(media_entity_create_link); 626EXPORT_SYMBOL_GPL(media_create_pad_link);
477 627
478void __media_entity_remove_links(struct media_entity *entity) 628int media_create_pad_links(const struct media_device *mdev,
629 const u32 source_function,
630 struct media_entity *source,
631 const u16 source_pad,
632 const u32 sink_function,
633 struct media_entity *sink,
634 const u16 sink_pad,
635 u32 flags,
636 const bool allow_both_undefined)
479{ 637{
480 unsigned int i; 638 struct media_entity *entity;
481 639 unsigned function;
482 for (i = 0; i < entity->num_links; i++) { 640 int ret;
483 struct media_link *link = &entity->links[i];
484 struct media_entity *remote;
485 unsigned int r = 0;
486
487 if (link->source->entity == entity)
488 remote = link->sink->entity;
489 else
490 remote = link->source->entity;
491
492 while (r < remote->num_links) {
493 struct media_link *rlink = &remote->links[r];
494 641
495 if (rlink != link->reverse) { 642 /* Trivial case: 1:1 relation */
496 r++; 643 if (source && sink)
644 return media_create_pad_link(source, source_pad,
645 sink, sink_pad, flags);
646
647 /* Worse case scenario: n:n relation */
648 if (!source && !sink) {
649 if (!allow_both_undefined)
650 return 0;
651 media_device_for_each_entity(source, mdev) {
652 if (source->function != source_function)
497 continue; 653 continue;
654 media_device_for_each_entity(sink, mdev) {
655 if (sink->function != sink_function)
656 continue;
657 ret = media_create_pad_link(source, source_pad,
658 sink, sink_pad,
659 flags);
660 if (ret)
661 return ret;
662 flags &= ~(MEDIA_LNK_FL_ENABLED |
663 MEDIA_LNK_FL_IMMUTABLE);
498 } 664 }
665 }
666 return 0;
667 }
499 668
500 if (link->source->entity == entity) 669 /* Handle 1:n and n:1 cases */
501 remote->num_backlinks--; 670 if (source)
671 function = sink_function;
672 else
673 function = source_function;
502 674
503 if (--remote->num_links == 0) 675 media_device_for_each_entity(entity, mdev) {
504 break; 676 if (entity->function != function)
677 continue;
505 678
506 /* Insert last entry in place of the dropped link. */ 679 if (source)
507 *rlink = remote->links[remote->num_links]; 680 ret = media_create_pad_link(source, source_pad,
508 } 681 entity, sink_pad, flags);
682 else
683 ret = media_create_pad_link(entity, source_pad,
684 sink, sink_pad, flags);
685 if (ret)
686 return ret;
687 flags &= ~(MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
509 } 688 }
689 return 0;
690}
691EXPORT_SYMBOL_GPL(media_create_pad_links);
692
693void __media_entity_remove_links(struct media_entity *entity)
694{
695 struct media_link *link, *tmp;
696
697 list_for_each_entry_safe(link, tmp, &entity->links, list)
698 __media_entity_remove_link(entity, link);
510 699
511 entity->num_links = 0; 700 entity->num_links = 0;
512 entity->num_backlinks = 0; 701 entity->num_backlinks = 0;
@@ -515,13 +704,15 @@ EXPORT_SYMBOL_GPL(__media_entity_remove_links);
515 704
516void media_entity_remove_links(struct media_entity *entity) 705void media_entity_remove_links(struct media_entity *entity)
517{ 706{
707 struct media_device *mdev = entity->graph_obj.mdev;
708
518 /* Do nothing if the entity is not registered. */ 709 /* Do nothing if the entity is not registered. */
519 if (entity->parent == NULL) 710 if (mdev == NULL)
520 return; 711 return;
521 712
522 mutex_lock(&entity->parent->graph_mutex); 713 spin_lock(&mdev->lock);
523 __media_entity_remove_links(entity); 714 __media_entity_remove_links(entity);
524 mutex_unlock(&entity->parent->graph_mutex); 715 spin_unlock(&mdev->lock);
525} 716}
526EXPORT_SYMBOL_GPL(media_entity_remove_links); 717EXPORT_SYMBOL_GPL(media_entity_remove_links);
527 718
@@ -549,20 +740,6 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
549 return 0; 740 return 0;
550} 741}
551 742
552/**
553 * __media_entity_setup_link - Configure a media link
554 * @link: The link being configured
555 * @flags: Link configuration flags
556 *
557 * The bulk of link setup is handled by the two entities connected through the
558 * link. This function notifies both entities of the link configuration change.
559 *
560 * If the link is immutable or if the current and new configuration are
561 * identical, return immediately.
562 *
563 * The user is expected to hold link->source->parent->mutex. If not,
564 * media_entity_setup_link() should be used instead.
565 */
566int __media_entity_setup_link(struct media_link *link, u32 flags) 743int __media_entity_setup_link(struct media_link *link, u32 flags)
567{ 744{
568 const u32 mask = MEDIA_LNK_FL_ENABLED; 745 const u32 mask = MEDIA_LNK_FL_ENABLED;
@@ -590,7 +767,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
590 (source->stream_count || sink->stream_count)) 767 (source->stream_count || sink->stream_count))
591 return -EBUSY; 768 return -EBUSY;
592 769
593 mdev = source->parent; 770 mdev = source->graph_obj.mdev;
594 771
595 if (mdev->link_notify) { 772 if (mdev->link_notify) {
596 ret = mdev->link_notify(link, flags, 773 ret = mdev->link_notify(link, flags,
@@ -611,31 +788,20 @@ int media_entity_setup_link(struct media_link *link, u32 flags)
611{ 788{
612 int ret; 789 int ret;
613 790
614 mutex_lock(&link->source->entity->parent->graph_mutex); 791 mutex_lock(&link->graph_obj.mdev->graph_mutex);
615 ret = __media_entity_setup_link(link, flags); 792 ret = __media_entity_setup_link(link, flags);
616 mutex_unlock(&link->source->entity->parent->graph_mutex); 793 mutex_unlock(&link->graph_obj.mdev->graph_mutex);
617 794
618 return ret; 795 return ret;
619} 796}
620EXPORT_SYMBOL_GPL(media_entity_setup_link); 797EXPORT_SYMBOL_GPL(media_entity_setup_link);
621 798
622/**
623 * media_entity_find_link - Find a link between two pads
624 * @source: Source pad
625 * @sink: Sink pad
626 *
627 * Return a pointer to the link between the two entities. If no such link
628 * exists, return NULL.
629 */
630struct media_link * 799struct media_link *
631media_entity_find_link(struct media_pad *source, struct media_pad *sink) 800media_entity_find_link(struct media_pad *source, struct media_pad *sink)
632{ 801{
633 struct media_link *link; 802 struct media_link *link;
634 unsigned int i;
635
636 for (i = 0; i < source->entity->num_links; ++i) {
637 link = &source->entity->links[i];
638 803
804 list_for_each_entry(link, &source->entity->links, list) {
639 if (link->source->entity == source->entity && 805 if (link->source->entity == source->entity &&
640 link->source->index == source->index && 806 link->source->index == source->index &&
641 link->sink->entity == sink->entity && 807 link->sink->entity == sink->entity &&
@@ -647,23 +813,11 @@ media_entity_find_link(struct media_pad *source, struct media_pad *sink)
647} 813}
648EXPORT_SYMBOL_GPL(media_entity_find_link); 814EXPORT_SYMBOL_GPL(media_entity_find_link);
649 815
650/**
651 * media_entity_remote_pad - Find the pad at the remote end of a link
652 * @pad: Pad at the local end of the link
653 *
654 * Search for a remote pad connected to the given pad by iterating over all
655 * links originating or terminating at that pad until an enabled link is found.
656 *
657 * Return a pointer to the pad at the remote end of the first found enabled
658 * link, or NULL if no enabled link has been found.
659 */
660struct media_pad *media_entity_remote_pad(struct media_pad *pad) 816struct media_pad *media_entity_remote_pad(struct media_pad *pad)
661{ 817{
662 unsigned int i; 818 struct media_link *link;
663
664 for (i = 0; i < pad->entity->num_links; i++) {
665 struct media_link *link = &pad->entity->links[i];
666 819
820 list_for_each_entry(link, &pad->entity->links, list) {
667 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) 821 if (!(link->flags & MEDIA_LNK_FL_ENABLED))
668 continue; 822 continue;
669 823
@@ -678,3 +832,113 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad)
678 832
679} 833}
680EXPORT_SYMBOL_GPL(media_entity_remote_pad); 834EXPORT_SYMBOL_GPL(media_entity_remote_pad);
835
836static void media_interface_init(struct media_device *mdev,
837 struct media_interface *intf,
838 u32 gobj_type,
839 u32 intf_type, u32 flags)
840{
841 intf->type = intf_type;
842 intf->flags = flags;
843 INIT_LIST_HEAD(&intf->links);
844
845 media_gobj_create(mdev, gobj_type, &intf->graph_obj);
846}
847
848/* Functions related to the media interface via device nodes */
849
850struct media_intf_devnode *media_devnode_create(struct media_device *mdev,
851 u32 type, u32 flags,
852 u32 major, u32 minor)
853{
854 struct media_intf_devnode *devnode;
855
856 devnode = kzalloc(sizeof(*devnode), GFP_KERNEL);
857 if (!devnode)
858 return NULL;
859
860 devnode->major = major;
861 devnode->minor = minor;
862
863 media_interface_init(mdev, &devnode->intf, MEDIA_GRAPH_INTF_DEVNODE,
864 type, flags);
865
866 return devnode;
867}
868EXPORT_SYMBOL_GPL(media_devnode_create);
869
870void media_devnode_remove(struct media_intf_devnode *devnode)
871{
872 media_remove_intf_links(&devnode->intf);
873 media_gobj_destroy(&devnode->intf.graph_obj);
874 kfree(devnode);
875}
876EXPORT_SYMBOL_GPL(media_devnode_remove);
877
878struct media_link *media_create_intf_link(struct media_entity *entity,
879 struct media_interface *intf,
880 u32 flags)
881{
882 struct media_link *link;
883
884 link = media_add_link(&intf->links);
885 if (link == NULL)
886 return NULL;
887
888 link->intf = intf;
889 link->entity = entity;
890 link->flags = flags | MEDIA_LNK_FL_INTERFACE_LINK;
891
892 /* Initialize graph object embedded at the new link */
893 media_gobj_create(intf->graph_obj.mdev, MEDIA_GRAPH_LINK,
894 &link->graph_obj);
895
896 return link;
897}
898EXPORT_SYMBOL_GPL(media_create_intf_link);
899
900void __media_remove_intf_link(struct media_link *link)
901{
902 list_del(&link->list);
903 media_gobj_destroy(&link->graph_obj);
904 kfree(link);
905}
906EXPORT_SYMBOL_GPL(__media_remove_intf_link);
907
908void media_remove_intf_link(struct media_link *link)
909{
910 struct media_device *mdev = link->graph_obj.mdev;
911
912 /* Do nothing if the intf is not registered. */
913 if (mdev == NULL)
914 return;
915
916 spin_lock(&mdev->lock);
917 __media_remove_intf_link(link);
918 spin_unlock(&mdev->lock);
919}
920EXPORT_SYMBOL_GPL(media_remove_intf_link);
921
922void __media_remove_intf_links(struct media_interface *intf)
923{
924 struct media_link *link, *tmp;
925
926 list_for_each_entry_safe(link, tmp, &intf->links, list)
927 __media_remove_intf_link(link);
928
929}
930EXPORT_SYMBOL_GPL(__media_remove_intf_links);
931
932void media_remove_intf_links(struct media_interface *intf)
933{
934 struct media_device *mdev = intf->graph_obj.mdev;
935
936 /* Do nothing if the intf is not registered. */
937 if (mdev == NULL)
938 return;
939
940 spin_lock(&mdev->lock);
941 __media_remove_intf_links(intf);
942 spin_unlock(&mdev->lock);
943}
944EXPORT_SYMBOL_GPL(media_remove_intf_links);
diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
index c5cc14ef8347..da8b414fd824 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_
705 struct dvb_device *dvbdev; 705 struct dvb_device *dvbdev;
706 706
707 dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device"); 707 dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device");
708 if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) { 708 if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst,
709 DVB_DEVICE_CA, 0) == 0) {
709 dst->dst_ca = dvbdev; 710 dst->dst_ca = dvbdev;
710 return dst->dst_ca; 711 return dst->dst_ca;
711 } 712 }
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index fba5b40a869c..9d5b314142f1 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)
1065 port->en, 0, 1); 1065 port->en, 0, 1);
1066 ret = dvb_register_device(&port->output->adap, &port->output->dev, 1066 ret = dvb_register_device(&port->output->adap, &port->output->dev,
1067 &dvbdev_ci, (void *) port->output, 1067 &dvbdev_ci, (void *) port->output,
1068 DVB_DEVICE_SEC); 1068 DVB_DEVICE_SEC, 0);
1069 return ret; 1069 return ret;
1070} 1070}
1071 1071
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)
1513 set_transfer(&chan->dev->channel[2], 1); 1513 set_transfer(&chan->dev->channel[2], 1);
1514 dvb_register_device(adapter, &chan->ci_dev, 1514 dvb_register_device(adapter, &chan->ci_dev,
1515 &ngene_dvbdev_ci, (void *) chan, 1515 &ngene_dvbdev_ci, (void *) chan,
1516 DVB_DEVICE_SEC); 1516 DVB_DEVICE_SEC, 0);
1517 if (!chan->ci_dev) 1517 if (!chan->ci_dev)
1518 goto err; 1518 goto err;
1519 } 1519 }
diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c
index 5e18b6796ed9..a69dc6a0752b 100644
--- a/drivers/media/pci/ttpci/av7110.c
+++ b/drivers/media/pci/ttpci/av7110.c
@@ -1358,7 +1358,7 @@ static int av7110_register(struct av7110 *av7110)
1358 1358
1359#ifdef CONFIG_DVB_AV7110_OSD 1359#ifdef CONFIG_DVB_AV7110_OSD
1360 dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev, 1360 dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
1361 &dvbdev_osd, av7110, DVB_DEVICE_OSD); 1361 &dvbdev_osd, av7110, DVB_DEVICE_OSD, 0);
1362#endif 1362#endif
1363 1363
1364 dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); 1364 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 6fc748e22017..26c5696c193b 100644
--- a/drivers/media/pci/ttpci/av7110_av.c
+++ b/drivers/media/pci/ttpci/av7110_av.c
@@ -1594,10 +1594,10 @@ int av7110_av_register(struct av7110 *av7110)
1594 memset(&av7110->video_size, 0, sizeof (video_size_t)); 1594 memset(&av7110->video_size, 0, sizeof (video_size_t));
1595 1595
1596 dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, 1596 dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
1597 &dvbdev_video, av7110, DVB_DEVICE_VIDEO); 1597 &dvbdev_video, av7110, DVB_DEVICE_VIDEO, 0);
1598 1598
1599 dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, 1599 dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev,
1600 &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); 1600 &dvbdev_audio, av7110, DVB_DEVICE_AUDIO, 0);
1601 1601
1602 return 0; 1602 return 0;
1603} 1603}
diff --git a/drivers/media/pci/ttpci/av7110_ca.c b/drivers/media/pci/ttpci/av7110_ca.c
index bc4c65ffd4b9..96a130fb4595 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 = {
378int av7110_ca_register(struct av7110 *av7110) 378int av7110_ca_register(struct av7110 *av7110)
379{ 379{
380 return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev, 380 return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev,
381 &dvbdev_ca, av7110, DVB_DEVICE_CA); 381 &dvbdev_ca, av7110, DVB_DEVICE_CA, 0);
382} 382}
383 383
384void av7110_ca_unregister(struct av7110 *av7110) 384void av7110_ca_unregister(struct av7110 *av7110)
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
index b6716c57b5db..b90f5bb15517 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)
22 while (pad->flags & MEDIA_PAD_FL_SINK) { 22 while (pad->flags & MEDIA_PAD_FL_SINK) {
23 /* source pad */ 23 /* source pad */
24 pad = media_entity_remote_pad(pad); 24 pad = media_entity_remote_pad(pad);
25 if (pad == NULL || 25 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
26 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
27 break; 26 break;
28 27
29 sd = media_entity_to_v4l2_subdev(pad->entity); 28 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 0d549a6c8a13..bf47d3b9cbe7 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1136,8 +1136,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
1136 } 1136 }
1137 } 1137 }
1138 1138
1139 if (src_pad == NULL || 1139 if (!src_pad || !is_media_entity_v4l2_subdev(src_pad->entity))
1140 media_entity_type(src_pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
1141 break; 1140 break;
1142 1141
1143 /* Don't call FIMC subdev operation to avoid nested locking */ 1142 /* Don't call FIMC subdev operation to avoid nested locking */
@@ -1392,7 +1391,7 @@ static int fimc_link_setup(struct media_entity *entity,
1392 struct fimc_vid_cap *vc = &fimc->vid_cap; 1391 struct fimc_vid_cap *vc = &fimc->vid_cap;
1393 struct v4l2_subdev *sensor; 1392 struct v4l2_subdev *sensor;
1394 1393
1395 if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 1394 if (!is_media_entity_v4l2_subdev(remote->entity))
1396 return -EINVAL; 1395 return -EINVAL;
1397 1396
1398 if (WARN_ON(fimc == NULL)) 1397 if (WARN_ON(fimc == NULL))
@@ -1800,7 +1799,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
1800 vid_cap->wb_fmt.code = fmt->mbus_code; 1799 vid_cap->wb_fmt.code = fmt->mbus_code;
1801 1800
1802 vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; 1801 vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
1803 ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); 1802 ret = media_entity_pads_init(&vfd->entity, 1, &vid_cap->vd_pad);
1804 if (ret) 1803 if (ret)
1805 goto err_free_ctx; 1804 goto err_free_ctx;
1806 1805
@@ -1892,8 +1891,8 @@ int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
1892 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_CAM].flags = MEDIA_PAD_FL_SINK; 1891 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_CAM].flags = MEDIA_PAD_FL_SINK;
1893 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK; 1892 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK;
1894 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1893 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1895 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, 1894 ret = media_entity_pads_init(&sd->entity, FIMC_SD_PADS_NUM,
1896 fimc->vid_cap.sd_pads, 0); 1895 fimc->vid_cap.sd_pads);
1897 if (ret) 1896 if (ret)
1898 return ret; 1897 return ret;
1899 1898
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 0dd22ec66694..bf9261eb57a1 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -287,7 +287,7 @@ static int isp_video_open(struct file *file)
287 goto rel_fh; 287 goto rel_fh;
288 288
289 if (v4l2_fh_is_singular_file(file)) { 289 if (v4l2_fh_is_singular_file(file)) {
290 mutex_lock(&me->parent->graph_mutex); 290 mutex_lock(&me->graph_obj.mdev->graph_mutex);
291 291
292 ret = fimc_pipeline_call(ve, open, me, true); 292 ret = fimc_pipeline_call(ve, open, me, true);
293 293
@@ -295,7 +295,7 @@ static int isp_video_open(struct file *file)
295 if (ret == 0) 295 if (ret == 0)
296 me->use_count++; 296 me->use_count++;
297 297
298 mutex_unlock(&me->parent->graph_mutex); 298 mutex_unlock(&me->graph_obj.mdev->graph_mutex);
299 } 299 }
300 if (!ret) 300 if (!ret)
301 goto unlock; 301 goto unlock;
@@ -311,7 +311,7 @@ static int isp_video_release(struct file *file)
311 struct fimc_isp *isp = video_drvdata(file); 311 struct fimc_isp *isp = video_drvdata(file);
312 struct fimc_is_video *ivc = &isp->video_capture; 312 struct fimc_is_video *ivc = &isp->video_capture;
313 struct media_entity *entity = &ivc->ve.vdev.entity; 313 struct media_entity *entity = &ivc->ve.vdev.entity;
314 struct media_device *mdev = entity->parent; 314 struct media_device *mdev = entity->graph_obj.mdev;
315 315
316 mutex_lock(&isp->video_lock); 316 mutex_lock(&isp->video_lock);
317 317
@@ -466,8 +466,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)
466 466
467 /* Retrieve format at the source pad */ 467 /* Retrieve format at the source pad */
468 pad = media_entity_remote_pad(pad); 468 pad = media_entity_remote_pad(pad);
469 if (pad == NULL || 469 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
470 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
471 break; 470 break;
472 471
473 sd = media_entity_to_v4l2_subdev(pad->entity); 472 sd = media_entity_to_v4l2_subdev(pad->entity);
@@ -617,7 +616,7 @@ int fimc_isp_video_device_register(struct fimc_isp *isp,
617 vdev->lock = &isp->video_lock; 616 vdev->lock = &isp->video_lock;
618 617
619 iv->pad.flags = MEDIA_PAD_FL_SINK; 618 iv->pad.flags = MEDIA_PAD_FL_SINK;
620 ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0); 619 ret = media_entity_pads_init(&vdev->entity, 1, &iv->pad);
621 if (ret < 0) 620 if (ret < 0)
622 return ret; 621 return ret;
623 622
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 5d78f5716f3b..293b807020c4 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -708,8 +708,8 @@ int fimc_isp_subdev_create(struct fimc_isp *isp)
708 isp->subdev_pads[FIMC_ISP_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 708 isp->subdev_pads[FIMC_ISP_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
709 isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE; 709 isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE;
710 isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE; 710 isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE;
711 ret = media_entity_init(&sd->entity, FIMC_ISP_SD_PADS_NUM, 711 ret = media_entity_pads_init(&sd->entity, FIMC_ISP_SD_PADS_NUM,
712 isp->subdev_pads, 0); 712 isp->subdev_pads);
713 if (ret) 713 if (ret)
714 return ret; 714 return ret;
715 715
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 639ee710499e..e85649147dc8 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -494,7 +494,7 @@ static int fimc_lite_open(struct file *file)
494 atomic_read(&fimc->out_path) != FIMC_IO_DMA) 494 atomic_read(&fimc->out_path) != FIMC_IO_DMA)
495 goto unlock; 495 goto unlock;
496 496
497 mutex_lock(&me->parent->graph_mutex); 497 mutex_lock(&me->graph_obj.mdev->graph_mutex);
498 498
499 ret = fimc_pipeline_call(&fimc->ve, open, me, true); 499 ret = fimc_pipeline_call(&fimc->ve, open, me, true);
500 500
@@ -502,7 +502,7 @@ static int fimc_lite_open(struct file *file)
502 if (ret == 0) 502 if (ret == 0)
503 me->use_count++; 503 me->use_count++;
504 504
505 mutex_unlock(&me->parent->graph_mutex); 505 mutex_unlock(&me->graph_obj.mdev->graph_mutex);
506 506
507 if (!ret) { 507 if (!ret) {
508 fimc_lite_clear_event_counters(fimc); 508 fimc_lite_clear_event_counters(fimc);
@@ -535,9 +535,9 @@ static int fimc_lite_release(struct file *file)
535 fimc_pipeline_call(&fimc->ve, close); 535 fimc_pipeline_call(&fimc->ve, close);
536 clear_bit(ST_FLITE_IN_USE, &fimc->state); 536 clear_bit(ST_FLITE_IN_USE, &fimc->state);
537 537
538 mutex_lock(&entity->parent->graph_mutex); 538 mutex_lock(&entity->graph_obj.mdev->graph_mutex);
539 entity->use_count--; 539 entity->use_count--;
540 mutex_unlock(&entity->parent->graph_mutex); 540 mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
541 } 541 }
542 542
543 _vb2_fop_release(file, NULL); 543 _vb2_fop_release(file, NULL);
@@ -808,8 +808,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc)
808 } 808 }
809 /* Retrieve format at the source pad */ 809 /* Retrieve format at the source pad */
810 pad = media_entity_remote_pad(pad); 810 pad = media_entity_remote_pad(pad);
811 if (pad == NULL || 811 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
812 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
813 break; 812 break;
814 813
815 sd = media_entity_to_v4l2_subdev(pad->entity); 814 sd = media_entity_to_v4l2_subdev(pad->entity);
@@ -982,7 +981,6 @@ static int fimc_lite_link_setup(struct media_entity *entity,
982{ 981{
983 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 982 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
984 struct fimc_lite *fimc = v4l2_get_subdevdata(sd); 983 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
985 unsigned int remote_ent_type = media_entity_type(remote->entity);
986 int ret = 0; 984 int ret = 0;
987 985
988 if (WARN_ON(fimc == NULL)) 986 if (WARN_ON(fimc == NULL))
@@ -994,7 +992,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
994 992
995 switch (local->index) { 993 switch (local->index) {
996 case FLITE_SD_PAD_SINK: 994 case FLITE_SD_PAD_SINK:
997 if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) { 995 if (!is_media_entity_v4l2_subdev(remote->entity)) {
998 ret = -EINVAL; 996 ret = -EINVAL;
999 break; 997 break;
1000 } 998 }
@@ -1012,7 +1010,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
1012 case FLITE_SD_PAD_SOURCE_DMA: 1010 case FLITE_SD_PAD_SOURCE_DMA:
1013 if (!(flags & MEDIA_LNK_FL_ENABLED)) 1011 if (!(flags & MEDIA_LNK_FL_ENABLED))
1014 atomic_set(&fimc->out_path, FIMC_IO_NONE); 1012 atomic_set(&fimc->out_path, FIMC_IO_NONE);
1015 else if (remote_ent_type == MEDIA_ENT_T_DEVNODE) 1013 else if (is_media_entity_v4l2_io(remote->entity))
1016 atomic_set(&fimc->out_path, FIMC_IO_DMA); 1014 atomic_set(&fimc->out_path, FIMC_IO_DMA);
1017 else 1015 else
1018 ret = -EINVAL; 1016 ret = -EINVAL;
@@ -1021,7 +1019,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
1021 case FLITE_SD_PAD_SOURCE_ISP: 1019 case FLITE_SD_PAD_SOURCE_ISP:
1022 if (!(flags & MEDIA_LNK_FL_ENABLED)) 1020 if (!(flags & MEDIA_LNK_FL_ENABLED))
1023 atomic_set(&fimc->out_path, FIMC_IO_NONE); 1021 atomic_set(&fimc->out_path, FIMC_IO_NONE);
1024 else if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV) 1022 else if (is_media_entity_v4l2_subdev(remote->entity))
1025 atomic_set(&fimc->out_path, FIMC_IO_ISP); 1023 atomic_set(&fimc->out_path, FIMC_IO_ISP);
1026 else 1024 else
1027 ret = -EINVAL; 1025 ret = -EINVAL;
@@ -1316,7 +1314,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
1316 return ret; 1314 return ret;
1317 1315
1318 fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; 1316 fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
1319 ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); 1317 ret = media_entity_pads_init(&vfd->entity, 1, &fimc->vd_pad);
1320 if (ret < 0) 1318 if (ret < 0)
1321 return ret; 1319 return ret;
1322 1320
@@ -1430,8 +1428,8 @@ static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
1430 fimc->subdev_pads[FLITE_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1428 fimc->subdev_pads[FLITE_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1431 fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE; 1429 fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE;
1432 fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE; 1430 fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE;
1433 ret = media_entity_init(&sd->entity, FLITE_SD_PADS_NUM, 1431 ret = media_entity_pads_init(&sd->entity, FLITE_SD_PADS_NUM,
1434 fimc->subdev_pads, 0); 1432 fimc->subdev_pads);
1435 if (ret) 1433 if (ret)
1436 return ret; 1434 return ret;
1437 1435
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 5aa857c7b631..55ec4c99d484 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -739,7 +739,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
739 return PTR_ERR(fimc->m2m.m2m_dev); 739 return PTR_ERR(fimc->m2m.m2m_dev);
740 } 740 }
741 741
742 ret = media_entity_init(&vfd->entity, 0, NULL, 0); 742 ret = media_entity_pads_init(&vfd->entity, 0, NULL);
743 if (ret) 743 if (ret)
744 goto err_me; 744 goto err_me;
745 745
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 9481ce3201a2..f3b2dd30ec77 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,
88 break; 88 break;
89 } 89 }
90 90
91 if (pad == NULL || 91 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
92 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
93 break; 92 break;
94 sd = media_entity_to_v4l2_subdev(pad->entity); 93 sd = media_entity_to_v4l2_subdev(pad->entity);
95 94
@@ -729,7 +728,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
729 flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0; 728 flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
730 729
731 sink = &fmd->fimc[i]->vid_cap.subdev.entity; 730 sink = &fmd->fimc[i]->vid_cap.subdev.entity;
732 ret = media_entity_create_link(source, pad, sink, 731 ret = media_create_pad_link(source, pad, sink,
733 FIMC_SD_PAD_SINK_CAM, flags); 732 FIMC_SD_PAD_SINK_CAM, flags);
734 if (ret) 733 if (ret)
735 return ret; 734 return ret;
@@ -749,7 +748,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
749 continue; 748 continue;
750 749
751 sink = &fmd->fimc_lite[i]->subdev.entity; 750 sink = &fmd->fimc_lite[i]->subdev.entity;
752 ret = media_entity_create_link(source, pad, sink, 751 ret = media_create_pad_link(source, pad, sink,
753 FLITE_SD_PAD_SINK, 0); 752 FLITE_SD_PAD_SINK, 0);
754 if (ret) 753 if (ret)
755 return ret; 754 return ret;
@@ -781,13 +780,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
781 source = &fimc->subdev.entity; 780 source = &fimc->subdev.entity;
782 sink = &fimc->ve.vdev.entity; 781 sink = &fimc->ve.vdev.entity;
783 /* FIMC-LITE's subdev and video node */ 782 /* FIMC-LITE's subdev and video node */
784 ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA, 783 ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
785 sink, 0, 0); 784 sink, 0, 0);
786 if (ret) 785 if (ret)
787 break; 786 break;
788 /* Link from FIMC-LITE to IS-ISP subdev */ 787 /* Link from FIMC-LITE to IS-ISP subdev */
789 sink = &fmd->fimc_is->isp.subdev.entity; 788 sink = &fmd->fimc_is->isp.subdev.entity;
790 ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP, 789 ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
791 sink, 0, 0); 790 sink, 0, 0);
792 if (ret) 791 if (ret)
793 break; 792 break;
@@ -811,7 +810,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
811 810
812 /* Link from FIMC-IS-ISP subdev to FIMC */ 811 /* Link from FIMC-IS-ISP subdev to FIMC */
813 sink = &fmd->fimc[i]->vid_cap.subdev.entity; 812 sink = &fmd->fimc[i]->vid_cap.subdev.entity;
814 ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO, 813 ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
815 sink, FIMC_SD_PAD_SINK_FIFO, 0); 814 sink, FIMC_SD_PAD_SINK_FIFO, 0);
816 if (ret) 815 if (ret)
817 return ret; 816 return ret;
@@ -824,7 +823,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
824 if (sink->num_pads == 0) 823 if (sink->num_pads == 0)
825 return 0; 824 return 0;
826 825
827 return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA, 826 return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
828 sink, 0, 0); 827 sink, 0, 0);
829} 828}
830 829
@@ -873,7 +872,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
873 return -EINVAL; 872 return -EINVAL;
874 873
875 pad = sensor->entity.num_pads - 1; 874 pad = sensor->entity.num_pads - 1;
876 ret = media_entity_create_link(&sensor->entity, pad, 875 ret = media_create_pad_link(&sensor->entity, pad,
877 &csis->entity, CSIS_PAD_SINK, 876 &csis->entity, CSIS_PAD_SINK,
878 MEDIA_LNK_FL_IMMUTABLE | 877 MEDIA_LNK_FL_IMMUTABLE |
879 MEDIA_LNK_FL_ENABLED); 878 MEDIA_LNK_FL_ENABLED);
@@ -927,7 +926,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
927 source = &fmd->fimc[i]->vid_cap.subdev.entity; 926 source = &fmd->fimc[i]->vid_cap.subdev.entity;
928 sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity; 927 sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
929 928
930 ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, 929 ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
931 sink, 0, flags); 930 sink, 0, flags);
932 if (ret) 931 if (ret)
933 break; 932 break;
@@ -1046,11 +1045,11 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
1046 return ret; 1045 return ret;
1047} 1046}
1048 1047
1049/* Locking: called with entity->parent->graph_mutex mutex held. */ 1048/* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */
1050static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable) 1049static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable,
1050 struct media_entity_graph *graph)
1051{ 1051{
1052 struct media_entity *entity_err = entity; 1052 struct media_entity *entity_err = entity;
1053 struct media_entity_graph graph;
1054 int ret; 1053 int ret;
1055 1054
1056 /* 1055 /*
@@ -1059,10 +1058,10 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
1059 * through active links. This is needed as we cannot power on/off the 1058 * through active links. This is needed as we cannot power on/off the
1060 * subdevs in random order. 1059 * subdevs in random order.
1061 */ 1060 */
1062 media_entity_graph_walk_start(&graph, entity); 1061 media_entity_graph_walk_start(graph, entity);
1063 1062
1064 while ((entity = media_entity_graph_walk_next(&graph))) { 1063 while ((entity = media_entity_graph_walk_next(graph))) {
1065 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 1064 if (!is_media_entity_v4l2_io(entity))
1066 continue; 1065 continue;
1067 1066
1068 ret = __fimc_md_modify_pipeline(entity, enable); 1067 ret = __fimc_md_modify_pipeline(entity, enable);
@@ -1072,11 +1071,12 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
1072 } 1071 }
1073 1072
1074 return 0; 1073 return 0;
1075 err:
1076 media_entity_graph_walk_start(&graph, entity_err);
1077 1074
1078 while ((entity_err = media_entity_graph_walk_next(&graph))) { 1075err:
1079 if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE) 1076 media_entity_graph_walk_start(graph, entity_err);
1077
1078 while ((entity_err = media_entity_graph_walk_next(graph))) {
1079 if (!is_media_entity_v4l2_io(entity_err))
1080 continue; 1080 continue;
1081 1081
1082 __fimc_md_modify_pipeline(entity_err, !enable); 1082 __fimc_md_modify_pipeline(entity_err, !enable);
@@ -1091,21 +1091,29 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
1091static int fimc_md_link_notify(struct media_link *link, unsigned int flags, 1091static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
1092 unsigned int notification) 1092 unsigned int notification)
1093{ 1093{
1094 struct media_entity_graph *graph =
1095 &container_of(link->graph_obj.mdev, struct fimc_md,
1096 media_dev)->link_setup_graph;
1094 struct media_entity *sink = link->sink->entity; 1097 struct media_entity *sink = link->sink->entity;
1095 int ret = 0; 1098 int ret = 0;
1096 1099
1097 /* Before link disconnection */ 1100 /* Before link disconnection */
1098 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) { 1101 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
1102 ret = media_entity_graph_walk_init(graph,
1103 link->graph_obj.mdev);
1104 if (ret)
1105 return ret;
1099 if (!(flags & MEDIA_LNK_FL_ENABLED)) 1106 if (!(flags & MEDIA_LNK_FL_ENABLED))
1100 ret = __fimc_md_modify_pipelines(sink, false); 1107 ret = __fimc_md_modify_pipelines(sink, false, graph);
1101#if 0 1108#if 0
1102 else 1109 else
1103 /* TODO: Link state change validation */ 1110 /* TODO: Link state change validation */
1104#endif 1111#endif
1105 /* After link activation */ 1112 /* After link activation */
1106 } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 1113 } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH) {
1107 (link->flags & MEDIA_LNK_FL_ENABLED)) { 1114 if (link->flags & MEDIA_LNK_FL_ENABLED)
1108 ret = __fimc_md_modify_pipelines(sink, true); 1115 ret = __fimc_md_modify_pipelines(sink, true, graph);
1116 media_entity_graph_walk_cleanup(graph);
1109 } 1117 }
1110 1118
1111 return ret ? -EPIPE : 0; 1119 return ret ? -EPIPE : 0;
@@ -1314,7 +1322,10 @@ static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
1314 ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); 1322 ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
1315unlock: 1323unlock:
1316 mutex_unlock(&fmd->media_dev.graph_mutex); 1324 mutex_unlock(&fmd->media_dev.graph_mutex);
1317 return ret; 1325 if (ret < 0)
1326 return ret;
1327
1328 return media_device_register(&fmd->media_dev);
1318} 1329}
1319 1330
1320static int fimc_md_probe(struct platform_device *pdev) 1331static int fimc_md_probe(struct platform_device *pdev)
@@ -1345,18 +1356,14 @@ static int fimc_md_probe(struct platform_device *pdev)
1345 fmd->use_isp = fimc_md_is_isp_available(dev->of_node); 1356 fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
1346 fmd->user_subdev_api = true; 1357 fmd->user_subdev_api = true;
1347 1358
1359 media_device_init(&fmd->media_dev);
1360
1348 ret = v4l2_device_register(dev, &fmd->v4l2_dev); 1361 ret = v4l2_device_register(dev, &fmd->v4l2_dev);
1349 if (ret < 0) { 1362 if (ret < 0) {
1350 v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); 1363 v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
1351 return ret; 1364 return ret;
1352 } 1365 }
1353 1366
1354 ret = media_device_register(&fmd->media_dev);
1355 if (ret < 0) {
1356 v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
1357 goto err_v4l2_dev;
1358 }
1359
1360 ret = fimc_md_get_clocks(fmd); 1367 ret = fimc_md_get_clocks(fmd);
1361 if (ret) 1368 if (ret)
1362 goto err_md; 1369 goto err_md;
@@ -1425,8 +1432,7 @@ err_clk:
1425err_m_ent: 1432err_m_ent:
1426 fimc_md_unregister_entities(fmd); 1433 fimc_md_unregister_entities(fmd);
1427err_md: 1434err_md:
1428 media_device_unregister(&fmd->media_dev); 1435 media_device_cleanup(&fmd->media_dev);
1429err_v4l2_dev:
1430 v4l2_device_unregister(&fmd->v4l2_dev); 1436 v4l2_device_unregister(&fmd->v4l2_dev);
1431 return ret; 1437 return ret;
1432} 1438}
@@ -1446,6 +1452,7 @@ static int fimc_md_remove(struct platform_device *pdev)
1446 fimc_md_unregister_entities(fmd); 1452 fimc_md_unregister_entities(fmd);
1447 fimc_md_pipelines_free(fmd); 1453 fimc_md_pipelines_free(fmd);
1448 media_device_unregister(&fmd->media_dev); 1454 media_device_unregister(&fmd->media_dev);
1455 media_device_cleanup(&fmd->media_dev);
1449 fimc_md_put_clocks(fmd); 1456 fimc_md_put_clocks(fmd);
1450 1457
1451 return 0; 1458 return 0;
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 93a96126929b..ed122cb2dd74 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -154,6 +154,7 @@ struct fimc_md {
154 bool user_subdev_api; 154 bool user_subdev_api;
155 spinlock_t slock; 155 spinlock_t slock;
156 struct list_head pipelines; 156 struct list_head pipelines;
157 struct media_entity_graph link_setup_graph;
157}; 158};
158 159
159static inline 160static inline
@@ -164,8 +165,8 @@ struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
164 165
165static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me) 166static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
166{ 167{
167 return me->parent == NULL ? NULL : 168 return me->graph_obj.mdev == NULL ? NULL :
168 container_of(me->parent, struct fimc_md, media_dev); 169 container_of(me->graph_obj.mdev, struct fimc_md, media_dev);
169} 170}
170 171
171static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n) 172static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
@@ -175,12 +176,12 @@ static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
175 176
176static inline void fimc_md_graph_lock(struct exynos_video_entity *ve) 177static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
177{ 178{
178 mutex_lock(&ve->vdev.entity.parent->graph_mutex); 179 mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
179} 180}
180 181
181static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve) 182static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
182{ 183{
183 mutex_unlock(&ve->vdev.entity.parent->graph_mutex); 184 mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
184} 185}
185 186
186int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); 187int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index ff5dabf24694..ac5e50e595be 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -866,8 +866,8 @@ static int s5pcsis_probe(struct platform_device *pdev)
866 866
867 state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 867 state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
868 state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 868 state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
869 ret = media_entity_init(&state->sd.entity, 869 ret = media_entity_pads_init(&state->sd.entity,
870 CSIS_PADS_NUM, state->pads, 0); 870 CSIS_PADS_NUM, state->pads);
871 if (ret < 0) 871 if (ret < 0)
872 goto e_clkdis; 872 goto e_clkdis;
873 873
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 56e683b19a73..0bcfa553c1aa 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -683,15 +683,15 @@ static irqreturn_t isp_isr(int irq, void *_isp)
683 * 683 *
684 * Return the total number of users of all video device nodes in the pipeline. 684 * Return the total number of users of all video device nodes in the pipeline.
685 */ 685 */
686static int isp_pipeline_pm_use_count(struct media_entity *entity) 686static int isp_pipeline_pm_use_count(struct media_entity *entity,
687 struct media_entity_graph *graph)
687{ 688{
688 struct media_entity_graph graph;
689 int use = 0; 689 int use = 0;
690 690
691 media_entity_graph_walk_start(&graph, entity); 691 media_entity_graph_walk_start(graph, entity);
692 692
693 while ((entity = media_entity_graph_walk_next(&graph))) { 693 while ((entity = media_entity_graph_walk_next(graph))) {
694 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) 694 if (is_media_entity_v4l2_io(entity))
695 use += entity->use_count; 695 use += entity->use_count;
696 } 696 }
697 697
@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
714 struct v4l2_subdev *subdev; 714 struct v4l2_subdev *subdev;
715 int ret; 715 int ret;
716 716
717 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV 717 subdev = is_media_entity_v4l2_subdev(entity)
718 ? media_entity_to_v4l2_subdev(entity) : NULL; 718 ? media_entity_to_v4l2_subdev(entity) : NULL;
719 719
720 if (entity->use_count == 0 && change > 0 && subdev != NULL) { 720 if (entity->use_count == 0 && change > 0 && subdev != NULL) {
@@ -742,29 +742,29 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
742 * 742 *
743 * Return 0 on success or a negative error code on failure. 743 * Return 0 on success or a negative error code on failure.
744 */ 744 */
745static int isp_pipeline_pm_power(struct media_entity *entity, int change) 745static int isp_pipeline_pm_power(struct media_entity *entity, int change,
746 struct media_entity_graph *graph)
746{ 747{
747 struct media_entity_graph graph;
748 struct media_entity *first = entity; 748 struct media_entity *first = entity;
749 int ret = 0; 749 int ret = 0;
750 750
751 if (!change) 751 if (!change)
752 return 0; 752 return 0;
753 753
754 media_entity_graph_walk_start(&graph, entity); 754 media_entity_graph_walk_start(graph, entity);
755 755
756 while (!ret && (entity = media_entity_graph_walk_next(&graph))) 756 while (!ret && (entity = media_entity_graph_walk_next(graph)))
757 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 757 if (is_media_entity_v4l2_subdev(entity))
758 ret = isp_pipeline_pm_power_one(entity, change); 758 ret = isp_pipeline_pm_power_one(entity, change);
759 759
760 if (!ret) 760 if (!ret)
761 return 0; 761 return ret;
762 762
763 media_entity_graph_walk_start(&graph, first); 763 media_entity_graph_walk_start(graph, first);
764 764
765 while ((first = media_entity_graph_walk_next(&graph)) 765 while ((first = media_entity_graph_walk_next(graph))
766 && first != entity) 766 && first != entity)
767 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE) 767 if (is_media_entity_v4l2_subdev(first))
768 isp_pipeline_pm_power_one(first, -change); 768 isp_pipeline_pm_power_one(first, -change);
769 769
770 return ret; 770 return ret;
@@ -782,23 +782,24 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)
782 * off is assumed to never fail. No failure can occur when the use parameter is 782 * off is assumed to never fail. No failure can occur when the use parameter is
783 * set to 0. 783 * set to 0.
784 */ 784 */
785int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) 785int omap3isp_pipeline_pm_use(struct media_entity *entity, int use,
786 struct media_entity_graph *graph)
786{ 787{
787 int change = use ? 1 : -1; 788 int change = use ? 1 : -1;
788 int ret; 789 int ret;
789 790
790 mutex_lock(&entity->parent->graph_mutex); 791 mutex_lock(&entity->graph_obj.mdev->graph_mutex);
791 792
792 /* Apply use count to node. */ 793 /* Apply use count to node. */
793 entity->use_count += change; 794 entity->use_count += change;
794 WARN_ON(entity->use_count < 0); 795 WARN_ON(entity->use_count < 0);
795 796
796 /* Apply power change to connected non-nodes. */ 797 /* Apply power change to connected non-nodes. */
797 ret = isp_pipeline_pm_power(entity, change); 798 ret = isp_pipeline_pm_power(entity, change, graph);
798 if (ret < 0) 799 if (ret < 0)
799 entity->use_count -= change; 800 entity->use_count -= change;
800 801
801 mutex_unlock(&entity->parent->graph_mutex); 802 mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
802 803
803 return ret; 804 return ret;
804} 805}
@@ -820,35 +821,49 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
820static int isp_pipeline_link_notify(struct media_link *link, u32 flags, 821static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
821 unsigned int notification) 822 unsigned int notification)
822{ 823{
824 struct media_entity_graph *graph =
825 &container_of(link->graph_obj.mdev, struct isp_device,
826 media_dev)->pm_count_graph;
823 struct media_entity *source = link->source->entity; 827 struct media_entity *source = link->source->entity;
824 struct media_entity *sink = link->sink->entity; 828 struct media_entity *sink = link->sink->entity;
825 int source_use = isp_pipeline_pm_use_count(source); 829 int source_use;
826 int sink_use = isp_pipeline_pm_use_count(sink); 830 int sink_use;
827 int ret; 831 int ret = 0;
832
833 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
834 ret = media_entity_graph_walk_init(graph,
835 link->graph_obj.mdev);
836 if (ret)
837 return ret;
838 }
839
840 source_use = isp_pipeline_pm_use_count(source, graph);
841 sink_use = isp_pipeline_pm_use_count(sink, graph);
828 842
829 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 843 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
830 !(flags & MEDIA_LNK_FL_ENABLED)) { 844 !(flags & MEDIA_LNK_FL_ENABLED)) {
831 /* Powering off entities is assumed to never fail. */ 845 /* Powering off entities is assumed to never fail. */
832 isp_pipeline_pm_power(source, -sink_use); 846 isp_pipeline_pm_power(source, -sink_use, graph);
833 isp_pipeline_pm_power(sink, -source_use); 847 isp_pipeline_pm_power(sink, -source_use, graph);
834 return 0; 848 return 0;
835 } 849 }
836 850
837 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH && 851 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
838 (flags & MEDIA_LNK_FL_ENABLED)) { 852 (flags & MEDIA_LNK_FL_ENABLED)) {
839 853
840 ret = isp_pipeline_pm_power(source, sink_use); 854 ret = isp_pipeline_pm_power(source, sink_use, graph);
841 if (ret < 0) 855 if (ret < 0)
842 return ret; 856 return ret;
843 857
844 ret = isp_pipeline_pm_power(sink, source_use); 858 ret = isp_pipeline_pm_power(sink, source_use, graph);
845 if (ret < 0) 859 if (ret < 0)
846 isp_pipeline_pm_power(source, -sink_use); 860 isp_pipeline_pm_power(source, -sink_use, graph);
847
848 return ret;
849 } 861 }
850 862
851 return 0; 863 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH)
864 media_entity_graph_walk_cleanup(graph);
865
866 return ret;
852} 867}
853 868
854/* ----------------------------------------------------------------------------- 869/* -----------------------------------------------------------------------------
@@ -881,7 +896,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
881 * starting entities if the pipeline won't start anyway (those entities 896 * starting entities if the pipeline won't start anyway (those entities
882 * would then likely fail to stop, making the problem worse). 897 * would then likely fail to stop, making the problem worse).
883 */ 898 */
884 if (pipe->entities & isp->crashed) 899 if (media_entity_enum_intersects(&pipe->ent_enum, &isp->crashed))
885 return -EIO; 900 return -EIO;
886 901
887 spin_lock_irqsave(&pipe->lock, flags); 902 spin_lock_irqsave(&pipe->lock, flags);
@@ -897,8 +912,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
897 break; 912 break;
898 913
899 pad = media_entity_remote_pad(pad); 914 pad = media_entity_remote_pad(pad);
900 if (pad == NULL || 915 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
901 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
902 break; 916 break;
903 917
904 entity = pad->entity; 918 entity = pad->entity;
@@ -987,8 +1001,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
987 break; 1001 break;
988 1002
989 pad = media_entity_remote_pad(pad); 1003 pad = media_entity_remote_pad(pad);
990 if (pad == NULL || 1004 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
991 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
992 break; 1005 break;
993 1006
994 entity = pad->entity; 1007 entity = pad->entity;
@@ -1028,7 +1041,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
1028 dev_info(isp->dev, "Unable to stop %s\n", subdev->name); 1041 dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
1029 isp->stop_failure = true; 1042 isp->stop_failure = true;
1030 if (subdev == &isp->isp_prev.subdev) 1043 if (subdev == &isp->isp_prev.subdev)
1031 isp->crashed |= 1U << subdev->entity.id; 1044 media_entity_enum_set(&isp->crashed,
1045 &subdev->entity);
1032 failure = -ETIMEDOUT; 1046 failure = -ETIMEDOUT;
1033 } 1047 }
1034 } 1048 }
@@ -1234,7 +1248,7 @@ static int isp_reset(struct isp_device *isp)
1234 } 1248 }
1235 1249
1236 isp->stop_failure = false; 1250 isp->stop_failure = false;
1237 isp->crashed = 0; 1251 media_entity_enum_zero(&isp->crashed);
1238 return 0; 1252 return 0;
1239} 1253}
1240 1254
@@ -1645,7 +1659,8 @@ static void __omap3isp_put(struct isp_device *isp, bool save_ctx)
1645 /* Reset the ISP if an entity has failed to stop. This is the 1659 /* Reset the ISP if an entity has failed to stop. This is the
1646 * only way to recover from such conditions. 1660 * only way to recover from such conditions.
1647 */ 1661 */
1648 if (isp->crashed || isp->stop_failure) 1662 if (!media_entity_enum_empty(&isp->crashed) ||
1663 isp->stop_failure)
1649 isp_reset(isp); 1664 isp_reset(isp);
1650 isp_disable_clocks(isp); 1665 isp_disable_clocks(isp);
1651 } 1666 }
@@ -1792,6 +1807,7 @@ static void isp_unregister_entities(struct isp_device *isp)
1792 1807
1793 v4l2_device_unregister(&isp->v4l2_dev); 1808 v4l2_device_unregister(&isp->v4l2_dev);
1794 media_device_unregister(&isp->media_dev); 1809 media_device_unregister(&isp->media_dev);
1810 media_device_cleanup(&isp->media_dev);
1795} 1811}
1796 1812
1797static int isp_link_entity( 1813static int isp_link_entity(
@@ -1862,7 +1878,7 @@ static int isp_link_entity(
1862 return -EINVAL; 1878 return -EINVAL;
1863 } 1879 }
1864 1880
1865 return media_entity_create_link(entity, i, input, pad, flags); 1881 return media_create_pad_link(entity, i, input, pad, flags);
1866} 1882}
1867 1883
1868static int isp_register_entities(struct isp_device *isp) 1884static int isp_register_entities(struct isp_device *isp)
@@ -1874,12 +1890,7 @@ static int isp_register_entities(struct isp_device *isp)
1874 sizeof(isp->media_dev.model)); 1890 sizeof(isp->media_dev.model));
1875 isp->media_dev.hw_revision = isp->revision; 1891 isp->media_dev.hw_revision = isp->revision;
1876 isp->media_dev.link_notify = isp_pipeline_link_notify; 1892 isp->media_dev.link_notify = isp_pipeline_link_notify;
1877 ret = media_device_register(&isp->media_dev); 1893 media_device_init(&isp->media_dev);
1878 if (ret < 0) {
1879 dev_err(isp->dev, "%s: Media device registration failed (%d)\n",
1880 __func__, ret);
1881 return ret;
1882 }
1883 1894
1884 isp->v4l2_dev.mdev = &isp->media_dev; 1895 isp->v4l2_dev.mdev = &isp->media_dev;
1885 ret = v4l2_device_register(isp->dev, &isp->v4l2_dev); 1896 ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
@@ -1930,6 +1941,118 @@ done:
1930 return ret; 1941 return ret;
1931} 1942}
1932 1943
1944/*
1945 * isp_create_links() - Create links for internal and external ISP entities
1946 * @isp : Pointer to ISP device
1947 *
1948 * This function creates all links between ISP internal and external entities.
1949 *
1950 * Return: A negative error code on failure or zero on success. Possible error
1951 * codes are those returned by media_create_pad_link().
1952 */
1953static int isp_create_links(struct isp_device *isp)
1954{
1955 int ret;
1956
1957 /* Create links between entities and video nodes. */
1958 ret = media_create_pad_link(
1959 &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
1960 &isp->isp_csi2a.video_out.video.entity, 0, 0);
1961 if (ret < 0)
1962 return ret;
1963
1964 ret = media_create_pad_link(
1965 &isp->isp_ccp2.video_in.video.entity, 0,
1966 &isp->isp_ccp2.subdev.entity, CCP2_PAD_SINK, 0);
1967 if (ret < 0)
1968 return ret;
1969
1970 ret = media_create_pad_link(
1971 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
1972 &isp->isp_ccdc.video_out.video.entity, 0, 0);
1973 if (ret < 0)
1974 return ret;
1975
1976 ret = media_create_pad_link(
1977 &isp->isp_prev.video_in.video.entity, 0,
1978 &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
1979 if (ret < 0)
1980 return ret;
1981
1982 ret = media_create_pad_link(
1983 &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
1984 &isp->isp_prev.video_out.video.entity, 0, 0);
1985 if (ret < 0)
1986 return ret;
1987
1988 ret = media_create_pad_link(
1989 &isp->isp_res.video_in.video.entity, 0,
1990 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
1991 if (ret < 0)
1992 return ret;
1993
1994 ret = media_create_pad_link(
1995 &isp->isp_res.subdev.entity, RESZ_PAD_SOURCE,
1996 &isp->isp_res.video_out.video.entity, 0, 0);
1997
1998 if (ret < 0)
1999 return ret;
2000
2001 /* Create links between entities. */
2002 ret = media_create_pad_link(
2003 &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
2004 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
2005 if (ret < 0)
2006 return ret;
2007
2008 ret = media_create_pad_link(
2009 &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
2010 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
2011 if (ret < 0)
2012 return ret;
2013
2014 ret = media_create_pad_link(
2015 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2016 &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
2017 if (ret < 0)
2018 return ret;
2019
2020 ret = media_create_pad_link(
2021 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
2022 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
2023 if (ret < 0)
2024 return ret;
2025
2026 ret = media_create_pad_link(
2027 &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
2028 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
2029 if (ret < 0)
2030 return ret;
2031
2032 ret = media_create_pad_link(
2033 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2034 &isp->isp_aewb.subdev.entity, 0,
2035 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
2036 if (ret < 0)
2037 return ret;
2038
2039 ret = media_create_pad_link(
2040 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2041 &isp->isp_af.subdev.entity, 0,
2042 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
2043 if (ret < 0)
2044 return ret;
2045
2046 ret = media_create_pad_link(
2047 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2048 &isp->isp_hist.subdev.entity, 0,
2049 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
2050 if (ret < 0)
2051 return ret;
2052
2053 return 0;
2054}
2055
1933static void isp_cleanup_modules(struct isp_device *isp) 2056static void isp_cleanup_modules(struct isp_device *isp)
1934{ 2057{
1935 omap3isp_h3a_aewb_cleanup(isp); 2058 omap3isp_h3a_aewb_cleanup(isp);
@@ -2000,62 +2123,8 @@ static int isp_initialize_modules(struct isp_device *isp)
2000 goto error_h3a_af; 2123 goto error_h3a_af;
2001 } 2124 }
2002 2125
2003 /* Connect the submodules. */
2004 ret = media_entity_create_link(
2005 &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
2006 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
2007 if (ret < 0)
2008 goto error_link;
2009
2010 ret = media_entity_create_link(
2011 &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
2012 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
2013 if (ret < 0)
2014 goto error_link;
2015
2016 ret = media_entity_create_link(
2017 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2018 &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
2019 if (ret < 0)
2020 goto error_link;
2021
2022 ret = media_entity_create_link(
2023 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
2024 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
2025 if (ret < 0)
2026 goto error_link;
2027
2028 ret = media_entity_create_link(
2029 &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
2030 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
2031 if (ret < 0)
2032 goto error_link;
2033
2034 ret = media_entity_create_link(
2035 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2036 &isp->isp_aewb.subdev.entity, 0,
2037 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
2038 if (ret < 0)
2039 goto error_link;
2040
2041 ret = media_entity_create_link(
2042 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2043 &isp->isp_af.subdev.entity, 0,
2044 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
2045 if (ret < 0)
2046 goto error_link;
2047
2048 ret = media_entity_create_link(
2049 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
2050 &isp->isp_hist.subdev.entity, 0,
2051 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
2052 if (ret < 0)
2053 goto error_link;
2054
2055 return 0; 2126 return 0;
2056 2127
2057error_link:
2058 omap3isp_h3a_af_cleanup(isp);
2059error_h3a_af: 2128error_h3a_af:
2060 omap3isp_h3a_aewb_cleanup(isp); 2129 omap3isp_h3a_aewb_cleanup(isp);
2061error_h3a_aewb: 2130error_h3a_aewb:
@@ -2149,6 +2218,8 @@ static int isp_remove(struct platform_device *pdev)
2149 isp_detach_iommu(isp); 2218 isp_detach_iommu(isp);
2150 __omap3isp_put(isp, false); 2219 __omap3isp_put(isp, false);
2151 2220
2221 media_entity_enum_cleanup(&isp->crashed);
2222
2152 return 0; 2223 return 0;
2153} 2224}
2154 2225
@@ -2278,28 +2349,43 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,
2278 struct v4l2_subdev *subdev, 2349 struct v4l2_subdev *subdev,
2279 struct v4l2_async_subdev *asd) 2350 struct v4l2_async_subdev *asd)
2280{ 2351{
2281 struct isp_device *isp = container_of(async, struct isp_device,
2282 notifier);
2283 struct isp_async_subdev *isd = 2352 struct isp_async_subdev *isd =
2284 container_of(asd, struct isp_async_subdev, asd); 2353 container_of(asd, struct isp_async_subdev, asd);
2285 int ret;
2286
2287 ret = isp_link_entity(isp, &subdev->entity, isd->bus.interface);
2288 if (ret < 0)
2289 return ret;
2290 2354
2291 isd->sd = subdev; 2355 isd->sd = subdev;
2292 isd->sd->host_priv = &isd->bus; 2356 isd->sd->host_priv = &isd->bus;
2293 2357
2294 return ret; 2358 return 0;
2295} 2359}
2296 2360
2297static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) 2361static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
2298{ 2362{
2299 struct isp_device *isp = container_of(async, struct isp_device, 2363 struct isp_device *isp = container_of(async, struct isp_device,
2300 notifier); 2364 notifier);
2365 struct v4l2_device *v4l2_dev = &isp->v4l2_dev;
2366 struct v4l2_subdev *sd;
2367 struct isp_bus_cfg *bus;
2368 int ret;
2369
2370 ret = media_entity_enum_init(&isp->crashed, &isp->media_dev);
2371 if (ret)
2372 return ret;
2301 2373
2302 return v4l2_device_register_subdev_nodes(&isp->v4l2_dev); 2374 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
2375 /* Only try to link entities whose interface was set on bound */
2376 if (sd->host_priv) {
2377 bus = (struct isp_bus_cfg *)sd->host_priv;
2378 ret = isp_link_entity(isp, &sd->entity, bus->interface);
2379 if (ret < 0)
2380 return ret;
2381 }
2382 }
2383
2384 ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
2385 if (ret < 0)
2386 return ret;
2387
2388 return media_device_register(&isp->media_dev);
2303} 2389}
2304 2390
2305/* 2391/*
@@ -2465,6 +2551,10 @@ static int isp_probe(struct platform_device *pdev)
2465 if (ret < 0) 2551 if (ret < 0)
2466 goto error_modules; 2552 goto error_modules;
2467 2553
2554 ret = isp_create_links(isp);
2555 if (ret < 0)
2556 goto error_register_entities;
2557
2468 isp->notifier.bound = isp_subdev_notifier_bound; 2558 isp->notifier.bound = isp_subdev_notifier_bound;
2469 isp->notifier.complete = isp_subdev_notifier_complete; 2559 isp->notifier.complete = isp_subdev_notifier_complete;
2470 2560
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index 5acc2e6511a5..49b7f71ac968 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -17,6 +17,7 @@
17#ifndef OMAP3_ISP_CORE_H 17#ifndef OMAP3_ISP_CORE_H
18#define OMAP3_ISP_CORE_H 18#define OMAP3_ISP_CORE_H
19 19
20#include <media/media-entity.h>
20#include <media/v4l2-async.h> 21#include <media/v4l2-async.h>
21#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
22#include <linux/clk-provider.h> 23#include <linux/clk-provider.h>
@@ -152,7 +153,7 @@ struct isp_xclk {
152 * @stat_lock: Spinlock for handling statistics 153 * @stat_lock: Spinlock for handling statistics
153 * @isp_mutex: Mutex for serializing requests to ISP. 154 * @isp_mutex: Mutex for serializing requests to ISP.
154 * @stop_failure: Indicates that an entity failed to stop. 155 * @stop_failure: Indicates that an entity failed to stop.
155 * @crashed: Bitmask of crashed entities (indexed by entity ID) 156 * @crashed: Crashed ent_enum
156 * @has_context: Context has been saved at least once and can be restored. 157 * @has_context: Context has been saved at least once and can be restored.
157 * @ref_count: Reference count for handling multiple ISP requests. 158 * @ref_count: Reference count for handling multiple ISP requests.
158 * @cam_ick: Pointer to camera interface clock structure. 159 * @cam_ick: Pointer to camera interface clock structure.
@@ -176,6 +177,7 @@ struct isp_device {
176 struct v4l2_device v4l2_dev; 177 struct v4l2_device v4l2_dev;
177 struct v4l2_async_notifier notifier; 178 struct v4l2_async_notifier notifier;
178 struct media_device media_dev; 179 struct media_device media_dev;
180 struct media_entity_graph pm_count_graph;
179 struct device *dev; 181 struct device *dev;
180 u32 revision; 182 u32 revision;
181 183
@@ -194,7 +196,7 @@ struct isp_device {
194 spinlock_t stat_lock; /* common lock for statistic drivers */ 196 spinlock_t stat_lock; /* common lock for statistic drivers */
195 struct mutex isp_mutex; /* For handling ref_count field */ 197 struct mutex isp_mutex; /* For handling ref_count field */
196 bool stop_failure; 198 bool stop_failure;
197 u32 crashed; 199 struct media_entity_enum crashed;
198 int has_context; 200 int has_context;
199 int ref_count; 201 int ref_count;
200 unsigned int autoidle; 202 unsigned int autoidle;
@@ -265,7 +267,8 @@ void omap3isp_subclk_enable(struct isp_device *isp,
265void omap3isp_subclk_disable(struct isp_device *isp, 267void omap3isp_subclk_disable(struct isp_device *isp,
266 enum isp_subclk_resource res); 268 enum isp_subclk_resource res);
267 269
268int omap3isp_pipeline_pm_use(struct media_entity *entity, int use); 270int omap3isp_pipeline_pm_use(struct media_entity *entity, int use,
271 struct media_entity_graph *graph);
269 272
270int omap3isp_register_entities(struct platform_device *pdev, 273int omap3isp_register_entities(struct platform_device *pdev,
271 struct v4l2_device *v4l2_dev); 274 struct v4l2_device *v4l2_dev);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index a6a61cce43dd..bb3974c98e37 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)
1608 /* Wait for the CCDC to become idle. */ 1608 /* Wait for the CCDC to become idle. */
1609 if (ccdc_sbl_wait_idle(ccdc, 1000)) { 1609 if (ccdc_sbl_wait_idle(ccdc, 1000)) {
1610 dev_info(isp->dev, "CCDC won't become idle!\n"); 1610 dev_info(isp->dev, "CCDC won't become idle!\n");
1611 isp->crashed |= 1U << ccdc->subdev.entity.id; 1611 media_entity_enum_set(&isp->crashed, &ccdc->subdev.entity);
1612 omap3isp_pipeline_cancel_stream(pipe); 1612 omap3isp_pipeline_cancel_stream(pipe);
1613 return 0; 1613 return 0;
1614 } 1614 }
@@ -2513,9 +2513,14 @@ static int ccdc_link_setup(struct media_entity *entity,
2513 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 2513 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
2514 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2514 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2515 struct isp_device *isp = to_isp_device(ccdc); 2515 struct isp_device *isp = to_isp_device(ccdc);
2516 unsigned int index = local->index;
2516 2517
2517 switch (local->index | media_entity_type(remote->entity)) { 2518 /* FIXME: this is actually a hack! */
2518 case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 2519 if (is_media_entity_v4l2_subdev(remote->entity))
2520 index |= 2 << 16;
2521
2522 switch (index) {
2523 case CCDC_PAD_SINK | 2 << 16:
2519 /* Read from the sensor (parallel interface), CCP2, CSI2a or 2524 /* Read from the sensor (parallel interface), CCP2, CSI2a or
2520 * CSI2c. 2525 * CSI2c.
2521 */ 2526 */
@@ -2543,7 +2548,7 @@ static int ccdc_link_setup(struct media_entity *entity,
2543 * Revisit this when it will be implemented, and return -EBUSY for now. 2548 * Revisit this when it will be implemented, and return -EBUSY for now.
2544 */ 2549 */
2545 2550
2546 case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: 2551 case CCDC_PAD_SOURCE_VP | 2 << 16:
2547 /* Write to preview engine, histogram and H3A. When none of 2552 /* Write to preview engine, histogram and H3A. When none of
2548 * those links are active, the video port can be disabled. 2553 * those links are active, the video port can be disabled.
2549 */ 2554 */
@@ -2556,7 +2561,7 @@ static int ccdc_link_setup(struct media_entity *entity,
2556 } 2561 }
2557 break; 2562 break;
2558 2563
2559 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE: 2564 case CCDC_PAD_SOURCE_OF:
2560 /* Write to memory */ 2565 /* Write to memory */
2561 if (flags & MEDIA_LNK_FL_ENABLED) { 2566 if (flags & MEDIA_LNK_FL_ENABLED) {
2562 if (ccdc->output & ~CCDC_OUTPUT_MEMORY) 2567 if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
@@ -2567,7 +2572,7 @@ static int ccdc_link_setup(struct media_entity *entity,
2567 } 2572 }
2568 break; 2573 break;
2569 2574
2570 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV: 2575 case CCDC_PAD_SOURCE_OF | 2 << 16:
2571 /* Write to resizer */ 2576 /* Write to resizer */
2572 if (flags & MEDIA_LNK_FL_ENABLED) { 2577 if (flags & MEDIA_LNK_FL_ENABLED) {
2573 if (ccdc->output & ~CCDC_OUTPUT_RESIZER) 2578 if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
@@ -2650,7 +2655,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2650 pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE; 2655 pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
2651 2656
2652 me->ops = &ccdc_media_ops; 2657 me->ops = &ccdc_media_ops;
2653 ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0); 2658 ret = media_entity_pads_init(me, CCDC_PADS_NUM, pads);
2654 if (ret < 0) 2659 if (ret < 0)
2655 return ret; 2660 return ret;
2656 2661
@@ -2664,19 +2669,11 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2664 2669
2665 ret = omap3isp_video_init(&ccdc->video_out, "CCDC"); 2670 ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2666 if (ret < 0) 2671 if (ret < 0)
2667 goto error_video; 2672 goto error;
2668
2669 /* Connect the CCDC subdev to the video node. */
2670 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2671 &ccdc->video_out.video.entity, 0, 0);
2672 if (ret < 0)
2673 goto error_link;
2674 2673
2675 return 0; 2674 return 0;
2676 2675
2677error_link: 2676error:
2678 omap3isp_video_cleanup(&ccdc->video_out);
2679error_video:
2680 media_entity_cleanup(me); 2677 media_entity_cleanup(me);
2681 return ret; 2678 return ret;
2682} 2679}
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index 38e6a974c5b1..ca095238510d 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,
956{ 956{
957 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 957 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
958 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 958 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
959 unsigned int index = local->index;
959 960
960 switch (local->index | media_entity_type(remote->entity)) { 961 /* FIXME: this is actually a hack! */
961 case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE: 962 if (is_media_entity_v4l2_subdev(remote->entity))
963 index |= 2 << 16;
964
965 switch (index) {
966 case CCP2_PAD_SINK:
962 /* read from memory */ 967 /* read from memory */
963 if (flags & MEDIA_LNK_FL_ENABLED) { 968 if (flags & MEDIA_LNK_FL_ENABLED) {
964 if (ccp2->input == CCP2_INPUT_SENSOR) 969 if (ccp2->input == CCP2_INPUT_SENSOR)
@@ -970,7 +975,7 @@ static int ccp2_link_setup(struct media_entity *entity,
970 } 975 }
971 break; 976 break;
972 977
973 case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 978 case CCP2_PAD_SINK | 2 << 16:
974 /* read from sensor/phy */ 979 /* read from sensor/phy */
975 if (flags & MEDIA_LNK_FL_ENABLED) { 980 if (flags & MEDIA_LNK_FL_ENABLED) {
976 if (ccp2->input == CCP2_INPUT_MEMORY) 981 if (ccp2->input == CCP2_INPUT_MEMORY)
@@ -981,7 +986,7 @@ static int ccp2_link_setup(struct media_entity *entity,
981 ccp2->input = CCP2_INPUT_NONE; 986 ccp2->input = CCP2_INPUT_NONE;
982 } break; 987 } break;
983 988
984 case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 989 case CCP2_PAD_SOURCE | 2 << 16:
985 /* write to video port/ccdc */ 990 /* write to video port/ccdc */
986 if (flags & MEDIA_LNK_FL_ENABLED) 991 if (flags & MEDIA_LNK_FL_ENABLED)
987 ccp2->output = CCP2_OUTPUT_CCDC; 992 ccp2->output = CCP2_OUTPUT_CCDC;
@@ -1071,7 +1076,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1071 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1076 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1072 1077
1073 me->ops = &ccp2_media_ops; 1078 me->ops = &ccp2_media_ops;
1074 ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0); 1079 ret = media_entity_pads_init(me, CCP2_PADS_NUM, pads);
1075 if (ret < 0) 1080 if (ret < 0)
1076 return ret; 1081 return ret;
1077 1082
@@ -1097,19 +1102,11 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1097 1102
1098 ret = omap3isp_video_init(&ccp2->video_in, "CCP2"); 1103 ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1099 if (ret < 0) 1104 if (ret < 0)
1100 goto error_video; 1105 goto error;
1101
1102 /* Connect the video node to the ccp2 subdev. */
1103 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1104 &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1105 if (ret < 0)
1106 goto error_link;
1107 1106
1108 return 0; 1107 return 0;
1109 1108
1110error_link: 1109error:
1111 omap3isp_video_cleanup(&ccp2->video_in);
1112error_video:
1113 media_entity_cleanup(&ccp2->subdev.entity); 1110 media_entity_cleanup(&ccp2->subdev.entity);
1114 return ret; 1111 return ret;
1115} 1112}
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index a78338d012b4..f75a1be29d84 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,
1144 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 1144 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1145 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); 1145 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1146 struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl; 1146 struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
1147 unsigned int index = local->index;
1147 1148
1148 /* 1149 /*
1149 * The ISP core doesn't support pipelines with multiple video outputs. 1150 * The ISP core doesn't support pipelines with multiple video outputs.
1150 * Revisit this when it will be implemented, and return -EBUSY for now. 1151 * Revisit this when it will be implemented, and return -EBUSY for now.
1151 */ 1152 */
1152 1153
1153 switch (local->index | media_entity_type(remote->entity)) { 1154 /* FIXME: this is actually a hack! */
1154 case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: 1155 if (is_media_entity_v4l2_subdev(remote->entity))
1156 index |= 2 << 16;
1157
1158 switch (index) {
1159 case CSI2_PAD_SOURCE:
1155 if (flags & MEDIA_LNK_FL_ENABLED) { 1160 if (flags & MEDIA_LNK_FL_ENABLED) {
1156 if (csi2->output & ~CSI2_OUTPUT_MEMORY) 1161 if (csi2->output & ~CSI2_OUTPUT_MEMORY)
1157 return -EBUSY; 1162 return -EBUSY;
@@ -1161,7 +1166,7 @@ static int csi2_link_setup(struct media_entity *entity,
1161 } 1166 }
1162 break; 1167 break;
1163 1168
1164 case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 1169 case CSI2_PAD_SOURCE | 2 << 16:
1165 if (flags & MEDIA_LNK_FL_ENABLED) { 1170 if (flags & MEDIA_LNK_FL_ENABLED) {
1166 if (csi2->output & ~CSI2_OUTPUT_CCDC) 1171 if (csi2->output & ~CSI2_OUTPUT_CCDC)
1167 return -EBUSY; 1172 return -EBUSY;
@@ -1245,7 +1250,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
1245 | MEDIA_PAD_FL_MUST_CONNECT; 1250 | MEDIA_PAD_FL_MUST_CONNECT;
1246 1251
1247 me->ops = &csi2_media_ops; 1252 me->ops = &csi2_media_ops;
1248 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0); 1253 ret = media_entity_pads_init(me, CSI2_PADS_NUM, pads);
1249 if (ret < 0) 1254 if (ret < 0)
1250 return ret; 1255 return ret;
1251 1256
@@ -1264,16 +1269,8 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
1264 if (ret < 0) 1269 if (ret < 0)
1265 goto error_video; 1270 goto error_video;
1266 1271
1267 /* Connect the CSI2 subdev to the video node. */
1268 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1269 &csi2->video_out.video.entity, 0, 0);
1270 if (ret < 0)
1271 goto error_link;
1272
1273 return 0; 1272 return 0;
1274 1273
1275error_link:
1276 omap3isp_video_cleanup(&csi2->video_out);
1277error_video: 1274error_video:
1278 media_entity_cleanup(&csi2->subdev.entity); 1275 media_entity_cleanup(&csi2->subdev.entity);
1279 return ret; 1276 return ret;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index 13803270d104..84a96670e2e7 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,
2144{ 2144{
2145 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 2145 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
2146 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 2146 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
2147 unsigned int index = local->index;
2147 2148
2148 switch (local->index | media_entity_type(remote->entity)) { 2149 /* FIXME: this is actually a hack! */
2149 case PREV_PAD_SINK | MEDIA_ENT_T_DEVNODE: 2150 if (is_media_entity_v4l2_subdev(remote->entity))
2151 index |= 2 << 16;
2152
2153 switch (index) {
2154 case PREV_PAD_SINK:
2150 /* read from memory */ 2155 /* read from memory */
2151 if (flags & MEDIA_LNK_FL_ENABLED) { 2156 if (flags & MEDIA_LNK_FL_ENABLED) {
2152 if (prev->input == PREVIEW_INPUT_CCDC) 2157 if (prev->input == PREVIEW_INPUT_CCDC)
@@ -2158,7 +2163,7 @@ static int preview_link_setup(struct media_entity *entity,
2158 } 2163 }
2159 break; 2164 break;
2160 2165
2161 case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 2166 case PREV_PAD_SINK | 2 << 16:
2162 /* read from ccdc */ 2167 /* read from ccdc */
2163 if (flags & MEDIA_LNK_FL_ENABLED) { 2168 if (flags & MEDIA_LNK_FL_ENABLED) {
2164 if (prev->input == PREVIEW_INPUT_MEMORY) 2169 if (prev->input == PREVIEW_INPUT_MEMORY)
@@ -2175,7 +2180,7 @@ static int preview_link_setup(struct media_entity *entity,
2175 * Revisit this when it will be implemented, and return -EBUSY for now. 2180 * Revisit this when it will be implemented, and return -EBUSY for now.
2176 */ 2181 */
2177 2182
2178 case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: 2183 case PREV_PAD_SOURCE:
2179 /* write to memory */ 2184 /* write to memory */
2180 if (flags & MEDIA_LNK_FL_ENABLED) { 2185 if (flags & MEDIA_LNK_FL_ENABLED) {
2181 if (prev->output & ~PREVIEW_OUTPUT_MEMORY) 2186 if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
@@ -2186,7 +2191,7 @@ static int preview_link_setup(struct media_entity *entity,
2186 } 2191 }
2187 break; 2192 break;
2188 2193
2189 case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 2194 case PREV_PAD_SOURCE | 2 << 16:
2190 /* write to resizer */ 2195 /* write to resizer */
2191 if (flags & MEDIA_LNK_FL_ENABLED) { 2196 if (flags & MEDIA_LNK_FL_ENABLED) {
2192 if (prev->output & ~PREVIEW_OUTPUT_RESIZER) 2197 if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
@@ -2282,7 +2287,7 @@ static int preview_init_entities(struct isp_prev_device *prev)
2282 pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 2287 pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
2283 2288
2284 me->ops = &preview_media_ops; 2289 me->ops = &preview_media_ops;
2285 ret = media_entity_init(me, PREV_PADS_NUM, pads, 0); 2290 ret = media_entity_pads_init(me, PREV_PADS_NUM, pads);
2286 if (ret < 0) 2291 if (ret < 0)
2287 return ret; 2292 return ret;
2288 2293
@@ -2311,21 +2316,8 @@ static int preview_init_entities(struct isp_prev_device *prev)
2311 if (ret < 0) 2316 if (ret < 0)
2312 goto error_video_out; 2317 goto error_video_out;
2313 2318
2314 /* Connect the video nodes to the previewer subdev. */
2315 ret = media_entity_create_link(&prev->video_in.video.entity, 0,
2316 &prev->subdev.entity, PREV_PAD_SINK, 0);
2317 if (ret < 0)
2318 goto error_link;
2319
2320 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
2321 &prev->video_out.video.entity, 0, 0);
2322 if (ret < 0)
2323 goto error_link;
2324
2325 return 0; 2319 return 0;
2326 2320
2327error_link:
2328 omap3isp_video_cleanup(&prev->video_out);
2329error_video_out: 2321error_video_out:
2330 omap3isp_video_cleanup(&prev->video_in); 2322 omap3isp_video_cleanup(&prev->video_in);
2331error_video_in: 2323error_video_in:
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 7cfb43dc0ffd..0b6a87508584 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,
1623{ 1623{
1624 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 1624 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1625 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1625 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1626 unsigned int index = local->index;
1626 1627
1627 switch (local->index | media_entity_type(remote->entity)) { 1628 /* FIXME: this is actually a hack! */
1628 case RESZ_PAD_SINK | MEDIA_ENT_T_DEVNODE: 1629 if (is_media_entity_v4l2_subdev(remote->entity))
1630 index |= 2 << 16;
1631
1632 switch (index) {
1633 case RESZ_PAD_SINK:
1629 /* read from memory */ 1634 /* read from memory */
1630 if (flags & MEDIA_LNK_FL_ENABLED) { 1635 if (flags & MEDIA_LNK_FL_ENABLED) {
1631 if (res->input == RESIZER_INPUT_VP) 1636 if (res->input == RESIZER_INPUT_VP)
@@ -1637,7 +1642,7 @@ static int resizer_link_setup(struct media_entity *entity,
1637 } 1642 }
1638 break; 1643 break;
1639 1644
1640 case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 1645 case RESZ_PAD_SINK | 2 << 16:
1641 /* read from ccdc or previewer */ 1646 /* read from ccdc or previewer */
1642 if (flags & MEDIA_LNK_FL_ENABLED) { 1647 if (flags & MEDIA_LNK_FL_ENABLED) {
1643 if (res->input == RESIZER_INPUT_MEMORY) 1648 if (res->input == RESIZER_INPUT_MEMORY)
@@ -1649,7 +1654,7 @@ static int resizer_link_setup(struct media_entity *entity,
1649 } 1654 }
1650 break; 1655 break;
1651 1656
1652 case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: 1657 case RESZ_PAD_SOURCE:
1653 /* resizer always write to memory */ 1658 /* resizer always write to memory */
1654 break; 1659 break;
1655 1660
@@ -1728,7 +1733,7 @@ static int resizer_init_entities(struct isp_res_device *res)
1728 pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1733 pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1729 1734
1730 me->ops = &resizer_media_ops; 1735 me->ops = &resizer_media_ops;
1731 ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0); 1736 ret = media_entity_pads_init(me, RESZ_PADS_NUM, pads);
1732 if (ret < 0) 1737 if (ret < 0)
1733 return ret; 1738 return ret;
1734 1739
@@ -1755,21 +1760,8 @@ static int resizer_init_entities(struct isp_res_device *res)
1755 1760
1756 res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT; 1761 res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
1757 1762
1758 /* Connect the video nodes to the resizer subdev. */
1759 ret = media_entity_create_link(&res->video_in.video.entity, 0,
1760 &res->subdev.entity, RESZ_PAD_SINK, 0);
1761 if (ret < 0)
1762 goto error_link;
1763
1764 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
1765 &res->video_out.video.entity, 0, 0);
1766 if (ret < 0)
1767 goto error_link;
1768
1769 return 0; 1763 return 0;
1770 1764
1771error_link:
1772 omap3isp_video_cleanup(&res->video_out);
1773error_video_out: 1765error_video_out:
1774 omap3isp_video_cleanup(&res->video_in); 1766 omap3isp_video_cleanup(&res->video_in);
1775error_video_in: 1767error_video_in:
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index 94d4c295d3d0..1b9217d3b1b6 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1028,7 +1028,7 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1028 stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; 1028 stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
1029 me->ops = NULL; 1029 me->ops = NULL;
1030 1030
1031 return media_entity_init(me, 1, &stat->pad, 0); 1031 return media_entity_pads_init(me, 1, &stat->pad);
1032} 1032}
1033 1033
1034int omap3isp_stat_init(struct ispstat *stat, const char *name, 1034int omap3isp_stat_init(struct ispstat *stat, const char *name,
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index ecadca3e945b..994dfc0813f6 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)
210 210
211 remote = media_entity_remote_pad(&video->pad); 211 remote = media_entity_remote_pad(&video->pad);
212 212
213 if (remote == NULL || 213 if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
214 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
215 return NULL; 214 return NULL;
216 215
217 if (pad) 216 if (pad)
@@ -226,16 +225,23 @@ static int isp_video_get_graph_data(struct isp_video *video,
226{ 225{
227 struct media_entity_graph graph; 226 struct media_entity_graph graph;
228 struct media_entity *entity = &video->video.entity; 227 struct media_entity *entity = &video->video.entity;
229 struct media_device *mdev = entity->parent; 228 struct media_device *mdev = entity->graph_obj.mdev;
230 struct isp_video *far_end = NULL; 229 struct isp_video *far_end = NULL;
230 int ret;
231 231
232 mutex_lock(&mdev->graph_mutex); 232 mutex_lock(&mdev->graph_mutex);
233 ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
234 if (ret) {
235 mutex_unlock(&mdev->graph_mutex);
236 return ret;
237 }
238
233 media_entity_graph_walk_start(&graph, entity); 239 media_entity_graph_walk_start(&graph, entity);
234 240
235 while ((entity = media_entity_graph_walk_next(&graph))) { 241 while ((entity = media_entity_graph_walk_next(&graph))) {
236 struct isp_video *__video; 242 struct isp_video *__video;
237 243
238 pipe->entities |= 1 << entity->id; 244 media_entity_enum_set(&pipe->ent_enum, entity);
239 245
240 if (far_end != NULL) 246 if (far_end != NULL)
241 continue; 247 continue;
@@ -243,7 +249,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
243 if (entity == &video->video.entity) 249 if (entity == &video->video.entity)
244 continue; 250 continue;
245 251
246 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 252 if (!is_media_entity_v4l2_io(entity))
247 continue; 253 continue;
248 254
249 __video = to_isp_video(media_entity_to_video_device(entity)); 255 __video = to_isp_video(media_entity_to_video_device(entity));
@@ -253,6 +259,8 @@ static int isp_video_get_graph_data(struct isp_video *video,
253 259
254 mutex_unlock(&mdev->graph_mutex); 260 mutex_unlock(&mdev->graph_mutex);
255 261
262 media_entity_graph_walk_cleanup(&graph);
263
256 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 264 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
257 pipe->input = far_end; 265 pipe->input = far_end;
258 pipe->output = video; 266 pipe->output = video;
@@ -900,7 +908,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
900 908
901 for (i = 0; i < ARRAY_SIZE(ents); i++) { 909 for (i = 0; i < ARRAY_SIZE(ents); i++) {
902 /* Is the entity part of the pipeline? */ 910 /* Is the entity part of the pipeline? */
903 if (!(pipe->entities & (1 << ents[i]->id))) 911 if (!media_entity_enum_test(&pipe->ent_enum, ents[i]))
904 continue; 912 continue;
905 913
906 /* ISP entities have always sink pad == 0. Find source. */ 914 /* ISP entities have always sink pad == 0. Find source. */
@@ -918,7 +926,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
918 return -EINVAL; 926 return -EINVAL;
919 } 927 }
920 928
921 if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV) 929 if (!is_media_entity_v4l2_subdev(source))
922 return 0; 930 return 0;
923 931
924 pipe->external = media_entity_to_v4l2_subdev(source); 932 pipe->external = media_entity_to_v4l2_subdev(source);
@@ -952,7 +960,8 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
952 960
953 pipe->external_rate = ctrl.value64; 961 pipe->external_rate = ctrl.value64;
954 962
955 if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) { 963 if (media_entity_enum_test(&pipe->ent_enum,
964 &isp->isp_ccdc.subdev.entity)) {
956 unsigned int rate = UINT_MAX; 965 unsigned int rate = UINT_MAX;
957 /* 966 /*
958 * Check that maximum allowed CCDC pixel rate isn't 967 * Check that maximum allowed CCDC pixel rate isn't
@@ -1018,7 +1027,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1018 pipe = video->video.entity.pipe 1027 pipe = video->video.entity.pipe
1019 ? to_isp_pipeline(&video->video.entity) : &video->pipe; 1028 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
1020 1029
1021 pipe->entities = 0; 1030 ret = media_entity_enum_init(&pipe->ent_enum, &video->isp->media_dev);
1031 if (ret)
1032 goto err_enum_init;
1022 1033
1023 /* TODO: Implement PM QoS */ 1034 /* TODO: Implement PM QoS */
1024 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); 1035 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1092,6 +1103,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1092 } 1103 }
1093 1104
1094 mutex_unlock(&video->stream_lock); 1105 mutex_unlock(&video->stream_lock);
1106
1095 return 0; 1107 return 0;
1096 1108
1097err_set_stream: 1109err_set_stream:
@@ -1112,7 +1124,11 @@ err_pipeline_start:
1112 INIT_LIST_HEAD(&video->dmaqueue); 1124 INIT_LIST_HEAD(&video->dmaqueue);
1113 video->queue = NULL; 1125 video->queue = NULL;
1114 1126
1127 media_entity_enum_cleanup(&pipe->ent_enum);
1128
1129err_enum_init:
1115 mutex_unlock(&video->stream_lock); 1130 mutex_unlock(&video->stream_lock);
1131
1116 return ret; 1132 return ret;
1117} 1133}
1118 1134
@@ -1164,6 +1180,8 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1164 /* TODO: Implement PM QoS */ 1180 /* TODO: Implement PM QoS */
1165 media_entity_pipeline_stop(&video->video.entity); 1181 media_entity_pipeline_stop(&video->video.entity);
1166 1182
1183 media_entity_enum_cleanup(&pipe->ent_enum);
1184
1167done: 1185done:
1168 mutex_unlock(&video->stream_lock); 1186 mutex_unlock(&video->stream_lock);
1169 return 0; 1187 return 0;
@@ -1243,7 +1261,12 @@ static int isp_video_open(struct file *file)
1243 goto done; 1261 goto done;
1244 } 1262 }
1245 1263
1246 ret = omap3isp_pipeline_pm_use(&video->video.entity, 1); 1264 ret = media_entity_graph_walk_init(&handle->graph,
1265 &video->isp->media_dev);
1266 if (ret)
1267 goto done;
1268
1269 ret = omap3isp_pipeline_pm_use(&video->video.entity, 1, &handle->graph);
1247 if (ret < 0) { 1270 if (ret < 0) {
1248 omap3isp_put(video->isp); 1271 omap3isp_put(video->isp);
1249 goto done; 1272 goto done;
@@ -1274,6 +1297,7 @@ static int isp_video_open(struct file *file)
1274done: 1297done:
1275 if (ret < 0) { 1298 if (ret < 0) {
1276 v4l2_fh_del(&handle->vfh); 1299 v4l2_fh_del(&handle->vfh);
1300 media_entity_graph_walk_cleanup(&handle->graph);
1277 kfree(handle); 1301 kfree(handle);
1278 } 1302 }
1279 1303
@@ -1293,7 +1317,8 @@ static int isp_video_release(struct file *file)
1293 vb2_queue_release(&handle->queue); 1317 vb2_queue_release(&handle->queue);
1294 mutex_unlock(&video->queue_lock); 1318 mutex_unlock(&video->queue_lock);
1295 1319
1296 omap3isp_pipeline_pm_use(&video->video.entity, 0); 1320 omap3isp_pipeline_pm_use(&video->video.entity, 0, &handle->graph);
1321 media_entity_graph_walk_cleanup(&handle->graph);
1297 1322
1298 /* Release the file handle. */ 1323 /* Release the file handle. */
1299 v4l2_fh_del(vfh); 1324 v4l2_fh_del(vfh);
@@ -1367,7 +1392,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
1367 if (IS_ERR(video->alloc_ctx)) 1392 if (IS_ERR(video->alloc_ctx))
1368 return PTR_ERR(video->alloc_ctx); 1393 return PTR_ERR(video->alloc_ctx);
1369 1394
1370 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); 1395 ret = media_entity_pads_init(&video->video.entity, 1, &video->pad);
1371 if (ret < 0) { 1396 if (ret < 0) {
1372 vb2_dma_contig_cleanup_ctx(video->alloc_ctx); 1397 vb2_dma_contig_cleanup_ctx(video->alloc_ctx);
1373 return ret; 1398 return ret;
diff --git a/drivers/media/platform/omap3isp/ispvideo.h b/drivers/media/platform/omap3isp/ispvideo.h
index bcf0e0acc8f3..156429878d64 100644
--- a/drivers/media/platform/omap3isp/ispvideo.h
+++ b/drivers/media/platform/omap3isp/ispvideo.h
@@ -80,7 +80,7 @@ enum isp_pipeline_state {
80 * struct isp_pipeline - An ISP hardware pipeline 80 * struct isp_pipeline - An ISP hardware pipeline
81 * @field: The field being processed by the pipeline 81 * @field: The field being processed by the pipeline
82 * @error: A hardware error occurred during capture 82 * @error: A hardware error occurred during capture
83 * @entities: Bitmask of entities in the pipeline (indexed by entity ID) 83 * @ent_enum: Entities in the pipeline
84 */ 84 */
85struct isp_pipeline { 85struct isp_pipeline {
86 struct media_pipeline pipe; 86 struct media_pipeline pipe;
@@ -89,7 +89,7 @@ struct isp_pipeline {
89 enum isp_pipeline_stream_state stream_state; 89 enum isp_pipeline_stream_state stream_state;
90 struct isp_video *input; 90 struct isp_video *input;
91 struct isp_video *output; 91 struct isp_video *output;
92 u32 entities; 92 struct media_entity_enum ent_enum;
93 unsigned long l3_ick; 93 unsigned long l3_ick;
94 unsigned int max_rate; 94 unsigned int max_rate;
95 enum v4l2_field field; 95 enum v4l2_field field;
@@ -189,6 +189,7 @@ struct isp_video_fh {
189 struct vb2_queue queue; 189 struct vb2_queue queue;
190 struct v4l2_format format; 190 struct v4l2_format format;
191 struct v4l2_fract timeperframe; 191 struct v4l2_fract timeperframe;
192 struct media_entity_graph graph;
192}; 193};
193 194
194#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh) 195#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh)
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index ec3abbed87d9..bd060ef5d1e1 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -822,7 +822,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)
822 822
823 /* Retrieve format at the sensor subdev source pad */ 823 /* Retrieve format at the sensor subdev source pad */
824 pad = media_entity_remote_pad(&camif->pads[0]); 824 pad = media_entity_remote_pad(&camif->pads[0]);
825 if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 825 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
826 return -EPIPE; 826 return -EPIPE;
827 827
828 src_fmt.pad = pad->index; 828 src_fmt.pad = pad->index;
@@ -1144,7 +1144,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
1144 goto err_vd_rel; 1144 goto err_vd_rel;
1145 1145
1146 vp->pad.flags = MEDIA_PAD_FL_SINK; 1146 vp->pad.flags = MEDIA_PAD_FL_SINK;
1147 ret = media_entity_init(&vfd->entity, 1, &vp->pad, 0); 1147 ret = media_entity_pads_init(&vfd->entity, 1, &vp->pad);
1148 if (ret) 1148 if (ret)
1149 goto err_vd_rel; 1149 goto err_vd_rel;
1150 1150
@@ -1559,8 +1559,8 @@ int s3c_camif_create_subdev(struct camif_dev *camif)
1559 camif->pads[CAMIF_SD_PAD_SOURCE_C].flags = MEDIA_PAD_FL_SOURCE; 1559 camif->pads[CAMIF_SD_PAD_SOURCE_C].flags = MEDIA_PAD_FL_SOURCE;
1560 camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE; 1560 camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE;
1561 1561
1562 ret = media_entity_init(&sd->entity, CAMIF_SD_PADS_NUM, 1562 ret = media_entity_pads_init(&sd->entity, CAMIF_SD_PADS_NUM,
1563 camif->pads, 0); 1563 camif->pads);
1564 if (ret) 1564 if (ret)
1565 return ret; 1565 return ret;
1566 1566
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index 1ba9bb08f5da..0b44b9accf50 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)
263{ 263{
264 int i, ret; 264 int i, ret;
265 265
266 ret = media_entity_create_link(&camif->sensor.sd->entity, 0, 266 ret = media_create_pad_link(&camif->sensor.sd->entity, 0,
267 &camif->subdev.entity, CAMIF_SD_PAD_SINK, 267 &camif->subdev.entity, CAMIF_SD_PAD_SINK,
268 MEDIA_LNK_FL_IMMUTABLE | 268 MEDIA_LNK_FL_IMMUTABLE |
269 MEDIA_LNK_FL_ENABLED); 269 MEDIA_LNK_FL_ENABLED);
@@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif)
271 return ret; 271 return ret;
272 272
273 for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) { 273 for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
274 ret = media_entity_create_link(&camif->subdev.entity, i, 274 ret = media_create_pad_link(&camif->subdev.entity, i,
275 &camif->vp[i - 1].vdev.entity, 0, 275 &camif->vp[i - 1].vdev.entity, 0,
276 MEDIA_LNK_FL_IMMUTABLE | 276 MEDIA_LNK_FL_IMMUTABLE |
277 MEDIA_LNK_FL_ENABLED); 277 MEDIA_LNK_FL_ENABLED);
@@ -305,7 +305,7 @@ static void camif_unregister_media_entities(struct camif_dev *camif)
305/* 305/*
306 * Media device 306 * Media device
307 */ 307 */
308static int camif_media_dev_register(struct camif_dev *camif) 308static int camif_media_dev_init(struct camif_dev *camif)
309{ 309{
310 struct media_device *md = &camif->media_dev; 310 struct media_device *md = &camif->media_dev;
311 struct v4l2_device *v4l2_dev = &camif->v4l2_dev; 311 struct v4l2_device *v4l2_dev = &camif->v4l2_dev;
@@ -324,14 +324,12 @@ static int camif_media_dev_register(struct camif_dev *camif)
324 strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name)); 324 strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name));
325 v4l2_dev->mdev = md; 325 v4l2_dev->mdev = md;
326 326
327 media_device_init(md);
328
327 ret = v4l2_device_register(camif->dev, v4l2_dev); 329 ret = v4l2_device_register(camif->dev, v4l2_dev);
328 if (ret < 0) 330 if (ret < 0)
329 return ret; 331 return ret;
330 332
331 ret = media_device_register(md);
332 if (ret < 0)
333 v4l2_device_unregister(v4l2_dev);
334
335 return ret; 333 return ret;
336} 334}
337 335
@@ -483,7 +481,7 @@ static int s3c_camif_probe(struct platform_device *pdev)
483 goto err_alloc; 481 goto err_alloc;
484 } 482 }
485 483
486 ret = camif_media_dev_register(camif); 484 ret = camif_media_dev_init(camif);
487 if (ret < 0) 485 if (ret < 0)
488 goto err_mdev; 486 goto err_mdev;
489 487
@@ -510,6 +508,11 @@ static int s3c_camif_probe(struct platform_device *pdev)
510 goto err_unlock; 508 goto err_unlock;
511 509
512 mutex_unlock(&camif->media_dev.graph_mutex); 510 mutex_unlock(&camif->media_dev.graph_mutex);
511
512 ret = media_device_register(&camif->media_dev);
513 if (ret < 0)
514 goto err_sens;
515
513 pm_runtime_put(dev); 516 pm_runtime_put(dev);
514 return 0; 517 return 0;
515 518
@@ -518,6 +521,7 @@ err_unlock:
518err_sens: 521err_sens:
519 v4l2_device_unregister(&camif->v4l2_dev); 522 v4l2_device_unregister(&camif->v4l2_dev);
520 media_device_unregister(&camif->media_dev); 523 media_device_unregister(&camif->media_dev);
524 media_device_cleanup(&camif->media_dev);
521 camif_unregister_media_entities(camif); 525 camif_unregister_media_entities(camif);
522err_mdev: 526err_mdev:
523 vb2_dma_contig_cleanup_ctx(camif->alloc_ctx); 527 vb2_dma_contig_cleanup_ctx(camif->alloc_ctx);
@@ -539,6 +543,7 @@ static int s3c_camif_remove(struct platform_device *pdev)
539 struct s3c_camif_plat_data *pdata = &camif->pdata; 543 struct s3c_camif_plat_data *pdata = &camif->pdata;
540 544
541 media_device_unregister(&camif->media_dev); 545 media_device_unregister(&camif->media_dev);
546 media_device_cleanup(&camif->media_dev);
542 camif_unregister_media_entities(camif); 547 camif_unregister_media_entities(camif);
543 v4l2_device_unregister(&camif->v4l2_dev); 548 v4l2_device_unregister(&camif->v4l2_dev);
544 549
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..42dff9d020af 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)
101 if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK)) 101 if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
102 continue; 102 continue;
103 103
104 ret = media_entity_create_link(&source->subdev.entity, 104 ret = media_create_pad_link(&source->subdev.entity,
105 source->source_pad, 105 source->source_pad,
106 entity, pad, flags); 106 entity, pad, flags);
107 if (ret < 0) 107 if (ret < 0)
@@ -127,6 +127,7 @@ static void vsp1_destroy_entities(struct vsp1_device *vsp1)
127 127
128 v4l2_device_unregister(&vsp1->v4l2_dev); 128 v4l2_device_unregister(&vsp1->v4l2_dev);
129 media_device_unregister(&vsp1->media_dev); 129 media_device_unregister(&vsp1->media_dev);
130 media_device_cleanup(&vsp1->media_dev);
130} 131}
131 132
132static int vsp1_create_entities(struct vsp1_device *vsp1) 133static int vsp1_create_entities(struct vsp1_device *vsp1)
@@ -141,12 +142,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
141 strlcpy(mdev->model, "VSP1", sizeof(mdev->model)); 142 strlcpy(mdev->model, "VSP1", sizeof(mdev->model));
142 snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", 143 snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
143 dev_name(mdev->dev)); 144 dev_name(mdev->dev));
144 ret = media_device_register(mdev); 145 media_device_init(mdev);
145 if (ret < 0) {
146 dev_err(vsp1->dev, "media device registration failed (%d)\n",
147 ret);
148 return ret;
149 }
150 146
151 vdev->mdev = mdev; 147 vdev->mdev = mdev;
152 ret = v4l2_device_register(vsp1->dev, vdev); 148 ret = v4l2_device_register(vsp1->dev, vdev);
@@ -250,34 +246,44 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
250 list_add_tail(&wpf->entity.list_dev, &vsp1->entities); 246 list_add_tail(&wpf->entity.list_dev, &vsp1->entities);
251 } 247 }
252 248
253 /* Create links. */ 249 /* Register all subdevs. */
254 list_for_each_entry(entity, &vsp1->entities, list_dev) { 250 list_for_each_entry(entity, &vsp1->entities, list_dev) {
255 if (entity->type == VSP1_ENTITY_LIF || 251 ret = v4l2_device_register_subdev(&vsp1->v4l2_dev,
256 entity->type == VSP1_ENTITY_RPF) 252 &entity->subdev);
257 continue;
258
259 ret = vsp1_create_links(vsp1, entity);
260 if (ret < 0) 253 if (ret < 0)
261 goto done; 254 goto done;
262 } 255 }
263 256
257 /* Create links. */
258 list_for_each_entry(entity, &vsp1->entities, list_dev) {
259 if (entity->type == VSP1_ENTITY_LIF) {
260 ret = vsp1_wpf_create_links(vsp1, entity);
261 if (ret < 0)
262 goto done;
263 } else if (entity->type == VSP1_ENTITY_RPF) {
264 ret = vsp1_rpf_create_links(vsp1, entity);
265 if (ret < 0)
266 goto done;
267 } else {
268 ret = vsp1_create_links(vsp1, entity);
269 if (ret < 0)
270 goto done;
271 }
272 }
273
264 if (vsp1->pdata.features & VSP1_HAS_LIF) { 274 if (vsp1->pdata.features & VSP1_HAS_LIF) {
265 ret = media_entity_create_link( 275 ret = media_create_pad_link(
266 &vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE, 276 &vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
267 &vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0); 277 &vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
268 if (ret < 0) 278 if (ret < 0)
269 return ret; 279 return ret;
270 } 280 }
271 281
272 /* Register all subdevs. */
273 list_for_each_entry(entity, &vsp1->entities, list_dev) {
274 ret = v4l2_device_register_subdev(&vsp1->v4l2_dev,
275 &entity->subdev);
276 if (ret < 0)
277 goto done;
278 }
279
280 ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev); 282 ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev);
283 if (ret < 0)
284 goto done;
285
286 ret = media_device_register(mdev);
281 287
282done: 288done:
283 if (ret < 0) 289 if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index fd95a75b04f4..d7308530952f 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -219,8 +219,8 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
219 entity->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE; 219 entity->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE;
220 220
221 /* Initialize the media entity. */ 221 /* Initialize the media entity. */
222 return media_entity_init(&entity->subdev.entity, num_pads, 222 return media_entity_pads_init(&entity->subdev.entity, num_pads,
223 entity->pads, 0); 223 entity->pads);
224} 224}
225 225
226void vsp1_entity_destroy(struct vsp1_entity *entity) 226void vsp1_entity_destroy(struct vsp1_entity *entity)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index cd5248a9a271..924538223d3e 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)
277 277
278 rpf->entity.video = video; 278 rpf->entity.video = video;
279 279
280 /* Connect the video device to the RPF. */
281 ret = media_entity_create_link(&rpf->video.video.entity, 0,
282 &rpf->entity.subdev.entity,
283 RWPF_PAD_SINK,
284 MEDIA_LNK_FL_ENABLED |
285 MEDIA_LNK_FL_IMMUTABLE);
286 if (ret < 0)
287 goto error;
288
289 return rpf; 280 return rpf;
290 281
291error: 282error:
292 vsp1_entity_destroy(&rpf->entity); 283 vsp1_entity_destroy(&rpf->entity);
293 return ERR_PTR(ret); 284 return ERR_PTR(ret);
294} 285}
286
287/*
288 * vsp1_rpf_create_links() - RPF pads links creation
289 * @vsp1: Pointer to VSP1 device
290 * @entity: Pointer to VSP1 entity
291 *
292 * return negative error code or zero on success
293 */
294int vsp1_rpf_create_links(struct vsp1_device *vsp1,
295 struct vsp1_entity *entity)
296{
297 struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
298
299 /* Connect the video device to the RPF. */
300 return media_create_pad_link(&rpf->video.video.entity, 0,
301 &rpf->entity.subdev.entity,
302 RWPF_PAD_SINK,
303 MEDIA_LNK_FL_ENABLED |
304 MEDIA_LNK_FL_IMMUTABLE);
305}
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index f452dce1a931..731d36e5258d 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)
50struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); 50struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index);
51struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); 51struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index);
52 52
53int vsp1_rpf_create_links(struct vsp1_device *vsp1,
54 struct vsp1_entity *entity);
55int vsp1_wpf_create_links(struct vsp1_device *vsp1,
56 struct vsp1_entity *entity);
57
53int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, 58int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev,
54 struct v4l2_subdev_pad_config *cfg, 59 struct v4l2_subdev_pad_config *cfg,
55 struct v4l2_subdev_mbus_code_enum *code); 60 struct v4l2_subdev_mbus_code_enum *code);
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 45eb65fa23db..637d0d6f79fb 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)
160 struct media_pad *remote; 160 struct media_pad *remote;
161 161
162 remote = media_entity_remote_pad(local); 162 remote = media_entity_remote_pad(local);
163 if (remote == NULL || 163 if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
164 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
165 return NULL; 164 return NULL;
166 165
167 if (pad) 166 if (pad)
@@ -283,24 +282,35 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
283 struct vsp1_rwpf *output) 282 struct vsp1_rwpf *output)
284{ 283{
285 struct vsp1_entity *entity; 284 struct vsp1_entity *entity;
286 unsigned int entities = 0; 285 struct media_entity_enum ent_enum;
287 struct media_pad *pad; 286 struct media_pad *pad;
287 int rval;
288 bool bru_found = false; 288 bool bru_found = false;
289 289
290 input->location.left = 0; 290 input->location.left = 0;
291 input->location.top = 0; 291 input->location.top = 0;
292 292
293 rval = media_entity_enum_init(
294 &ent_enum, input->entity.pads[RWPF_PAD_SOURCE].graph_obj.mdev);
295 if (rval)
296 return rval;
297
293 pad = media_entity_remote_pad(&input->entity.pads[RWPF_PAD_SOURCE]); 298 pad = media_entity_remote_pad(&input->entity.pads[RWPF_PAD_SOURCE]);
294 299
295 while (1) { 300 while (1) {
296 if (pad == NULL) 301 if (pad == NULL) {
297 return -EPIPE; 302 rval = -EPIPE;
303 goto out;
304 }
298 305
299 /* We've reached a video node, that shouldn't have happened. */ 306 /* We've reached a video node, that shouldn't have happened. */
300 if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 307 if (!is_media_entity_v4l2_subdev(pad->entity)) {
301 return -EPIPE; 308 rval = -EPIPE;
309 goto out;
310 }
302 311
303 entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity)); 312 entity = to_vsp1_entity(
313 media_entity_to_v4l2_subdev(pad->entity));
304 314
305 /* A BRU is present in the pipeline, store the compose rectangle 315 /* A BRU is present in the pipeline, store the compose rectangle
306 * location in the input RPF for use when configuring the RPF. 316 * location in the input RPF for use when configuring the RPF.
@@ -323,15 +333,18 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
323 break; 333 break;
324 334
325 /* Ensure the branch has no loop. */ 335 /* Ensure the branch has no loop. */
326 if (entities & (1 << entity->subdev.entity.id)) 336 if (media_entity_enum_test_and_set(&ent_enum,
327 return -EPIPE; 337 &entity->subdev.entity)) {
328 338 rval = -EPIPE;
329 entities |= 1 << entity->subdev.entity.id; 339 goto out;
340 }
330 341
331 /* UDS can't be chained. */ 342 /* UDS can't be chained. */
332 if (entity->type == VSP1_ENTITY_UDS) { 343 if (entity->type == VSP1_ENTITY_UDS) {
333 if (pipe->uds) 344 if (pipe->uds) {
334 return -EPIPE; 345 rval = -EPIPE;
346 goto out;
347 }
335 348
336 pipe->uds = entity; 349 pipe->uds = entity;
337 pipe->uds_input = bru_found ? pipe->bru 350 pipe->uds_input = bru_found ? pipe->bru
@@ -349,9 +362,12 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
349 362
350 /* The last entity must be the output WPF. */ 363 /* The last entity must be the output WPF. */
351 if (entity != &output->entity) 364 if (entity != &output->entity)
352 return -EPIPE; 365 rval = -EPIPE;
353 366
354 return 0; 367out:
368 media_entity_enum_cleanup(&ent_enum);
369
370 return rval;
355} 371}
356 372
357static void __vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe) 373static void __vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
@@ -380,13 +396,19 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
380{ 396{
381 struct media_entity_graph graph; 397 struct media_entity_graph graph;
382 struct media_entity *entity = &video->video.entity; 398 struct media_entity *entity = &video->video.entity;
383 struct media_device *mdev = entity->parent; 399 struct media_device *mdev = entity->graph_obj.mdev;
384 unsigned int i; 400 unsigned int i;
385 int ret; 401 int ret;
386 402
387 mutex_lock(&mdev->graph_mutex); 403 mutex_lock(&mdev->graph_mutex);
388 404
389 /* Walk the graph to locate the entities and video nodes. */ 405 /* Walk the graph to locate the entities and video nodes. */
406 ret = media_entity_graph_walk_init(&graph, mdev);
407 if (ret) {
408 mutex_unlock(&mdev->graph_mutex);
409 return ret;
410 }
411
390 media_entity_graph_walk_start(&graph, entity); 412 media_entity_graph_walk_start(&graph, entity);
391 413
392 while ((entity = media_entity_graph_walk_next(&graph))) { 414 while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -394,7 +416,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
394 struct vsp1_rwpf *rwpf; 416 struct vsp1_rwpf *rwpf;
395 struct vsp1_entity *e; 417 struct vsp1_entity *e;
396 418
397 if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) { 419 if (is_media_entity_v4l2_io(entity)) {
398 pipe->num_video++; 420 pipe->num_video++;
399 continue; 421 continue;
400 } 422 }
@@ -420,6 +442,8 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
420 442
421 mutex_unlock(&mdev->graph_mutex); 443 mutex_unlock(&mdev->graph_mutex);
422 444
445 media_entity_graph_walk_cleanup(&graph);
446
423 /* We need one output and at least one input. */ 447 /* We need one output and at least one input. */
424 if (pipe->num_inputs == 0 || !pipe->output) { 448 if (pipe->num_inputs == 0 || !pipe->output) {
425 ret = -EPIPE; 449 ret = -EPIPE;
@@ -663,7 +687,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
663 pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]); 687 pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
664 688
665 while (pad) { 689 while (pad) {
666 if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) 690 if (!is_media_entity_v4l2_subdev(pad->entity))
667 break; 691 break;
668 692
669 entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity)); 693 entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
@@ -1193,7 +1217,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
1193 video->pipe.state = VSP1_PIPELINE_STOPPED; 1217 video->pipe.state = VSP1_PIPELINE_STOPPED;
1194 1218
1195 /* Initialize the media entity... */ 1219 /* Initialize the media entity... */
1196 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); 1220 ret = media_entity_pads_init(&video->video.entity, 1, &video->pad);
1197 if (ret < 0) 1221 if (ret < 0)
1198 return ret; 1222 return ret;
1199 1223
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 95b62f4f77e7..cbf514a6582d 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)
220 struct v4l2_subdev *subdev; 220 struct v4l2_subdev *subdev;
221 struct vsp1_video *video; 221 struct vsp1_video *video;
222 struct vsp1_rwpf *wpf; 222 struct vsp1_rwpf *wpf;
223 unsigned int flags;
224 int ret; 223 int ret;
225 224
226 wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL); 225 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)
276 goto error; 275 goto error;
277 276
278 wpf->entity.video = video; 277 wpf->entity.video = video;
279
280 /* Connect the video device to the WPF. All connections are immutable
281 * except for the WPF0 source link if a LIF is present.
282 */
283 flags = MEDIA_LNK_FL_ENABLED;
284 if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
285 flags |= MEDIA_LNK_FL_IMMUTABLE;
286
287 ret = media_entity_create_link(&wpf->entity.subdev.entity,
288 RWPF_PAD_SOURCE,
289 &wpf->video.video.entity, 0, flags);
290 if (ret < 0)
291 goto error;
292
293 wpf->entity.sink = &wpf->video.video.entity; 278 wpf->entity.sink = &wpf->video.video.entity;
294 279
295 return wpf; 280 return wpf;
@@ -298,3 +283,28 @@ error:
298 vsp1_entity_destroy(&wpf->entity); 283 vsp1_entity_destroy(&wpf->entity);
299 return ERR_PTR(ret); 284 return ERR_PTR(ret);
300} 285}
286
287/*
288 * vsp1_wpf_create_links() - RPF pads links creation
289 * @vsp1: Pointer to VSP1 device
290 * @entity: Pointer to VSP1 entity
291 *
292 * return negative error code or zero on success
293 */
294int vsp1_wpf_create_links(struct vsp1_device *vsp1,
295 struct vsp1_entity *entity)
296{
297 struct vsp1_rwpf *wpf = to_rwpf(&entity->subdev);
298 unsigned int flags;
299
300 /* Connect the video device to the WPF. All connections are immutable
301 * except for the WPF0 source link if a LIF is present.
302 */
303 flags = MEDIA_LNK_FL_ENABLED;
304 if (!(vsp1->pdata.features & VSP1_HAS_LIF) || entity->index != 0)
305 flags |= MEDIA_LNK_FL_IMMUTABLE;
306
307 return media_create_pad_link(&wpf->entity.subdev.entity,
308 RWPF_PAD_SOURCE,
309 &wpf->video.video.entity, 0, flags);
310}
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 722758f33924..7f6898b13cac 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)
49 struct media_pad *remote; 49 struct media_pad *remote;
50 50
51 remote = media_entity_remote_pad(local); 51 remote = media_entity_remote_pad(local);
52 if (remote == NULL || 52 if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
53 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
54 return NULL; 53 return NULL;
55 54
56 if (pad) 55 if (pad)
@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)
113 break; 112 break;
114 113
115 pad = media_entity_remote_pad(pad); 114 pad = media_entity_remote_pad(pad);
116 if (pad == NULL || 115 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
117 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
118 break; 116 break;
119 117
120 entity = pad->entity; 118 entity = pad->entity;
@@ -181,19 +179,26 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
181{ 179{
182 struct media_entity_graph graph; 180 struct media_entity_graph graph;
183 struct media_entity *entity = &start->video.entity; 181 struct media_entity *entity = &start->video.entity;
184 struct media_device *mdev = entity->parent; 182 struct media_device *mdev = entity->graph_obj.mdev;
185 unsigned int num_inputs = 0; 183 unsigned int num_inputs = 0;
186 unsigned int num_outputs = 0; 184 unsigned int num_outputs = 0;
185 int ret;
187 186
188 mutex_lock(&mdev->graph_mutex); 187 mutex_lock(&mdev->graph_mutex);
189 188
190 /* Walk the graph to locate the video nodes. */ 189 /* Walk the graph to locate the video nodes. */
190 ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
191 if (ret) {
192 mutex_unlock(&mdev->graph_mutex);
193 return ret;
194 }
195
191 media_entity_graph_walk_start(&graph, entity); 196 media_entity_graph_walk_start(&graph, entity);
192 197
193 while ((entity = media_entity_graph_walk_next(&graph))) { 198 while ((entity = media_entity_graph_walk_next(&graph))) {
194 struct xvip_dma *dma; 199 struct xvip_dma *dma;
195 200
196 if (entity->type != MEDIA_ENT_T_DEVNODE_V4L) 201 if (entity->function != MEDIA_ENT_F_IO_V4L)
197 continue; 202 continue;
198 203
199 dma = to_xvip_dma(media_entity_to_video_device(entity)); 204 dma = to_xvip_dma(media_entity_to_video_device(entity));
@@ -208,6 +213,8 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
208 213
209 mutex_unlock(&mdev->graph_mutex); 214 mutex_unlock(&mdev->graph_mutex);
210 215
216 media_entity_graph_walk_cleanup(&graph);
217
211 /* We need exactly one output and zero or one input. */ 218 /* We need exactly one output and zero or one input. */
212 if (num_outputs != 1 || num_inputs > 1) 219 if (num_outputs != 1 || num_inputs > 1)
213 return -EPIPE; 220 return -EPIPE;
@@ -677,7 +684,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
677 dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE 684 dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
678 ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; 685 ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
679 686
680 ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0); 687 ret = media_entity_pads_init(&dma->video.entity, 1, &dma->pad);
681 if (ret < 0) 688 if (ret < 0)
682 goto error; 689 goto error;
683 690
diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c
index 8bd7e3736019..2ec1f6c4b274 100644
--- a/drivers/media/platform/xilinx/xilinx-tpg.c
+++ b/drivers/media/platform/xilinx/xilinx-tpg.c
@@ -838,7 +838,7 @@ static int xtpg_probe(struct platform_device *pdev)
838 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 838 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
839 subdev->entity.ops = &xtpg_media_ops; 839 subdev->entity.ops = &xtpg_media_ops;
840 840
841 ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0); 841 ret = media_entity_pads_init(&subdev->entity, xtpg->npads, xtpg->pads);
842 if (ret < 0) 842 if (ret < 0)
843 goto error; 843 goto error;
844 844
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index b9bf24fefa5a..e795a4501e8b 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,
156 local->name, local_pad->index, 156 local->name, local_pad->index,
157 remote->name, remote_pad->index); 157 remote->name, remote_pad->index);
158 158
159 ret = media_entity_create_link(local, local_pad->index, 159 ret = media_create_pad_link(local, local_pad->index,
160 remote, remote_pad->index, 160 remote, remote_pad->index,
161 link_flags); 161 link_flags);
162 if (ret < 0) { 162 if (ret < 0) {
@@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
270 source->name, source_pad->index, 270 source->name, source_pad->index,
271 sink->name, sink_pad->index); 271 sink->name, sink_pad->index);
272 272
273 ret = media_entity_create_link(source, source_pad->index, 273 ret = media_create_pad_link(source, source_pad->index,
274 sink, sink_pad->index, 274 sink, sink_pad->index,
275 link_flags); 275 link_flags);
276 if (ret < 0) { 276 if (ret < 0) {
@@ -311,7 +311,7 @@ static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier)
311 if (ret < 0) 311 if (ret < 0)
312 dev_err(xdev->dev, "failed to register subdev nodes\n"); 312 dev_err(xdev->dev, "failed to register subdev nodes\n");
313 313
314 return ret; 314 return media_device_register(&xdev->media_dev);
315} 315}
316 316
317static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, 317static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier,
@@ -573,6 +573,7 @@ static void xvip_composite_v4l2_cleanup(struct xvip_composite_device *xdev)
573{ 573{
574 v4l2_device_unregister(&xdev->v4l2_dev); 574 v4l2_device_unregister(&xdev->v4l2_dev);
575 media_device_unregister(&xdev->media_dev); 575 media_device_unregister(&xdev->media_dev);
576 media_device_cleanup(&xdev->media_dev);
576} 577}
577 578
578static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev) 579static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev)
@@ -584,19 +585,14 @@ static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev)
584 sizeof(xdev->media_dev.model)); 585 sizeof(xdev->media_dev.model));
585 xdev->media_dev.hw_revision = 0; 586 xdev->media_dev.hw_revision = 0;
586 587
587 ret = media_device_register(&xdev->media_dev); 588 media_device_init(&xdev->media_dev);
588 if (ret < 0) {
589 dev_err(xdev->dev, "media device registration failed (%d)\n",
590 ret);
591 return ret;
592 }
593 589
594 xdev->v4l2_dev.mdev = &xdev->media_dev; 590 xdev->v4l2_dev.mdev = &xdev->media_dev;
595 ret = v4l2_device_register(xdev->dev, &xdev->v4l2_dev); 591 ret = v4l2_device_register(xdev->dev, &xdev->v4l2_dev);
596 if (ret < 0) { 592 if (ret < 0) {
597 dev_err(xdev->dev, "V4L2 device registration failed (%d)\n", 593 dev_err(xdev->dev, "V4L2 device registration failed (%d)\n",
598 ret); 594 ret);
599 media_device_unregister(&xdev->media_dev); 595 media_device_cleanup(&xdev->media_dev);
600 return ret; 596 return ret;
601 } 597 }
602 598
diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
index 6b469e8c4c6e..ca861aea68a5 100644
--- a/drivers/media/usb/au0828/au0828-cards.c
+++ b/drivers/media/usb/au0828/au0828-cards.c
@@ -228,6 +228,10 @@ void au0828_card_analog_fe_setup(struct au0828_dev *dev)
228 "au8522", 0x8e >> 1, NULL); 228 "au8522", 0x8e >> 1, NULL);
229 if (sd == NULL) 229 if (sd == NULL)
230 pr_err("analog subdev registration failed\n"); 230 pr_err("analog subdev registration failed\n");
231#ifdef CONFIG_MEDIA_CONTROLLER
232 if (sd)
233 dev->decoder = &sd->entity;
234#endif
231 } 235 }
232 236
233 /* Setup tuners */ 237 /* Setup tuners */
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0934024fb89d..9e29e70a78d7 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -27,6 +27,9 @@
27#include <media/v4l2-common.h> 27#include <media/v4l2-common.h>
28#include <linux/mutex.h> 28#include <linux/mutex.h>
29 29
30/* Due to enum tuner_pad_index */
31#include <media/tuner.h>
32
30/* 33/*
31 * 1 = General debug messages 34 * 1 = General debug messages
32 * 2 = USB handling 35 * 2 = USB handling
@@ -127,8 +130,23 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
127 return status; 130 return status;
128} 131}
129 132
133static void au0828_unregister_media_device(struct au0828_dev *dev)
134{
135
136#ifdef CONFIG_MEDIA_CONTROLLER
137 if (dev->media_dev) {
138 media_device_unregister(dev->media_dev);
139 media_device_cleanup(dev->media_dev);
140 kfree(dev->media_dev);
141 dev->media_dev = NULL;
142 }
143#endif
144}
145
130static void au0828_usb_release(struct au0828_dev *dev) 146static void au0828_usb_release(struct au0828_dev *dev)
131{ 147{
148 au0828_unregister_media_device(dev);
149
132 /* I2C */ 150 /* I2C */
133 au0828_i2c_unregister(dev); 151 au0828_i2c_unregister(dev);
134 152
@@ -136,6 +154,20 @@ static void au0828_usb_release(struct au0828_dev *dev)
136} 154}
137 155
138#ifdef CONFIG_VIDEO_AU0828_V4L2 156#ifdef CONFIG_VIDEO_AU0828_V4L2
157
158static void au0828_usb_v4l2_media_release(struct au0828_dev *dev)
159{
160#ifdef CONFIG_MEDIA_CONTROLLER
161 int i;
162
163 for (i = 0; i < AU0828_MAX_INPUT; i++) {
164 if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
165 return;
166 media_device_unregister_entity(&dev->input_ent[i]);
167 }
168#endif
169}
170
139static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev) 171static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev)
140{ 172{
141 struct au0828_dev *dev = 173 struct au0828_dev *dev =
@@ -143,6 +175,7 @@ static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev)
143 175
144 v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl); 176 v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl);
145 v4l2_device_unregister(&dev->v4l2_dev); 177 v4l2_device_unregister(&dev->v4l2_dev);
178 au0828_usb_v4l2_media_release(dev);
146 au0828_usb_release(dev); 179 au0828_usb_release(dev);
147} 180}
148#endif 181#endif
@@ -174,12 +207,123 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
174 au0828_analog_unregister(dev); 207 au0828_analog_unregister(dev);
175 v4l2_device_disconnect(&dev->v4l2_dev); 208 v4l2_device_disconnect(&dev->v4l2_dev);
176 v4l2_device_put(&dev->v4l2_dev); 209 v4l2_device_put(&dev->v4l2_dev);
210 /*
211 * No need to call au0828_usb_release() if V4L2 is enabled,
212 * as this is already called via au0828_usb_v4l2_release()
213 */
177 return; 214 return;
178 } 215 }
179#endif 216#endif
180 au0828_usb_release(dev); 217 au0828_usb_release(dev);
181} 218}
182 219
220static int au0828_media_device_init(struct au0828_dev *dev,
221 struct usb_device *udev)
222{
223#ifdef CONFIG_MEDIA_CONTROLLER
224 struct media_device *mdev;
225
226 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
227 if (!mdev)
228 return -ENOMEM;
229
230 mdev->dev = &udev->dev;
231
232 if (!dev->board.name)
233 strlcpy(mdev->model, "unknown au0828", sizeof(mdev->model));
234 else
235 strlcpy(mdev->model, dev->board.name, sizeof(mdev->model));
236 if (udev->serial)
237 strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
238 strcpy(mdev->bus_info, udev->devpath);
239 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
240 mdev->driver_version = LINUX_VERSION_CODE;
241
242 media_device_init(mdev);
243
244 dev->media_dev = mdev;
245#endif
246 return 0;
247}
248
249
250static int au0828_create_media_graph(struct au0828_dev *dev)
251{
252#ifdef CONFIG_MEDIA_CONTROLLER
253 struct media_device *mdev = dev->media_dev;
254 struct media_entity *entity;
255 struct media_entity *tuner = NULL, *decoder = NULL;
256 int i, ret;
257
258 if (!mdev)
259 return 0;
260
261 media_device_for_each_entity(entity, mdev) {
262 switch (entity->function) {
263 case MEDIA_ENT_F_TUNER:
264 tuner = entity;
265 break;
266 case MEDIA_ENT_F_ATV_DECODER:
267 decoder = entity;
268 break;
269 }
270 }
271
272 /* Analog setup, using tuner as a link */
273
274 /* Something bad happened! */
275 if (!decoder)
276 return -EINVAL;
277
278 if (tuner) {
279 ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
280 decoder, 0,
281 MEDIA_LNK_FL_ENABLED);
282 if (ret)
283 return ret;
284 }
285 ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
286 MEDIA_LNK_FL_ENABLED);
287 if (ret)
288 return ret;
289 ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
290 MEDIA_LNK_FL_ENABLED);
291 if (ret)
292 return ret;
293
294 for (i = 0; i < AU0828_MAX_INPUT; i++) {
295 struct media_entity *ent = &dev->input_ent[i];
296
297 if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
298 break;
299
300 switch (AUVI_INPUT(i).type) {
301 case AU0828_VMUX_CABLE:
302 case AU0828_VMUX_TELEVISION:
303 case AU0828_VMUX_DVB:
304 if (!tuner)
305 break;
306
307 ret = media_create_pad_link(ent, 0, tuner,
308 TUNER_PAD_RF_INPUT,
309 MEDIA_LNK_FL_ENABLED);
310 if (ret)
311 return ret;
312 break;
313 case AU0828_VMUX_COMPOSITE:
314 case AU0828_VMUX_SVIDEO:
315 default: /* AU0828_VMUX_DEBUG */
316 /* FIXME: fix the decoder PAD */
317 ret = media_create_pad_link(ent, 0, decoder, 0, 0);
318 if (ret)
319 return ret;
320 break;
321 }
322 }
323#endif
324 return 0;
325}
326
183static int au0828_usb_probe(struct usb_interface *interface, 327static int au0828_usb_probe(struct usb_interface *interface,
184 const struct usb_device_id *id) 328 const struct usb_device_id *id)
185{ 329{
@@ -224,11 +368,23 @@ static int au0828_usb_probe(struct usb_interface *interface,
224 dev->boardnr = id->driver_info; 368 dev->boardnr = id->driver_info;
225 dev->board = au0828_boards[dev->boardnr]; 369 dev->board = au0828_boards[dev->boardnr];
226 370
371 /* Initialize the media controller */
372 retval = au0828_media_device_init(dev, usbdev);
373 if (retval) {
374 pr_err("%s() au0828_media_device_init failed\n",
375 __func__);
376 mutex_unlock(&dev->lock);
377 kfree(dev);
378 return retval;
379 }
227 380
228#ifdef CONFIG_VIDEO_AU0828_V4L2 381#ifdef CONFIG_VIDEO_AU0828_V4L2
229 dev->v4l2_dev.release = au0828_usb_v4l2_release; 382 dev->v4l2_dev.release = au0828_usb_v4l2_release;
230 383
231 /* Create the v4l2_device */ 384 /* Create the v4l2_device */
385#ifdef CONFIG_MEDIA_CONTROLLER
386 dev->v4l2_dev.mdev = dev->media_dev;
387#endif
232 retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); 388 retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
233 if (retval) { 389 if (retval) {
234 pr_err("%s() v4l2_device_register failed\n", 390 pr_err("%s() v4l2_device_register failed\n",
@@ -287,6 +443,21 @@ static int au0828_usb_probe(struct usb_interface *interface,
287 443
288 mutex_unlock(&dev->lock); 444 mutex_unlock(&dev->lock);
289 445
446 retval = au0828_create_media_graph(dev);
447 if (retval) {
448 pr_err("%s() au0282_dev_register failed to create graph\n",
449 __func__);
450 goto done;
451 }
452
453#ifdef CONFIG_MEDIA_CONTROLLER
454 retval = media_device_register(dev->media_dev);
455#endif
456
457done:
458 if (retval < 0)
459 au0828_usb_disconnect(interface);
460
290 return retval; 461 return retval;
291} 462}
292 463
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index c267d76f5b3c..94363a3ba400 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -415,6 +415,11 @@ static int dvb_register(struct au0828_dev *dev)
415 result); 415 result);
416 goto fail_adapter; 416 goto fail_adapter;
417 } 417 }
418
419#ifdef CONFIG_MEDIA_CONTROLLER_DVB
420 dvb->adapter.mdev = dev->media_dev;
421#endif
422
418 dvb->adapter.priv = dev; 423 dvb->adapter.priv = dev;
419 424
420 /* register frontend */ 425 /* register frontend */
@@ -480,8 +485,15 @@ static int dvb_register(struct au0828_dev *dev)
480 485
481 dvb->start_count = 0; 486 dvb->start_count = 0;
482 dvb->stop_count = 0; 487 dvb->stop_count = 0;
488
489 result = dvb_create_media_graph(&dvb->adapter, false);
490 if (result < 0)
491 goto fail_create_graph;
492
483 return 0; 493 return 0;
484 494
495fail_create_graph:
496 dvb_net_release(&dvb->net);
485fail_fe_conn: 497fail_fe_conn:
486 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 498 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
487fail_fe_mem: 499fail_fe_mem:
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 0a725a161dd6..8c54fd21022e 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -638,6 +638,64 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
638 return rc; 638 return rc;
639} 639}
640 640
641static int au0828_enable_analog_tuner(struct au0828_dev *dev)
642{
643#ifdef CONFIG_MEDIA_CONTROLLER
644 struct media_device *mdev = dev->media_dev;
645 struct media_entity *source;
646 struct media_link *link, *found_link = NULL;
647 int ret, active_links = 0;
648
649 if (!mdev || !dev->decoder)
650 return 0;
651
652 /*
653 * This will find the tuner that is connected into the decoder.
654 * Technically, this is not 100% correct, as the device may be
655 * using an analog input instead of the tuner. However, as we can't
656 * do DVB streaming while the DMA engine is being used for V4L2,
657 * this should be enough for the actual needs.
658 */
659 list_for_each_entry(link, &dev->decoder->links, list) {
660 if (link->sink->entity == dev->decoder) {
661 found_link = link;
662 if (link->flags & MEDIA_LNK_FL_ENABLED)
663 active_links++;
664 break;
665 }
666 }
667
668 if (active_links == 1 || !found_link)
669 return 0;
670
671 source = found_link->source->entity;
672 list_for_each_entry(link, &source->links, list) {
673 struct media_entity *sink;
674 int flags = 0;
675
676 sink = link->sink->entity;
677
678 if (sink == dev->decoder)
679 flags = MEDIA_LNK_FL_ENABLED;
680
681 ret = media_entity_setup_link(link, flags);
682 if (ret) {
683 pr_err(
684 "Couldn't change link %s->%s to %s. Error %d\n",
685 source->name, sink->name,
686 flags ? "enabled" : "disabled",
687 ret);
688 return ret;
689 } else
690 au0828_isocdbg(
691 "link %s->%s was %s\n",
692 source->name, sink->name,
693 flags ? "ENABLED" : "disabled");
694 }
695#endif
696 return 0;
697}
698
641static int queue_setup(struct vb2_queue *vq, 699static int queue_setup(struct vb2_queue *vq,
642 unsigned int *nbuffers, unsigned int *nplanes, 700 unsigned int *nbuffers, unsigned int *nplanes,
643 unsigned int sizes[], void *alloc_ctxs[]) 701 unsigned int sizes[], void *alloc_ctxs[])
@@ -650,6 +708,8 @@ static int queue_setup(struct vb2_queue *vq,
650 *nplanes = 1; 708 *nplanes = 1;
651 sizes[0] = size; 709 sizes[0] = size;
652 710
711 au0828_enable_analog_tuner(dev);
712
653 return 0; 713 return 0;
654} 714}
655 715
@@ -1735,6 +1795,69 @@ static int au0828_vb2_setup(struct au0828_dev *dev)
1735 return 0; 1795 return 0;
1736} 1796}
1737 1797
1798static void au0828_analog_create_entities(struct au0828_dev *dev)
1799{
1800#if defined(CONFIG_MEDIA_CONTROLLER)
1801 static const char * const inames[] = {
1802 [AU0828_VMUX_COMPOSITE] = "Composite",
1803 [AU0828_VMUX_SVIDEO] = "S-Video",
1804 [AU0828_VMUX_CABLE] = "Cable TV",
1805 [AU0828_VMUX_TELEVISION] = "Television",
1806 [AU0828_VMUX_DVB] = "DVB",
1807 [AU0828_VMUX_DEBUG] = "tv debug"
1808 };
1809 int ret, i;
1810
1811 /* Initialize Video and VBI pads */
1812 dev->video_pad.flags = MEDIA_PAD_FL_SINK;
1813 ret = media_entity_pads_init(&dev->vdev.entity, 1, &dev->video_pad);
1814 if (ret < 0)
1815 pr_err("failed to initialize video media entity!\n");
1816
1817 dev->vbi_pad.flags = MEDIA_PAD_FL_SINK;
1818 ret = media_entity_pads_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad);
1819 if (ret < 0)
1820 pr_err("failed to initialize vbi media entity!\n");
1821
1822 /* Create entities for each input connector */
1823 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1824 struct media_entity *ent = &dev->input_ent[i];
1825
1826 if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
1827 break;
1828
1829 ent->name = inames[AUVI_INPUT(i).type];
1830 ent->flags = MEDIA_ENT_FL_CONNECTOR;
1831 dev->input_pad[i].flags = MEDIA_PAD_FL_SOURCE;
1832
1833 switch (AUVI_INPUT(i).type) {
1834 case AU0828_VMUX_COMPOSITE:
1835 ent->function = MEDIA_ENT_F_CONN_COMPOSITE;
1836 break;
1837 case AU0828_VMUX_SVIDEO:
1838 ent->function = MEDIA_ENT_F_CONN_SVIDEO;
1839 break;
1840 case AU0828_VMUX_CABLE:
1841 case AU0828_VMUX_TELEVISION:
1842 case AU0828_VMUX_DVB:
1843 ent->function = MEDIA_ENT_F_CONN_RF;
1844 break;
1845 default: /* AU0828_VMUX_DEBUG */
1846 ent->function = MEDIA_ENT_F_CONN_TEST;
1847 break;
1848 }
1849
1850 ret = media_entity_pads_init(ent, 1, &dev->input_pad[i]);
1851 if (ret < 0)
1852 pr_err("failed to initialize input pad[%d]!\n", i);
1853
1854 ret = media_device_register_entity(dev->media_dev, ent);
1855 if (ret < 0)
1856 pr_err("failed to register input entity %d!\n", i);
1857 }
1858#endif
1859}
1860
1738/**************************************************************************/ 1861/**************************************************************************/
1739 1862
1740int au0828_analog_register(struct au0828_dev *dev, 1863int au0828_analog_register(struct au0828_dev *dev,
@@ -1823,6 +1946,9 @@ int au0828_analog_register(struct au0828_dev *dev,
1823 dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock; 1946 dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock;
1824 strcpy(dev->vbi_dev.name, "au0828a vbi"); 1947 strcpy(dev->vbi_dev.name, "au0828a vbi");
1825 1948
1949 /* Init entities at the Media Controller */
1950 au0828_analog_create_entities(dev);
1951
1826 /* initialize videobuf2 stuff */ 1952 /* initialize videobuf2 stuff */
1827 retval = au0828_vb2_setup(dev); 1953 retval = au0828_vb2_setup(dev);
1828 if (retval != 0) { 1954 if (retval != 0) {
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index 60b59391ea2a..8276072bc55a 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -33,6 +33,7 @@
33#include <media/v4l2-device.h> 33#include <media/v4l2-device.h>
34#include <media/v4l2-ctrls.h> 34#include <media/v4l2-ctrls.h>
35#include <media/v4l2-fh.h> 35#include <media/v4l2-fh.h>
36#include <media/media-device.h>
36 37
37/* DVB */ 38/* DVB */
38#include "demux.h" 39#include "demux.h"
@@ -93,7 +94,6 @@ struct au0828_board {
93 unsigned char has_ir_i2c:1; 94 unsigned char has_ir_i2c:1;
94 unsigned char has_analog:1; 95 unsigned char has_analog:1;
95 struct au0828_input input[AU0828_MAX_INPUT]; 96 struct au0828_input input[AU0828_MAX_INPUT];
96
97}; 97};
98 98
99struct au0828_dvb { 99struct au0828_dvb {
@@ -276,6 +276,14 @@ struct au0828_dev {
276 /* Preallocated transfer digital transfer buffers */ 276 /* Preallocated transfer digital transfer buffers */
277 277
278 char *dig_transfer_buffer[URB_COUNT]; 278 char *dig_transfer_buffer[URB_COUNT];
279
280#ifdef CONFIG_MEDIA_CONTROLLER
281 struct media_device *media_dev;
282 struct media_pad video_pad, vbi_pad;
283 struct media_entity *decoder;
284 struct media_entity input_ent[AU0828_MAX_INPUT];
285 struct media_pad input_pad[AU0828_MAX_INPUT];
286#endif
279}; 287};
280 288
281 289
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 89dc695c696e..620b83d03f75 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1172,6 +1172,7 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev)
1172#ifdef CONFIG_MEDIA_CONTROLLER 1172#ifdef CONFIG_MEDIA_CONTROLLER
1173 if (dev->media_dev) { 1173 if (dev->media_dev) {
1174 media_device_unregister(dev->media_dev); 1174 media_device_unregister(dev->media_dev);
1175 media_device_cleanup(dev->media_dev);
1175 kfree(dev->media_dev); 1176 kfree(dev->media_dev);
1176 dev->media_dev = NULL; 1177 dev->media_dev = NULL;
1177 } 1178 }
@@ -1185,8 +1186,6 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev)
1185*/ 1186*/
1186void cx231xx_release_resources(struct cx231xx *dev) 1187void cx231xx_release_resources(struct cx231xx *dev)
1187{ 1188{
1188 cx231xx_unregister_media_device(dev);
1189
1190 cx231xx_release_analog_resources(dev); 1189 cx231xx_release_analog_resources(dev);
1191 1190
1192 cx231xx_remove_from_devlist(dev); 1191 cx231xx_remove_from_devlist(dev);
@@ -1199,22 +1198,23 @@ void cx231xx_release_resources(struct cx231xx *dev)
1199 /* delete v4l2 device */ 1198 /* delete v4l2 device */
1200 v4l2_device_unregister(&dev->v4l2_dev); 1199 v4l2_device_unregister(&dev->v4l2_dev);
1201 1200
1201 cx231xx_unregister_media_device(dev);
1202
1202 usb_put_dev(dev->udev); 1203 usb_put_dev(dev->udev);
1203 1204
1204 /* Mark device as unused */ 1205 /* Mark device as unused */
1205 clear_bit(dev->devno, &cx231xx_devused); 1206 clear_bit(dev->devno, &cx231xx_devused);
1206} 1207}
1207 1208
1208static void cx231xx_media_device_register(struct cx231xx *dev, 1209static int cx231xx_media_device_init(struct cx231xx *dev,
1209 struct usb_device *udev) 1210 struct usb_device *udev)
1210{ 1211{
1211#ifdef CONFIG_MEDIA_CONTROLLER 1212#ifdef CONFIG_MEDIA_CONTROLLER
1212 struct media_device *mdev; 1213 struct media_device *mdev;
1213 int ret;
1214 1214
1215 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 1215 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
1216 if (!mdev) 1216 if (!mdev)
1217 return; 1217 return -ENOMEM;
1218 1218
1219 mdev->dev = dev->dev; 1219 mdev->dev = dev->dev;
1220 strlcpy(mdev->model, dev->board.name, sizeof(mdev->model)); 1220 strlcpy(mdev->model, dev->board.name, sizeof(mdev->model));
@@ -1224,35 +1224,30 @@ static void cx231xx_media_device_register(struct cx231xx *dev,
1224 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); 1224 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
1225 mdev->driver_version = LINUX_VERSION_CODE; 1225 mdev->driver_version = LINUX_VERSION_CODE;
1226 1226
1227 ret = media_device_register(mdev); 1227 media_device_init(mdev);
1228 if (ret) {
1229 dev_err(dev->dev,
1230 "Couldn't create a media device. Error: %d\n",
1231 ret);
1232 kfree(mdev);
1233 return;
1234 }
1235 1228
1236 dev->media_dev = mdev; 1229 dev->media_dev = mdev;
1237#endif 1230#endif
1231 return 0;
1238} 1232}
1239 1233
1240static void cx231xx_create_media_graph(struct cx231xx *dev) 1234static int cx231xx_create_media_graph(struct cx231xx *dev)
1241{ 1235{
1242#ifdef CONFIG_MEDIA_CONTROLLER 1236#ifdef CONFIG_MEDIA_CONTROLLER
1243 struct media_device *mdev = dev->media_dev; 1237 struct media_device *mdev = dev->media_dev;
1244 struct media_entity *entity; 1238 struct media_entity *entity;
1245 struct media_entity *tuner = NULL, *decoder = NULL; 1239 struct media_entity *tuner = NULL, *decoder = NULL;
1240 int ret;
1246 1241
1247 if (!mdev) 1242 if (!mdev)
1248 return; 1243 return 0;
1249 1244
1250 media_device_for_each_entity(entity, mdev) { 1245 media_device_for_each_entity(entity, mdev) {
1251 switch (entity->type) { 1246 switch (entity->function) {
1252 case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: 1247 case MEDIA_ENT_F_TUNER:
1253 tuner = entity; 1248 tuner = entity;
1254 break; 1249 break;
1255 case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: 1250 case MEDIA_ENT_F_ATV_DECODER:
1256 decoder = entity; 1251 decoder = entity;
1257 break; 1252 break;
1258 } 1253 }
@@ -1261,16 +1256,24 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
1261 /* Analog setup, using tuner as a link */ 1256 /* Analog setup, using tuner as a link */
1262 1257
1263 if (!decoder) 1258 if (!decoder)
1264 return; 1259 return 0;
1265 1260
1266 if (tuner) 1261 if (tuner) {
1267 media_entity_create_link(tuner, 0, decoder, 0, 1262 ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
1268 MEDIA_LNK_FL_ENABLED); 1263 MEDIA_LNK_FL_ENABLED);
1269 media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, 1264 if (ret < 0)
1270 MEDIA_LNK_FL_ENABLED); 1265 return ret;
1271 media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, 1266 }
1272 MEDIA_LNK_FL_ENABLED); 1267 ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
1268 MEDIA_LNK_FL_ENABLED);
1269 if (ret < 0)
1270 return ret;
1271 ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
1272 MEDIA_LNK_FL_ENABLED);
1273 if (ret < 0)
1274 return ret;
1273#endif 1275#endif
1276 return 0;
1274} 1277}
1275 1278
1276/* 1279/*
@@ -1660,8 +1663,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1660 /* save our data pointer in this interface device */ 1663 /* save our data pointer in this interface device */
1661 usb_set_intfdata(interface, dev); 1664 usb_set_intfdata(interface, dev);
1662 1665
1663 /* Register the media controller */ 1666 /* Initialize the media controller */
1664 cx231xx_media_device_register(dev, udev); 1667 retval = cx231xx_media_device_init(dev, udev);
1668 if (retval) {
1669 dev_err(d, "cx231xx_media_device_init failed\n");
1670 goto err_media_init;
1671 }
1665 1672
1666 /* Create v4l2 device */ 1673 /* Create v4l2 device */
1667#ifdef CONFIG_MEDIA_CONTROLLER 1674#ifdef CONFIG_MEDIA_CONTROLLER
@@ -1732,9 +1739,19 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1732 /* load other modules required */ 1739 /* load other modules required */
1733 request_modules(dev); 1740 request_modules(dev);
1734 1741
1735 cx231xx_create_media_graph(dev); 1742 retval = cx231xx_create_media_graph(dev);
1743 if (retval < 0)
1744 goto done;
1745
1746#ifdef CONFIG_MEDIA_CONTROLLER
1747 retval = media_device_register(dev->media_dev);
1748#endif
1749
1750done:
1751 if (retval < 0)
1752 cx231xx_release_resources(dev);
1753 return retval;
1736 1754
1737 return 0;
1738err_video_alt: 1755err_video_alt:
1739 /* cx231xx_uninit_dev: */ 1756 /* cx231xx_uninit_dev: */
1740 cx231xx_close_extension(dev); 1757 cx231xx_close_extension(dev);
@@ -1746,6 +1763,8 @@ err_video_alt:
1746err_init: 1763err_init:
1747 v4l2_device_unregister(&dev->v4l2_dev); 1764 v4l2_device_unregister(&dev->v4l2_dev);
1748err_v4l2: 1765err_v4l2:
1766 cx231xx_unregister_media_device(dev);
1767err_media_init:
1749 usb_set_intfdata(interface, NULL); 1768 usb_set_intfdata(interface, NULL);
1750err_if: 1769err_if:
1751 usb_put_dev(udev); 1770 usb_put_dev(udev);
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index e3594b9fab4a..b8d5b2be9293 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,
551 551
552 /* register network adapter */ 552 /* register network adapter */
553 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); 553 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
554 dvb_create_media_graph(&dvb->adapter); 554 result = dvb_create_media_graph(&dvb->adapter, false);
555 if (result < 0)
556 goto fail_create_graph;
555 557
556 return 0; 558 return 0;
557 559
560fail_create_graph:
561 dvb_net_release(&dvb->net);
558fail_fe_conn: 562fail_fe_conn:
559 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 563 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
560fail_fe_mem: 564fail_fe_mem:
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index a70850fe6235..9b88cd8127ac 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)
106 struct media_device *mdev = dev->media_dev; 106 struct media_device *mdev = dev->media_dev;
107 struct media_entity *entity, *decoder = NULL, *source; 107 struct media_entity *entity, *decoder = NULL, *source;
108 struct media_link *link, *found_link = NULL; 108 struct media_link *link, *found_link = NULL;
109 int i, ret, active_links = 0; 109 int ret, active_links = 0;
110 110
111 if (!mdev) 111 if (!mdev)
112 return 0; 112 return 0;
@@ -119,7 +119,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)
119 * this should be enough for the actual needs. 119 * this should be enough for the actual needs.
120 */ 120 */
121 media_device_for_each_entity(entity, mdev) { 121 media_device_for_each_entity(entity, mdev) {
122 if (entity->type == MEDIA_ENT_T_V4L2_SUBDEV_DECODER) { 122 if (entity->function == MEDIA_ENT_F_ATV_DECODER) {
123 decoder = entity; 123 decoder = entity;
124 break; 124 break;
125 } 125 }
@@ -127,8 +127,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)
127 if (!decoder) 127 if (!decoder)
128 return 0; 128 return 0;
129 129
130 for (i = 0; i < decoder->num_links; i++) { 130 list_for_each_entry(link, &decoder->links, list) {
131 link = &decoder->links[i];
132 if (link->sink->entity == decoder) { 131 if (link->sink->entity == decoder) {
133 found_link = link; 132 found_link = link;
134 if (link->flags & MEDIA_LNK_FL_ENABLED) 133 if (link->flags & MEDIA_LNK_FL_ENABLED)
@@ -141,11 +140,10 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)
141 return 0; 140 return 0;
142 141
143 source = found_link->source->entity; 142 source = found_link->source->entity;
144 for (i = 0; i < source->num_links; i++) { 143 list_for_each_entry(link, &source->links, list) {
145 struct media_entity *sink; 144 struct media_entity *sink;
146 int flags = 0; 145 int flags = 0;
147 146
148 link = &source->links[i];
149 sink = link->sink->entity; 147 sink = link->sink->entity;
150 148
151 if (sink == entity) 149 if (sink == entity)
@@ -2177,7 +2175,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
2177 cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video"); 2175 cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video");
2178#if defined(CONFIG_MEDIA_CONTROLLER) 2176#if defined(CONFIG_MEDIA_CONTROLLER)
2179 dev->video_pad.flags = MEDIA_PAD_FL_SINK; 2177 dev->video_pad.flags = MEDIA_PAD_FL_SINK;
2180 ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0); 2178 ret = media_entity_pads_init(&dev->vdev.entity, 1, &dev->video_pad);
2181 if (ret < 0) 2179 if (ret < 0)
2182 dev_err(dev->dev, "failed to initialize video media entity!\n"); 2180 dev_err(dev->dev, "failed to initialize video media entity!\n");
2183#endif 2181#endif
@@ -2204,7 +2202,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
2204 2202
2205#if defined(CONFIG_MEDIA_CONTROLLER) 2203#if defined(CONFIG_MEDIA_CONTROLLER)
2206 dev->vbi_pad.flags = MEDIA_PAD_FL_SINK; 2204 dev->vbi_pad.flags = MEDIA_PAD_FL_SINK;
2207 ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0); 2205 ret = media_entity_pads_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad);
2208 if (ret < 0) 2206 if (ret < 0)
2209 dev_err(dev->dev, "failed to initialize vbi media entity!\n"); 2207 dev_err(dev->dev, "failed to initialize vbi media entity!\n");
2210#endif 2208#endif
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..f0565bf3673e 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -400,17 +400,16 @@ skip_feed_stop:
400 return ret; 400 return ret;
401} 401}
402 402
403static void dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap) 403static int dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap)
404{ 404{
405#ifdef CONFIG_MEDIA_CONTROLLER_DVB 405#ifdef CONFIG_MEDIA_CONTROLLER_DVB
406 struct media_device *mdev; 406 struct media_device *mdev;
407 struct dvb_usb_device *d = adap_to_d(adap); 407 struct dvb_usb_device *d = adap_to_d(adap);
408 struct usb_device *udev = d->udev; 408 struct usb_device *udev = d->udev;
409 int ret;
410 409
411 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 410 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
412 if (!mdev) 411 if (!mdev)
413 return; 412 return -ENOMEM;
414 413
415 mdev->dev = &udev->dev; 414 mdev->dev = &udev->dev;
416 strlcpy(mdev->model, d->name, sizeof(mdev->model)); 415 strlcpy(mdev->model, d->name, sizeof(mdev->model));
@@ -420,19 +419,21 @@ static void dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap)
420 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); 419 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
421 mdev->driver_version = LINUX_VERSION_CODE; 420 mdev->driver_version = LINUX_VERSION_CODE;
422 421
423 ret = media_device_register(mdev); 422 media_device_init(mdev);
424 if (ret) {
425 dev_err(&d->udev->dev,
426 "Couldn't create a media device. Error: %d\n",
427 ret);
428 kfree(mdev);
429 return;
430 }
431 423
432 dvb_register_media_controller(&adap->dvb_adap, mdev); 424 dvb_register_media_controller(&adap->dvb_adap, mdev);
433 425
434 dev_info(&d->udev->dev, "media controller created\n"); 426 dev_info(&d->udev->dev, "media controller created\n");
427#endif
428 return 0;
429}
435 430
431static int dvb_usbv2_media_device_register(struct dvb_usb_adapter *adap)
432{
433#ifdef CONFIG_MEDIA_CONTROLLER_DVB
434 return media_device_register(adap->dvb_adap.mdev);
435#else
436 return 0;
436#endif 437#endif
437} 438}
438 439
@@ -444,6 +445,7 @@ static void dvb_usbv2_media_device_unregister(struct dvb_usb_adapter *adap)
444 return; 445 return;
445 446
446 media_device_unregister(adap->dvb_adap.mdev); 447 media_device_unregister(adap->dvb_adap.mdev);
448 media_device_cleanup(adap->dvb_adap.mdev);
447 kfree(adap->dvb_adap.mdev); 449 kfree(adap->dvb_adap.mdev);
448 adap->dvb_adap.mdev = NULL; 450 adap->dvb_adap.mdev = NULL;
449 451
@@ -467,7 +469,12 @@ static int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
467 469
468 adap->dvb_adap.priv = adap; 470 adap->dvb_adap.priv = adap;
469 471
470 dvb_usbv2_media_device_register(adap); 472 ret = dvb_usbv2_media_device_init(adap);
473 if (ret < 0) {
474 dev_dbg(&d->udev->dev, "%s: dvb_usbv2_media_device_init() failed=%d\n",
475 __func__, ret);
476 goto err_dvb_register_mc;
477 }
471 478
472 if (d->props->read_mac_address) { 479 if (d->props->read_mac_address) {
473 ret = d->props->read_mac_address(adap, 480 ret = d->props->read_mac_address(adap,
@@ -518,6 +525,7 @@ err_dvb_dmxdev_init:
518 dvb_dmx_release(&adap->demux); 525 dvb_dmx_release(&adap->demux);
519err_dvb_dmx_init: 526err_dvb_dmx_init:
520 dvb_usbv2_media_device_unregister(adap); 527 dvb_usbv2_media_device_unregister(adap);
528err_dvb_register_mc:
521 dvb_unregister_adapter(&adap->dvb_adap); 529 dvb_unregister_adapter(&adap->dvb_adap);
522err_dvb_register_adapter: 530err_dvb_register_adapter:
523 adap->dvb_adap.priv = NULL; 531 adap->dvb_adap.priv = NULL;
@@ -534,7 +542,6 @@ static int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
534 adap->demux.dmx.close(&adap->demux.dmx); 542 adap->demux.dmx.close(&adap->demux.dmx);
535 dvb_dmxdev_release(&adap->dmxdev); 543 dvb_dmxdev_release(&adap->dmxdev);
536 dvb_dmx_release(&adap->demux); 544 dvb_dmx_release(&adap->demux);
537 dvb_usbv2_media_device_unregister(adap);
538 dvb_unregister_adapter(&adap->dvb_adap); 545 dvb_unregister_adapter(&adap->dvb_adap);
539 } 546 }
540 547
@@ -698,9 +705,13 @@ static int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
698 } 705 }
699 } 706 }
700 707
701 dvb_create_media_graph(&adap->dvb_adap); 708 ret = dvb_create_media_graph(&adap->dvb_adap, true);
709 if (ret < 0)
710 goto err_dvb_unregister_frontend;
702 711
703 return 0; 712 ret = dvb_usbv2_media_device_register(adap);
713
714 return ret;
704 715
705err_dvb_unregister_frontend: 716err_dvb_unregister_frontend:
706 for (i = count_registered - 1; i >= 0; i--) 717 for (i = count_registered - 1; i >= 0; i--)
@@ -840,6 +851,7 @@ static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d)
840 dvb_usbv2_adapter_dvb_exit(&d->adapter[i]); 851 dvb_usbv2_adapter_dvb_exit(&d->adapter[i]);
841 dvb_usbv2_adapter_stream_exit(&d->adapter[i]); 852 dvb_usbv2_adapter_stream_exit(&d->adapter[i]);
842 dvb_usbv2_adapter_frontend_exit(&d->adapter[i]); 853 dvb_usbv2_adapter_frontend_exit(&d->adapter[i]);
854 dvb_usbv2_media_device_unregister(&d->adapter[i]);
843 } 855 }
844 } 856 }
845 857
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index 1710f9038d75..b669deccc34c 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/vmalloc.h> 11#include <linux/vmalloc.h>
12#include <linux/i2c.h> 12#include <linux/i2c.h>
13#include <media/tuner.h>
13 14
14#include "mxl111sf.h" 15#include "mxl111sf.h"
15#include "mxl111sf-reg.h" 16#include "mxl111sf-reg.h"
@@ -868,6 +869,10 @@ static struct mxl111sf_tuner_config mxl_tuner_config = {
868static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap) 869static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
869{ 870{
870 struct mxl111sf_state *state = adap_to_priv(adap); 871 struct mxl111sf_state *state = adap_to_priv(adap);
872#ifdef CONFIG_MEDIA_CONTROLLER_DVB
873 struct media_device *mdev = dvb_get_media_controller(&adap->dvb_adap);
874 int ret;
875#endif
871 int i; 876 int i;
872 877
873 pr_debug("%s()\n", __func__); 878 pr_debug("%s()\n", __func__);
@@ -879,6 +884,21 @@ static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
879 adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength; 884 adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength;
880 } 885 }
881 886
887#ifdef CONFIG_MEDIA_CONTROLLER_DVB
888 state->tuner.function = MEDIA_ENT_F_TUNER;
889 state->tuner.name = "mxl111sf tuner";
890 state->tuner_pads[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
891 state->tuner_pads[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
892
893 ret = media_entity_pads_init(&state->tuner,
894 TUNER_NUM_PADS, state->tuner_pads);
895 if (ret)
896 return ret;
897
898 ret = media_device_register_entity(mdev, &state->tuner);
899 if (ret)
900 return ret;
901#endif
882 return 0; 902 return 0;
883} 903}
884 904
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
index ee70df1f1e94..846260e0eec0 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
@@ -17,6 +17,7 @@
17#define DVB_USB_LOG_PREFIX "mxl111sf" 17#define DVB_USB_LOG_PREFIX "mxl111sf"
18#include "dvb_usb.h" 18#include "dvb_usb.h"
19#include <media/tveeprom.h> 19#include <media/tveeprom.h>
20#include <media/media-entity.h>
20 21
21#define MXL_EP1_REG_READ 1 22#define MXL_EP1_REG_READ 1
22#define MXL_EP2_REG_WRITE 2 23#define MXL_EP2_REG_WRITE 2
@@ -85,6 +86,10 @@ struct mxl111sf_state {
85 struct mutex fe_lock; 86 struct mutex fe_lock;
86 u8 num_frontends; 87 u8 num_frontends;
87 struct mxl111sf_adap_state adap_state[3]; 88 struct mxl111sf_adap_state adap_state[3];
89#ifdef CONFIG_MEDIA_CONTROLLER_DVB
90 struct media_entity tuner;
91 struct media_pad tuner_pads[2];
92#endif
88}; 93};
89 94
90int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data); 95int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data);
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
index 8a260c854653..9ddfcab268be 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
@@ -95,17 +95,16 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
95 return dvb_usb_ctrl_feed(dvbdmxfeed, 0); 95 return dvb_usb_ctrl_feed(dvbdmxfeed, 0);
96} 96}
97 97
98static void dvb_usb_media_device_register(struct dvb_usb_adapter *adap) 98static int dvb_usb_media_device_init(struct dvb_usb_adapter *adap)
99{ 99{
100#ifdef CONFIG_MEDIA_CONTROLLER_DVB 100#ifdef CONFIG_MEDIA_CONTROLLER_DVB
101 struct media_device *mdev; 101 struct media_device *mdev;
102 struct dvb_usb_device *d = adap->dev; 102 struct dvb_usb_device *d = adap->dev;
103 struct usb_device *udev = d->udev; 103 struct usb_device *udev = d->udev;
104 int ret;
105 104
106 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 105 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
107 if (!mdev) 106 if (!mdev)
108 return; 107 return -ENOMEM;
109 108
110 mdev->dev = &udev->dev; 109 mdev->dev = &udev->dev;
111 strlcpy(mdev->model, d->desc->name, sizeof(mdev->model)); 110 strlcpy(mdev->model, d->desc->name, sizeof(mdev->model));
@@ -115,18 +114,22 @@ static void dvb_usb_media_device_register(struct dvb_usb_adapter *adap)
115 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); 114 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
116 mdev->driver_version = LINUX_VERSION_CODE; 115 mdev->driver_version = LINUX_VERSION_CODE;
117 116
118 ret = media_device_register(mdev); 117 media_device_init(mdev);
119 if (ret) { 118
120 dev_err(&d->udev->dev,
121 "Couldn't create a media device. Error: %d\n",
122 ret);
123 kfree(mdev);
124 return;
125 }
126 dvb_register_media_controller(&adap->dvb_adap, mdev); 119 dvb_register_media_controller(&adap->dvb_adap, mdev);
127 120
128 dev_info(&d->udev->dev, "media controller created\n"); 121 dev_info(&d->udev->dev, "media controller created\n");
129#endif 122#endif
123 return 0;
124}
125
126static int dvb_usb_media_device_register(struct dvb_usb_adapter *adap)
127{
128#ifdef CONFIG_MEDIA_CONTROLLER_DVB
129 return media_device_register(adap->dvb_adap.mdev);
130#else
131 return 0;
132#endif
130} 133}
131 134
132static void dvb_usb_media_device_unregister(struct dvb_usb_adapter *adap) 135static void dvb_usb_media_device_unregister(struct dvb_usb_adapter *adap)
@@ -136,6 +139,7 @@ static void dvb_usb_media_device_unregister(struct dvb_usb_adapter *adap)
136 return; 139 return;
137 140
138 media_device_unregister(adap->dvb_adap.mdev); 141 media_device_unregister(adap->dvb_adap.mdev);
142 media_device_cleanup(adap->dvb_adap.mdev);
139 kfree(adap->dvb_adap.mdev); 143 kfree(adap->dvb_adap.mdev);
140 adap->dvb_adap.mdev = NULL; 144 adap->dvb_adap.mdev = NULL;
141#endif 145#endif
@@ -154,7 +158,11 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
154 } 158 }
155 adap->dvb_adap.priv = adap; 159 adap->dvb_adap.priv = adap;
156 160
157 dvb_usb_media_device_register(adap); 161 ret = dvb_usb_media_device_init(adap);
162 if (ret < 0) {
163 deb_info("dvb_usb_media_device_init failed: error %d", ret);
164 goto err_mc;
165 }
158 166
159 if (adap->dev->props.read_mac_address) { 167 if (adap->dev->props.read_mac_address) {
160 if (adap->dev->props.read_mac_address(adap->dev, adap->dvb_adap.proposed_mac) == 0) 168 if (adap->dev->props.read_mac_address(adap->dev, adap->dvb_adap.proposed_mac) == 0)
@@ -204,6 +212,7 @@ err_dmx_dev:
204 dvb_dmx_release(&adap->demux); 212 dvb_dmx_release(&adap->demux);
205err_dmx: 213err_dmx:
206 dvb_usb_media_device_unregister(adap); 214 dvb_usb_media_device_unregister(adap);
215err_mc:
207 dvb_unregister_adapter(&adap->dvb_adap); 216 dvb_unregister_adapter(&adap->dvb_adap);
208err: 217err:
209 return ret; 218 return ret;
@@ -318,10 +327,16 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
318 327
319 adap->num_frontends_initialized++; 328 adap->num_frontends_initialized++;
320 } 329 }
330 if (ret)
331 return ret;
321 332
322 dvb_create_media_graph(&adap->dvb_adap); 333 ret = dvb_create_media_graph(&adap->dvb_adap, true);
334 if (ret)
335 return ret;
323 336
324 return 0; 337 ret = dvb_usb_media_device_register(adap);
338
339 return ret;
325} 340}
326 341
327int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap) 342int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index c945e4c2fbd4..8abbd3cc8eba 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -361,10 +361,11 @@ static void *siano_media_device_register(struct smsusb_device_t *dev,
361 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); 361 mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
362 mdev->driver_version = LINUX_VERSION_CODE; 362 mdev->driver_version = LINUX_VERSION_CODE;
363 363
364 media_device_init(mdev);
365
364 ret = media_device_register(mdev); 366 ret = media_device_register(mdev);
365 if (ret) { 367 if (ret) {
366 pr_err("Couldn't create a media device. Error: %d\n", 368 media_device_cleanup(mdev);
367 ret);
368 kfree(mdev); 369 kfree(mdev);
369 return NULL; 370 return NULL;
370 } 371 }
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 39abbafad796..4e7148815a78 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1656,6 +1656,7 @@ static void uvc_delete(struct uvc_device *dev)
1656#ifdef CONFIG_MEDIA_CONTROLLER 1656#ifdef CONFIG_MEDIA_CONTROLLER
1657 if (media_devnode_is_registered(&dev->mdev.devnode)) 1657 if (media_devnode_is_registered(&dev->mdev.devnode))
1658 media_device_unregister(&dev->mdev); 1658 media_device_unregister(&dev->mdev);
1659 media_device_cleanup(&dev->mdev);
1659#endif 1660#endif
1660 1661
1661 list_for_each_safe(p, n, &dev->chains) { 1662 list_for_each_safe(p, n, &dev->chains) {
@@ -1906,7 +1907,7 @@ static int uvc_probe(struct usb_interface *intf,
1906 "linux-uvc-devel mailing list.\n"); 1907 "linux-uvc-devel mailing list.\n");
1907 } 1908 }
1908 1909
1909 /* Register the media and V4L2 devices. */ 1910 /* Initialize the media device and register the V4L2 device. */
1910#ifdef CONFIG_MEDIA_CONTROLLER 1911#ifdef CONFIG_MEDIA_CONTROLLER
1911 dev->mdev.dev = &intf->dev; 1912 dev->mdev.dev = &intf->dev;
1912 strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); 1913 strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
@@ -1916,8 +1917,7 @@ static int uvc_probe(struct usb_interface *intf,
1916 strcpy(dev->mdev.bus_info, udev->devpath); 1917 strcpy(dev->mdev.bus_info, udev->devpath);
1917 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); 1918 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
1918 dev->mdev.driver_version = LINUX_VERSION_CODE; 1919 dev->mdev.driver_version = LINUX_VERSION_CODE;
1919 if (media_device_register(&dev->mdev) < 0) 1920 media_device_init(&dev->mdev);
1920 goto error;
1921 1921
1922 dev->vdev.mdev = &dev->mdev; 1922 dev->vdev.mdev = &dev->mdev;
1923#endif 1923#endif
@@ -1936,6 +1936,11 @@ static int uvc_probe(struct usb_interface *intf,
1936 if (uvc_register_chains(dev) < 0) 1936 if (uvc_register_chains(dev) < 0)
1937 goto error; 1937 goto error;
1938 1938
1939#ifdef CONFIG_MEDIA_CONTROLLER
1940 /* Register the media device node */
1941 if (media_device_register(&dev->mdev) < 0)
1942 goto error;
1943#endif
1939 /* Save our data pointer in the interface data. */ 1944 /* Save our data pointer in the interface data. */
1940 usb_set_intfdata(intf, dev); 1945 usb_set_intfdata(intf, dev);
1941 1946
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index dc56a59ecadc..ac386bb547e6 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -19,12 +19,8 @@
19 19
20#include "uvcvideo.h" 20#include "uvcvideo.h"
21 21
22/* ------------------------------------------------------------------------ 22static int uvc_mc_create_links(struct uvc_video_chain *chain,
23 * Video subdevices registration and unregistration 23 struct uvc_entity *entity)
24 */
25
26static int uvc_mc_register_entity(struct uvc_video_chain *chain,
27 struct uvc_entity *entity)
28{ 24{
29 const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; 25 const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
30 struct media_entity *sink; 26 struct media_entity *sink;
@@ -56,16 +52,13 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
56 continue; 52 continue;
57 53
58 remote_pad = remote->num_pads - 1; 54 remote_pad = remote->num_pads - 1;
59 ret = media_entity_create_link(source, remote_pad, 55 ret = media_create_pad_link(source, remote_pad,
60 sink, i, flags); 56 sink, i, flags);
61 if (ret < 0) 57 if (ret < 0)
62 return ret; 58 return ret;
63 } 59 }
64 60
65 if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) 61 return 0;
66 return 0;
67
68 return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev);
69} 62}
70 63
71static struct v4l2_subdev_ops uvc_subdev_ops = { 64static struct v4l2_subdev_ops uvc_subdev_ops = {
@@ -79,7 +72,8 @@ void uvc_mc_cleanup_entity(struct uvc_entity *entity)
79 media_entity_cleanup(&entity->vdev->entity); 72 media_entity_cleanup(&entity->vdev->entity);
80} 73}
81 74
82static int uvc_mc_init_entity(struct uvc_entity *entity) 75static int uvc_mc_init_entity(struct uvc_video_chain *chain,
76 struct uvc_entity *entity)
83{ 77{
84 int ret; 78 int ret;
85 79
@@ -88,11 +82,17 @@ static int uvc_mc_init_entity(struct uvc_entity *entity)
88 strlcpy(entity->subdev.name, entity->name, 82 strlcpy(entity->subdev.name, entity->name,
89 sizeof(entity->subdev.name)); 83 sizeof(entity->subdev.name));
90 84
91 ret = media_entity_init(&entity->subdev.entity, 85 ret = media_entity_pads_init(&entity->subdev.entity,
92 entity->num_pads, entity->pads, 0); 86 entity->num_pads, entity->pads);
87
88 if (ret < 0)
89 return ret;
90
91 ret = v4l2_device_register_subdev(&chain->dev->vdev,
92 &entity->subdev);
93 } else if (entity->vdev != NULL) { 93 } else if (entity->vdev != NULL) {
94 ret = media_entity_init(&entity->vdev->entity, 94 ret = media_entity_pads_init(&entity->vdev->entity,
95 entity->num_pads, entity->pads, 0); 95 entity->num_pads, entity->pads);
96 if (entity->flags & UVC_ENTITY_FLAG_DEFAULT) 96 if (entity->flags & UVC_ENTITY_FLAG_DEFAULT)
97 entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; 97 entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
98 } else 98 } else
@@ -107,7 +107,7 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain)
107 int ret; 107 int ret;
108 108
109 list_for_each_entry(entity, &chain->entities, chain) { 109 list_for_each_entry(entity, &chain->entities, chain) {
110 ret = uvc_mc_init_entity(entity); 110 ret = uvc_mc_init_entity(chain, entity);
111 if (ret < 0) { 111 if (ret < 0) {
112 uvc_printk(KERN_INFO, "Failed to initialize entity for " 112 uvc_printk(KERN_INFO, "Failed to initialize entity for "
113 "entity %u\n", entity->id); 113 "entity %u\n", entity->id);
@@ -116,9 +116,9 @@ int uvc_mc_register_entities(struct uvc_video_chain *chain)
116 } 116 }
117 117
118 list_for_each_entry(entity, &chain->entities, chain) { 118 list_for_each_entry(entity, &chain->entities, chain) {
119 ret = uvc_mc_register_entity(chain, entity); 119 ret = uvc_mc_create_links(chain, entity);
120 if (ret < 0) { 120 if (ret < 0) {
121 uvc_printk(KERN_INFO, "Failed to register entity for " 121 uvc_printk(KERN_INFO, "Failed to create links for "
122 "entity %u\n", entity->id); 122 "entity %u\n", entity->id);
123 return ret; 123 return ret;
124 } 124 }
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index 581e21ad6801..76496fd282aa 100644
--- a/drivers/media/v4l2-core/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
@@ -134,8 +134,9 @@ struct tuner {
134 unsigned int type; /* chip type id */ 134 unsigned int type; /* chip type id */
135 void *config; 135 void *config;
136 const char *name; 136 const char *name;
137
137#if defined(CONFIG_MEDIA_CONTROLLER) 138#if defined(CONFIG_MEDIA_CONTROLLER)
138 struct media_pad pad; 139 struct media_pad pad[TUNER_NUM_PADS];
139#endif 140#endif
140}; 141};
141 142
@@ -695,11 +696,12 @@ static int tuner_probe(struct i2c_client *client,
695 /* Should be just before return */ 696 /* Should be just before return */
696register_client: 697register_client:
697#if defined(CONFIG_MEDIA_CONTROLLER) 698#if defined(CONFIG_MEDIA_CONTROLLER)
698 t->pad.flags = MEDIA_PAD_FL_SOURCE; 699 t->pad[TUNER_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
699 t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER; 700 t->pad[TUNER_PAD_IF_OUTPUT].flags = MEDIA_PAD_FL_SOURCE;
701 t->sd.entity.function = MEDIA_ENT_F_TUNER;
700 t->sd.entity.name = t->name; 702 t->sd.entity.name = t->name;
701 703
702 ret = media_entity_init(&t->sd.entity, 1, &t->pad, 0); 704 ret = media_entity_pads_init(&t->sd.entity, TUNER_NUM_PADS, &t->pad[0]);
703 if (ret < 0) { 705 if (ret < 0) {
704 tuner_err("failed to initialize media entity!\n"); 706 tuner_err("failed to initialize media entity!\n");
705 kfree(t); 707 kfree(t);
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 6b1eaeddbdb3..d8e5994cccf1 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)
194 mutex_unlock(&videodev_lock); 194 mutex_unlock(&videodev_lock);
195 195
196#if defined(CONFIG_MEDIA_CONTROLLER) 196#if defined(CONFIG_MEDIA_CONTROLLER)
197 if (v4l2_dev->mdev && 197 if (v4l2_dev->mdev) {
198 vdev->vfl_type != VFL_TYPE_SUBDEV) 198 /* Remove interfaces and interface links */
199 media_device_unregister_entity(&vdev->entity); 199 media_devnode_remove(vdev->intf_devnode);
200 if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN)
201 media_device_unregister_entity(&vdev->entity);
202 }
200#endif 203#endif
201 204
202 /* Do not call v4l2_device_put if there is no release callback set. 205 /* 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)
723 BASE_VIDIOC_PRIVATE); 726 BASE_VIDIOC_PRIVATE);
724} 727}
725 728
729static int video_register_media_controller(struct video_device *vdev, int type)
730{
731#if defined(CONFIG_MEDIA_CONTROLLER)
732 u32 intf_type;
733 int ret;
734
735 if (!vdev->v4l2_dev->mdev)
736 return 0;
737
738 vdev->entity.function = MEDIA_ENT_F_UNKNOWN;
739
740 switch (type) {
741 case VFL_TYPE_GRABBER:
742 intf_type = MEDIA_INTF_T_V4L_VIDEO;
743 vdev->entity.function = MEDIA_ENT_F_IO_V4L;
744 break;
745 case VFL_TYPE_VBI:
746 intf_type = MEDIA_INTF_T_V4L_VBI;
747 vdev->entity.function = MEDIA_ENT_F_IO_VBI;
748 break;
749 case VFL_TYPE_SDR:
750 intf_type = MEDIA_INTF_T_V4L_SWRADIO;
751 vdev->entity.function = MEDIA_ENT_F_IO_SWRADIO;
752 break;
753 case VFL_TYPE_RADIO:
754 intf_type = MEDIA_INTF_T_V4L_RADIO;
755 /*
756 * Radio doesn't have an entity at the V4L2 side to represent
757 * radio input or output. Instead, the audio input/output goes
758 * via either physical wires or ALSA.
759 */
760 break;
761 case VFL_TYPE_SUBDEV:
762 intf_type = MEDIA_INTF_T_V4L_SUBDEV;
763 /* Entity will be created via v4l2_device_register_subdev() */
764 break;
765 default:
766 return 0;
767 }
768
769 if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) {
770 vdev->entity.name = vdev->name;
771
772 /* Needed just for backward compatibility with legacy MC API */
773 vdev->entity.info.dev.major = VIDEO_MAJOR;
774 vdev->entity.info.dev.minor = vdev->minor;
775
776 ret = media_device_register_entity(vdev->v4l2_dev->mdev,
777 &vdev->entity);
778 if (ret < 0) {
779 printk(KERN_WARNING
780 "%s: media_device_register_entity failed\n",
781 __func__);
782 return ret;
783 }
784 }
785
786 vdev->intf_devnode = media_devnode_create(vdev->v4l2_dev->mdev,
787 intf_type,
788 0, VIDEO_MAJOR,
789 vdev->minor);
790 if (!vdev->intf_devnode) {
791 media_device_unregister_entity(&vdev->entity);
792 return -ENOMEM;
793 }
794
795 if (vdev->entity.function != MEDIA_ENT_F_UNKNOWN) {
796 struct media_link *link;
797
798 link = media_create_intf_link(&vdev->entity,
799 &vdev->intf_devnode->intf,
800 MEDIA_LNK_FL_ENABLED);
801 if (!link) {
802 media_devnode_remove(vdev->intf_devnode);
803 media_device_unregister_entity(&vdev->entity);
804 return -ENOMEM;
805 }
806 }
807
808 /* FIXME: how to create the other interface links? */
809
810#endif
811 return 0;
812}
813
726/** 814/**
727 * __video_register_device - register video4linux devices 815 * __video_register_device - register video4linux devices
728 * @vdev: video device structure we want to register 816 * @vdev: video device structure we want to register
@@ -918,22 +1006,9 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
918 /* Increase v4l2_device refcount */ 1006 /* Increase v4l2_device refcount */
919 v4l2_device_get(vdev->v4l2_dev); 1007 v4l2_device_get(vdev->v4l2_dev);
920 1008
921#if defined(CONFIG_MEDIA_CONTROLLER)
922 /* Part 5: Register the entity. */ 1009 /* Part 5: Register the entity. */
923 if (vdev->v4l2_dev->mdev && 1010 ret = video_register_media_controller(vdev, type);
924 vdev->vfl_type != VFL_TYPE_SUBDEV) { 1011
925 vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
926 vdev->entity.name = vdev->name;
927 vdev->entity.info.dev.major = VIDEO_MAJOR;
928 vdev->entity.info.dev.minor = vdev->minor;
929 ret = media_device_register_entity(vdev->v4l2_dev->mdev,
930 &vdev->entity);
931 if (ret < 0)
932 printk(KERN_WARNING
933 "%s: media_device_register_entity failed\n",
934 __func__);
935 }
936#endif
937 /* Part 6: Activate this minor. The char device can now be used. */ 1012 /* Part 6: Activate this minor. The char device can now be used. */
938 set_bit(V4L2_FL_REGISTERED, &vdev->flags); 1013 set_bit(V4L2_FL_REGISTERED, &vdev->flags);
939 1014
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 7129e438f29e..06fa5f1b2cff 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -180,26 +180,26 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
180 return -ENODEV; 180 return -ENODEV;
181 181
182 sd->v4l2_dev = v4l2_dev; 182 sd->v4l2_dev = v4l2_dev;
183 if (sd->internal_ops && sd->internal_ops->registered) {
184 err = sd->internal_ops->registered(sd);
185 if (err)
186 goto error_module;
187 }
188
189 /* This just returns 0 if either of the two args is NULL */ 183 /* This just returns 0 if either of the two args is NULL */
190 err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL); 184 err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler, NULL);
191 if (err) 185 if (err)
192 goto error_unregister; 186 goto error_module;
193 187
194#if defined(CONFIG_MEDIA_CONTROLLER) 188#if defined(CONFIG_MEDIA_CONTROLLER)
195 /* Register the entity. */ 189 /* Register the entity. */
196 if (v4l2_dev->mdev) { 190 if (v4l2_dev->mdev) {
197 err = media_device_register_entity(v4l2_dev->mdev, entity); 191 err = media_device_register_entity(v4l2_dev->mdev, entity);
198 if (err < 0) 192 if (err < 0)
199 goto error_unregister; 193 goto error_module;
200 } 194 }
201#endif 195#endif
202 196
197 if (sd->internal_ops && sd->internal_ops->registered) {
198 err = sd->internal_ops->registered(sd);
199 if (err)
200 goto error_unregister;
201 }
202
203 spin_lock(&v4l2_dev->lock); 203 spin_lock(&v4l2_dev->lock);
204 list_add_tail(&sd->list, &v4l2_dev->subdevs); 204 list_add_tail(&sd->list, &v4l2_dev->subdevs);
205 spin_unlock(&v4l2_dev->lock); 205 spin_unlock(&v4l2_dev->lock);
@@ -207,8 +207,9 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
207 return 0; 207 return 0;
208 208
209error_unregister: 209error_unregister:
210 if (sd->internal_ops && sd->internal_ops->unregistered) 210#if defined(CONFIG_MEDIA_CONTROLLER)
211 sd->internal_ops->unregistered(sd); 211 media_device_unregister_entity(entity);
212#endif
212error_module: 213error_module:
213 if (!sd->owner_v4l2_dev) 214 if (!sd->owner_v4l2_dev)
214 module_put(sd->owner); 215 module_put(sd->owner);
@@ -258,6 +259,19 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
258#if defined(CONFIG_MEDIA_CONTROLLER) 259#if defined(CONFIG_MEDIA_CONTROLLER)
259 sd->entity.info.dev.major = VIDEO_MAJOR; 260 sd->entity.info.dev.major = VIDEO_MAJOR;
260 sd->entity.info.dev.minor = vdev->minor; 261 sd->entity.info.dev.minor = vdev->minor;
262
263 /* Interface is created by __video_register_device() */
264 if (vdev->v4l2_dev->mdev) {
265 struct media_link *link;
266
267 link = media_create_intf_link(&sd->entity,
268 &vdev->intf_devnode->intf,
269 MEDIA_LNK_FL_ENABLED);
270 if (!link) {
271 err = -ENOMEM;
272 goto clean_up;
273 }
274 }
261#endif 275#endif
262 sd->devnode = vdev; 276 sd->devnode = vdev;
263 } 277 }
@@ -294,7 +308,10 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
294 308
295#if defined(CONFIG_MEDIA_CONTROLLER) 309#if defined(CONFIG_MEDIA_CONTROLLER)
296 if (v4l2_dev->mdev) { 310 if (v4l2_dev->mdev) {
297 media_entity_remove_links(&sd->entity); 311 /*
312 * No need to explicitly remove links, as both pads and
313 * links are removed by the function below, in the right order
314 */
298 media_device_unregister_entity(&sd->entity); 315 media_device_unregister_entity(&sd->entity);
299 } 316 }
300#endif 317#endif
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index 5d673357f75f..fc5ff8b215f9 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -651,11 +651,11 @@ struct v4l2_flash *v4l2_flash_init(
651 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 651 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
652 strlcpy(sd->name, config->dev_name, sizeof(sd->name)); 652 strlcpy(sd->name, config->dev_name, sizeof(sd->name));
653 653
654 ret = media_entity_init(&sd->entity, 0, NULL, 0); 654 ret = media_entity_pads_init(&sd->entity, 0, NULL);
655 if (ret < 0) 655 if (ret < 0)
656 return ERR_PTR(ret); 656 return ERR_PTR(ret);
657 657
658 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; 658 sd->entity.function = MEDIA_ENT_F_FLASH;
659 659
660 ret = v4l2_flash_init_controls(v4l2_flash, config); 660 ret = v4l2_flash_init_controls(v4l2_flash, config);
661 if (ret < 0) 661 if (ret < 0)
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 83615b8fb46a..d63083803144 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -526,7 +526,7 @@ static int
526v4l2_subdev_link_validate_get_format(struct media_pad *pad, 526v4l2_subdev_link_validate_get_format(struct media_pad *pad,
527 struct v4l2_subdev_format *fmt) 527 struct v4l2_subdev_format *fmt)
528{ 528{
529 if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) { 529 if (is_media_entity_v4l2_subdev(pad->entity)) {
530 struct v4l2_subdev *sd = 530 struct v4l2_subdev *sd =
531 media_entity_to_v4l2_subdev(pad->entity); 531 media_entity_to_v4l2_subdev(pad->entity);
532 532
@@ -535,9 +535,9 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
535 return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt); 535 return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
536 } 536 }
537 537
538 WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L, 538 WARN(pad->entity->function != MEDIA_ENT_F_IO_V4L,
539 "Driver bug! Wrong media entity type 0x%08x, entity %s\n", 539 "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
540 pad->entity->type, pad->entity->name); 540 pad->entity->function, pad->entity->name);
541 541
542 return -EINVAL; 542 return -EINVAL;
543} 543}
@@ -584,7 +584,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
584 sd->host_priv = NULL; 584 sd->host_priv = NULL;
585#if defined(CONFIG_MEDIA_CONTROLLER) 585#if defined(CONFIG_MEDIA_CONTROLLER)
586 sd->entity.name = sd->name; 586 sd->entity.name = sd->name;
587 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; 587 sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
588#endif 588#endif
589} 589}
590EXPORT_SYMBOL(v4l2_subdev_init); 590EXPORT_SYMBOL(v4l2_subdev_init);
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index c492914768ea..ac78ed2f8bcc 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1712,8 +1712,11 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local,
1712 struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe); 1712 struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
1713 u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input; 1713 u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
1714 1714
1715 switch (local->index | media_entity_type(remote->entity)) { 1715 if (!is_media_entity_v4l2_subdev(remote->entity))
1716 case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 1716 return -EINVAL;
1717
1718 switch (local->index) {
1719 case IPIPE_PAD_SINK:
1717 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1720 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1718 ipipe->input = IPIPE_INPUT_NONE; 1721 ipipe->input = IPIPE_INPUT_NONE;
1719 break; 1722 break;
@@ -1726,7 +1729,7 @@ ipipe_link_setup(struct media_entity *entity, const struct media_pad *local,
1726 ipipe->input = IPIPE_INPUT_CCDC; 1729 ipipe->input = IPIPE_INPUT_CCDC;
1727 break; 1730 break;
1728 1731
1729 case IPIPE_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 1732 case IPIPE_PAD_SOURCE:
1730 /* out to RESIZER */ 1733 /* out to RESIZER */
1731 if (flags & MEDIA_LNK_FL_ENABLED) 1734 if (flags & MEDIA_LNK_FL_ENABLED)
1732 ipipe->output = IPIPE_OUTPUT_RESIZER; 1735 ipipe->output = IPIPE_OUTPUT_RESIZER;
@@ -1840,7 +1843,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
1840 v4l2_ctrl_handler_setup(&ipipe->ctrls); 1843 v4l2_ctrl_handler_setup(&ipipe->ctrls);
1841 sd->ctrl_handler = &ipipe->ctrls; 1844 sd->ctrl_handler = &ipipe->ctrls;
1842 1845
1843 return media_entity_init(me, IPIPE_PADS_NUM, pads, 0); 1846 return media_entity_pads_init(me, IPIPE_PADS_NUM, pads);
1844} 1847}
1845 1848
1846/* 1849/*
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8b230541b1d1..633d6456fdce 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,
885 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 885 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
886 struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); 886 struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
887 struct vpfe_device *vpfe = to_vpfe_device(ipipeif); 887 struct vpfe_device *vpfe = to_vpfe_device(ipipeif);
888 unsigned int index = local->index;
888 889
889 switch (local->index | media_entity_type(remote->entity)) { 890 /* FIXME: this is actually a hack! */
890 case IPIPEIF_PAD_SINK | MEDIA_ENT_T_DEVNODE: 891 if (is_media_entity_v4l2_subdev(remote->entity))
892 index |= 2 << 16;
893
894 switch (index) {
895 case IPIPEIF_PAD_SINK:
891 /* Single shot mode */ 896 /* Single shot mode */
892 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 897 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
893 ipipeif->input = IPIPEIF_INPUT_NONE; 898 ipipeif->input = IPIPEIF_INPUT_NONE;
@@ -896,7 +901,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local,
896 ipipeif->input = IPIPEIF_INPUT_MEMORY; 901 ipipeif->input = IPIPEIF_INPUT_MEMORY;
897 break; 902 break;
898 903
899 case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 904 case IPIPEIF_PAD_SINK | 2 << 16:
900 /* read from isif */ 905 /* read from isif */
901 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 906 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
902 ipipeif->input = IPIPEIF_INPUT_NONE; 907 ipipeif->input = IPIPEIF_INPUT_NONE;
@@ -908,7 +913,7 @@ ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local,
908 ipipeif->input = IPIPEIF_INPUT_ISIF; 913 ipipeif->input = IPIPEIF_INPUT_ISIF;
909 break; 914 break;
910 915
911 case IPIPEIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 916 case IPIPEIF_PAD_SOURCE | 2 << 16:
912 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 917 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
913 ipipeif->output = IPIPEIF_OUTPUT_NONE; 918 ipipeif->output = IPIPEIF_OUTPUT_NONE;
914 break; 919 break;
@@ -971,7 +976,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
971 ipipeif->video_in.vpfe_dev = vpfe_dev; 976 ipipeif->video_in.vpfe_dev = vpfe_dev;
972 977
973 flags = 0; 978 flags = 0;
974 ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0, 979 ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
975 &ipipeif->subdev.entity, 0, flags); 980 &ipipeif->subdev.entity, 0, flags);
976 if (ret < 0) 981 if (ret < 0)
977 goto fail; 982 goto fail;
@@ -1026,7 +1031,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
1026 ipipeif->output = IPIPEIF_OUTPUT_NONE; 1031 ipipeif->output = IPIPEIF_OUTPUT_NONE;
1027 me->ops = &ipipeif_media_ops; 1032 me->ops = &ipipeif_media_ops;
1028 1033
1029 ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads, 0); 1034 ret = media_entity_pads_init(me, IPIPEIF_NUM_PADS, pads);
1030 if (ret) 1035 if (ret)
1031 goto fail; 1036 goto fail;
1032 1037
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index 80907b464412..99057892d88d 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,
1707{ 1707{
1708 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 1708 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1709 struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd); 1709 struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
1710 unsigned int index = local->index;
1710 1711
1711 switch (local->index | media_entity_type(remote->entity)) { 1712 /* FIXME: this is actually a hack! */
1712 case ISIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 1713 if (is_media_entity_v4l2_subdev(remote->entity))
1714 index |= 2 << 16;
1715
1716 switch (index) {
1717 case ISIF_PAD_SINK | 2 << 16:
1713 /* read from decoder/sensor */ 1718 /* read from decoder/sensor */
1714 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1719 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1715 isif->input = ISIF_INPUT_NONE; 1720 isif->input = ISIF_INPUT_NONE;
@@ -1720,7 +1725,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local,
1720 isif->input = ISIF_INPUT_PARALLEL; 1725 isif->input = ISIF_INPUT_PARALLEL;
1721 break; 1726 break;
1722 1727
1723 case ISIF_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: 1728 case ISIF_PAD_SOURCE:
1724 /* write to memory */ 1729 /* write to memory */
1725 if (flags & MEDIA_LNK_FL_ENABLED) 1730 if (flags & MEDIA_LNK_FL_ENABLED)
1726 isif->output = ISIF_OUTPUT_MEMORY; 1731 isif->output = ISIF_OUTPUT_MEMORY;
@@ -1728,7 +1733,7 @@ isif_link_setup(struct media_entity *entity, const struct media_pad *local,
1728 isif->output = ISIF_OUTPUT_NONE; 1733 isif->output = ISIF_OUTPUT_NONE;
1729 break; 1734 break;
1730 1735
1731 case ISIF_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 1736 case ISIF_PAD_SOURCE | 2 << 16:
1732 if (flags & MEDIA_LNK_FL_ENABLED) 1737 if (flags & MEDIA_LNK_FL_ENABLED)
1733 isif->output = ISIF_OUTPUT_IPIPEIF; 1738 isif->output = ISIF_OUTPUT_IPIPEIF;
1734 else 1739 else
@@ -1817,7 +1822,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
1817 isif->video_out.vpfe_dev = vpfe_dev; 1822 isif->video_out.vpfe_dev = vpfe_dev;
1818 flags = 0; 1823 flags = 0;
1819 /* connect isif to video node */ 1824 /* connect isif to video node */
1820 ret = media_entity_create_link(&isif->subdev.entity, 1, 1825 ret = media_create_pad_link(&isif->subdev.entity, 1,
1821 &isif->video_out.video_dev.entity, 1826 &isif->video_out.video_dev.entity,
1822 0, flags); 1827 0, flags);
1823 if (ret < 0) 1828 if (ret < 0)
@@ -2052,7 +2057,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev)
2052 isif->input = ISIF_INPUT_NONE; 2057 isif->input = ISIF_INPUT_NONE;
2053 isif->output = ISIF_OUTPUT_NONE; 2058 isif->output = ISIF_OUTPUT_NONE;
2054 me->ops = &isif_media_ops; 2059 me->ops = &isif_media_ops;
2055 status = media_entity_init(me, ISIF_PADS_NUM, pads, 0); 2060 status = media_entity_pads_init(me, ISIF_PADS_NUM, pads);
2056 if (status) 2061 if (status)
2057 goto isif_fail; 2062 goto isif_fail;
2058 isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2063 isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index d892fee3f52f..a91395ce91e1 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1648,10 +1648,15 @@ static int resizer_link_setup(struct media_entity *entity,
1648 struct vpfe_device *vpfe_dev = to_vpfe_device(resizer); 1648 struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
1649 u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output; 1649 u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output;
1650 u16 ipipe_source = vpfe_dev->vpfe_ipipe.output; 1650 u16 ipipe_source = vpfe_dev->vpfe_ipipe.output;
1651 unsigned int index = local->index;
1652
1653 /* FIXME: this is actually a hack! */
1654 if (is_media_entity_v4l2_subdev(remote->entity))
1655 index |= 2 << 16;
1651 1656
1652 if (&resizer->crop_resizer.subdev == sd) { 1657 if (&resizer->crop_resizer.subdev == sd) {
1653 switch (local->index | media_entity_type(remote->entity)) { 1658 switch (index) {
1654 case RESIZER_CROP_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 1659 case RESIZER_CROP_PAD_SINK | 2 << 16:
1655 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1660 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1656 resizer->crop_resizer.input = 1661 resizer->crop_resizer.input =
1657 RESIZER_CROP_INPUT_NONE; 1662 RESIZER_CROP_INPUT_NONE;
@@ -1671,7 +1676,7 @@ static int resizer_link_setup(struct media_entity *entity,
1671 return -EINVAL; 1676 return -EINVAL;
1672 break; 1677 break;
1673 1678
1674 case RESIZER_CROP_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 1679 case RESIZER_CROP_PAD_SOURCE | 2 << 16:
1675 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1680 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1676 resizer->crop_resizer.output = 1681 resizer->crop_resizer.output =
1677 RESIZER_CROP_OUTPUT_NONE; 1682 RESIZER_CROP_OUTPUT_NONE;
@@ -1683,7 +1688,7 @@ static int resizer_link_setup(struct media_entity *entity,
1683 resizer->crop_resizer.output = RESIZER_A; 1688 resizer->crop_resizer.output = RESIZER_A;
1684 break; 1689 break;
1685 1690
1686 case RESIZER_CROP_PAD_SOURCE2 | MEDIA_ENT_T_V4L2_SUBDEV: 1691 case RESIZER_CROP_PAD_SOURCE2 | 2 << 16:
1687 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1692 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1688 resizer->crop_resizer.output2 = 1693 resizer->crop_resizer.output2 =
1689 RESIZER_CROP_OUTPUT_NONE; 1694 RESIZER_CROP_OUTPUT_NONE;
@@ -1699,8 +1704,8 @@ static int resizer_link_setup(struct media_entity *entity,
1699 return -EINVAL; 1704 return -EINVAL;
1700 } 1705 }
1701 } else if (&resizer->resizer_a.subdev == sd) { 1706 } else if (&resizer->resizer_a.subdev == sd) {
1702 switch (local->index | media_entity_type(remote->entity)) { 1707 switch (index) {
1703 case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 1708 case RESIZER_PAD_SINK | 2 << 16:
1704 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1709 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1705 resizer->resizer_a.input = RESIZER_INPUT_NONE; 1710 resizer->resizer_a.input = RESIZER_INPUT_NONE;
1706 break; 1711 break;
@@ -1710,7 +1715,7 @@ static int resizer_link_setup(struct media_entity *entity,
1710 resizer->resizer_a.input = RESIZER_INPUT_CROP_RESIZER; 1715 resizer->resizer_a.input = RESIZER_INPUT_CROP_RESIZER;
1711 break; 1716 break;
1712 1717
1713 case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: 1718 case RESIZER_PAD_SOURCE:
1714 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1719 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1715 resizer->resizer_a.output = RESIZER_OUTPUT_NONE; 1720 resizer->resizer_a.output = RESIZER_OUTPUT_NONE;
1716 break; 1721 break;
@@ -1724,8 +1729,8 @@ static int resizer_link_setup(struct media_entity *entity,
1724 return -EINVAL; 1729 return -EINVAL;
1725 } 1730 }
1726 } else if (&resizer->resizer_b.subdev == sd) { 1731 } else if (&resizer->resizer_b.subdev == sd) {
1727 switch (local->index | media_entity_type(remote->entity)) { 1732 switch (index) {
1728 case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 1733 case RESIZER_PAD_SINK | 2 << 16:
1729 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1734 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1730 resizer->resizer_b.input = RESIZER_INPUT_NONE; 1735 resizer->resizer_b.input = RESIZER_INPUT_NONE;
1731 break; 1736 break;
@@ -1735,7 +1740,7 @@ static int resizer_link_setup(struct media_entity *entity,
1735 resizer->resizer_b.input = RESIZER_INPUT_CROP_RESIZER; 1740 resizer->resizer_b.input = RESIZER_INPUT_CROP_RESIZER;
1736 break; 1741 break;
1737 1742
1738 case RESIZER_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: 1743 case RESIZER_PAD_SOURCE:
1739 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 1744 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
1740 resizer->resizer_b.output = RESIZER_OUTPUT_NONE; 1745 resizer->resizer_b.output = RESIZER_OUTPUT_NONE;
1741 break; 1746 break;
@@ -1826,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
1826 resizer->resizer_b.video_out.vpfe_dev = vpfe_dev; 1831 resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
1827 1832
1828 /* create link between Resizer Crop----> Resizer A*/ 1833 /* create link between Resizer Crop----> Resizer A*/
1829 ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1, 1834 ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
1830 &resizer->resizer_a.subdev.entity, 1835 &resizer->resizer_a.subdev.entity,
1831 0, flags); 1836 0, flags);
1832 if (ret < 0) 1837 if (ret < 0)
1833 goto out_create_link; 1838 goto out_create_link;
1834 1839
1835 /* create link between Resizer Crop----> Resizer B*/ 1840 /* create link between Resizer Crop----> Resizer B*/
1836 ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2, 1841 ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
1837 &resizer->resizer_b.subdev.entity, 1842 &resizer->resizer_b.subdev.entity,
1838 0, flags); 1843 0, flags);
1839 if (ret < 0) 1844 if (ret < 0)
1840 goto out_create_link; 1845 goto out_create_link;
1841 1846
1842 /* create link between Resizer A ----> video out */ 1847 /* create link between Resizer A ----> video out */
1843 ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1, 1848 ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
1844 &resizer->resizer_a.video_out.video_dev.entity, 0, flags); 1849 &resizer->resizer_a.video_out.video_dev.entity, 0, flags);
1845 if (ret < 0) 1850 if (ret < 0)
1846 goto out_create_link; 1851 goto out_create_link;
1847 1852
1848 /* create link between Resizer B ----> video out */ 1853 /* create link between Resizer B ----> video out */
1849 ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1, 1854 ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
1850 &resizer->resizer_b.video_out.video_dev.entity, 0, flags); 1855 &resizer->resizer_b.video_out.video_dev.entity, 0, flags);
1851 if (ret < 0) 1856 if (ret < 0)
1852 goto out_create_link; 1857 goto out_create_link;
@@ -1910,7 +1915,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
1910 vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE; 1915 vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE;
1911 vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz; 1916 vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz;
1912 me->ops = &resizer_media_ops; 1917 me->ops = &resizer_media_ops;
1913 ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads, 0); 1918 ret = media_entity_pads_init(me, RESIZER_CROP_PADS_NUM, pads);
1914 if (ret) 1919 if (ret)
1915 return ret; 1920 return ret;
1916 1921
@@ -1932,7 +1937,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
1932 vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE; 1937 vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE;
1933 vpfe_rsz->resizer_a.rsz_device = vpfe_rsz; 1938 vpfe_rsz->resizer_a.rsz_device = vpfe_rsz;
1934 me->ops = &resizer_media_ops; 1939 me->ops = &resizer_media_ops;
1935 ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0); 1940 ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
1936 if (ret) 1941 if (ret)
1937 return ret; 1942 return ret;
1938 1943
@@ -1954,7 +1959,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
1954 vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE; 1959 vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE;
1955 vpfe_rsz->resizer_b.rsz_device = vpfe_rsz; 1960 vpfe_rsz->resizer_b.rsz_device = vpfe_rsz;
1956 me->ops = &resizer_media_ops; 1961 me->ops = &resizer_media_ops;
1957 ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0); 1962 ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
1958 if (ret) 1963 if (ret)
1959 return ret; 1964 return ret;
1960 1965
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 69b678ca40c0..ec46f366dd17 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)
445 /* if entity has no pads (ex: amplifier), 445 /* if entity has no pads (ex: amplifier),
446 cant establish link */ 446 cant establish link */
447 if (vpfe_dev->sd[i]->entity.num_pads) { 447 if (vpfe_dev->sd[i]->entity.num_pads) {
448 ret = media_entity_create_link(&vpfe_dev->sd[i]->entity, 448 ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
449 0, &vpfe_dev->vpfe_isif.subdev.entity, 449 0, &vpfe_dev->vpfe_isif.subdev.entity,
450 0, flags); 450 0, flags);
451 if (ret < 0) 451 if (ret < 0)
452 goto out_resizer_register; 452 goto out_resizer_register;
453 } 453 }
454 454
455 ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1, 455 ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
456 &vpfe_dev->vpfe_ipipeif.subdev.entity, 456 &vpfe_dev->vpfe_ipipeif.subdev.entity,
457 0, flags); 457 0, flags);
458 if (ret < 0) 458 if (ret < 0)
459 goto out_resizer_register; 459 goto out_resizer_register;
460 460
461 ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, 461 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
462 &vpfe_dev->vpfe_ipipe.subdev.entity, 462 &vpfe_dev->vpfe_ipipe.subdev.entity,
463 0, flags); 463 0, flags);
464 if (ret < 0) 464 if (ret < 0)
465 goto out_resizer_register; 465 goto out_resizer_register;
466 466
467 ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity, 467 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
468 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity, 468 1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
469 0, flags); 469 0, flags);
470 if (ret < 0) 470 if (ret < 0)
471 goto out_resizer_register; 471 goto out_resizer_register;
472 472
473 ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1, 473 ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
474 &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity, 474 &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
475 0, flags); 475 0, flags);
476 if (ret < 0) 476 if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index adb2bc8811ab..3ec7e65a3ffa 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)
88{ 88{
89 struct media_pad *remote = media_entity_remote_pad(&video->pad); 89 struct media_pad *remote = media_entity_remote_pad(&video->pad);
90 90
91 if (remote == NULL || remote->entity->type != MEDIA_ENT_T_V4L2_SUBDEV) 91 if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
92 return NULL; 92 return NULL;
93 if (pad) 93 if (pad)
94 *pad = remote->index; 94 *pad = remote->index;
@@ -127,13 +127,14 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
127} 127}
128 128
129/* make a note of pipeline details */ 129/* make a note of pipeline details */
130static void vpfe_prepare_pipeline(struct vpfe_video_device *video) 130static int vpfe_prepare_pipeline(struct vpfe_video_device *video)
131{ 131{
132 struct media_entity_graph graph;
132 struct media_entity *entity = &video->video_dev.entity; 133 struct media_entity *entity = &video->video_dev.entity;
133 struct media_device *mdev = entity->parent; 134 struct media_device *mdev = entity->graph_obj.mdev;
134 struct vpfe_pipeline *pipe = &video->pipe; 135 struct vpfe_pipeline *pipe = &video->pipe;
135 struct vpfe_video_device *far_end = NULL; 136 struct vpfe_video_device *far_end = NULL;
136 struct media_entity_graph graph; 137 int ret;
137 138
138 pipe->input_num = 0; 139 pipe->input_num = 0;
139 pipe->output_num = 0; 140 pipe->output_num = 0;
@@ -144,11 +145,16 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
144 pipe->outputs[pipe->output_num++] = video; 145 pipe->outputs[pipe->output_num++] = video;
145 146
146 mutex_lock(&mdev->graph_mutex); 147 mutex_lock(&mdev->graph_mutex);
148 ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
149 if (ret) {
150 mutex_unlock(&video->lock);
151 return -ENOMEM;
152 }
147 media_entity_graph_walk_start(&graph, entity); 153 media_entity_graph_walk_start(&graph, entity);
148 while ((entity = media_entity_graph_walk_next(&graph))) { 154 while ((entity = media_entity_graph_walk_next(&graph))) {
149 if (entity == &video->video_dev.entity) 155 if (entity == &video->video_dev.entity)
150 continue; 156 continue;
151 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 157 if (!is_media_entity_v4l2_io(entity))
152 continue; 158 continue;
153 far_end = to_vpfe_video(media_entity_to_video_device(entity)); 159 far_end = to_vpfe_video(media_entity_to_video_device(entity));
154 if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 160 if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -156,7 +162,10 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
156 else 162 else
157 pipe->outputs[pipe->output_num++] = far_end; 163 pipe->outputs[pipe->output_num++] = far_end;
158 } 164 }
165 media_entity_graph_walk_cleanup(&graph);
159 mutex_unlock(&mdev->graph_mutex); 166 mutex_unlock(&mdev->graph_mutex);
167
168 return 0;
160} 169}
161 170
162/* update pipe state selected by user */ 171/* update pipe state selected by user */
@@ -165,7 +174,9 @@ static int vpfe_update_pipe_state(struct vpfe_video_device *video)
165 struct vpfe_pipeline *pipe = &video->pipe; 174 struct vpfe_pipeline *pipe = &video->pipe;
166 int ret; 175 int ret;
167 176
168 vpfe_prepare_pipeline(video); 177 ret = vpfe_prepare_pipeline(video);
178 if (ret)
179 return ret;
169 180
170 /* Find out if there is any input video 181 /* Find out if there is any input video
171 if yes, it is single shot. 182 if yes, it is single shot.
@@ -243,8 +254,7 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
243 254
244 /* Retrieve the source format */ 255 /* Retrieve the source format */
245 pad = media_entity_remote_pad(pad); 256 pad = media_entity_remote_pad(pad);
246 if (pad == NULL || 257 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
247 pad->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
248 break; 258 break;
249 259
250 subdev = media_entity_to_v4l2_subdev(pad->entity); 260 subdev = media_entity_to_v4l2_subdev(pad->entity);
@@ -277,29 +287,35 @@ static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
277 */ 287 */
278static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe) 288static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
279{ 289{
280 struct media_entity_graph graph;
281 struct media_entity *entity; 290 struct media_entity *entity;
282 struct v4l2_subdev *subdev; 291 struct v4l2_subdev *subdev;
283 struct media_device *mdev; 292 struct media_device *mdev;
284 int ret = 0; 293 int ret;
285 294
286 if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS) 295 if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS)
287 entity = vpfe_get_input_entity(pipe->outputs[0]); 296 entity = vpfe_get_input_entity(pipe->outputs[0]);
288 else 297 else
289 entity = &pipe->inputs[0]->video_dev.entity; 298 entity = &pipe->inputs[0]->video_dev.entity;
290 299
291 mdev = entity->parent; 300 mdev = entity->graph_obj.mdev;
292 mutex_lock(&mdev->graph_mutex); 301 mutex_lock(&mdev->graph_mutex);
293 media_entity_graph_walk_start(&graph, entity); 302 ret = media_entity_graph_walk_init(&pipe->graph,
294 while ((entity = media_entity_graph_walk_next(&graph))) { 303 entity->graph_obj.mdev);
304 if (ret)
305 goto out;
306 media_entity_graph_walk_start(&pipe->graph, entity);
307 while ((entity = media_entity_graph_walk_next(&pipe->graph))) {
295 308
296 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) 309 if (!is_media_entity_v4l2_subdev(entity))
297 continue; 310 continue;
298 subdev = media_entity_to_v4l2_subdev(entity); 311 subdev = media_entity_to_v4l2_subdev(entity);
299 ret = v4l2_subdev_call(subdev, video, s_stream, 1); 312 ret = v4l2_subdev_call(subdev, video, s_stream, 1);
300 if (ret < 0 && ret != -ENOIOCTLCMD) 313 if (ret < 0 && ret != -ENOIOCTLCMD)
301 break; 314 break;
302 } 315 }
316out:
317 if (ret)
318 media_entity_graph_walk_cleanup(&pipe->graph);
303 mutex_unlock(&mdev->graph_mutex); 319 mutex_unlock(&mdev->graph_mutex);
304 return ret; 320 return ret;
305} 321}
@@ -317,7 +333,6 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
317 */ 333 */
318static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe) 334static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
319{ 335{
320 struct media_entity_graph graph;
321 struct media_entity *entity; 336 struct media_entity *entity;
322 struct v4l2_subdev *subdev; 337 struct v4l2_subdev *subdev;
323 struct media_device *mdev; 338 struct media_device *mdev;
@@ -328,13 +343,13 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
328 else 343 else
329 entity = &pipe->inputs[0]->video_dev.entity; 344 entity = &pipe->inputs[0]->video_dev.entity;
330 345
331 mdev = entity->parent; 346 mdev = entity->graph_obj.mdev;
332 mutex_lock(&mdev->graph_mutex); 347 mutex_lock(&mdev->graph_mutex);
333 media_entity_graph_walk_start(&graph, entity); 348 media_entity_graph_walk_start(&pipe->graph, entity);
334 349
335 while ((entity = media_entity_graph_walk_next(&graph))) { 350 while ((entity = media_entity_graph_walk_next(&pipe->graph))) {
336 351
337 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) 352 if (!is_media_entity_v4l2_subdev(entity))
338 continue; 353 continue;
339 subdev = media_entity_to_v4l2_subdev(entity); 354 subdev = media_entity_to_v4l2_subdev(entity);
340 ret = v4l2_subdev_call(subdev, video, s_stream, 0); 355 ret = v4l2_subdev_call(subdev, video, s_stream, 0);
@@ -343,6 +358,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
343 } 358 }
344 mutex_unlock(&mdev->graph_mutex); 359 mutex_unlock(&mdev->graph_mutex);
345 360
361 media_entity_graph_walk_cleanup(&pipe->graph);
346 return ret ? -ETIMEDOUT : 0; 362 return ret ? -ETIMEDOUT : 0;
347} 363}
348 364
@@ -1600,8 +1616,8 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
1600 spin_lock_init(&video->irqlock); 1616 spin_lock_init(&video->irqlock);
1601 spin_lock_init(&video->dma_queue_lock); 1617 spin_lock_init(&video->dma_queue_lock);
1602 mutex_init(&video->lock); 1618 mutex_init(&video->lock);
1603 ret = media_entity_init(&video->video_dev.entity, 1619 ret = media_entity_pads_init(&video->video_dev.entity,
1604 1, &video->pad, 0); 1620 1, &video->pad);
1605 if (ret < 0) 1621 if (ret < 0)
1606 return ret; 1622 return ret;
1607 1623
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.h b/drivers/staging/media/davinci_vpfe/vpfe_video.h
index 673cefe3ef61..653334d537d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.h
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.h
@@ -52,6 +52,7 @@ enum vpfe_video_state {
52struct vpfe_pipeline { 52struct vpfe_pipeline {
53 /* media pipeline */ 53 /* media pipeline */
54 struct media_pipeline *pipe; 54 struct media_pipeline *pipe;
55 struct media_entity_graph graph;
55 /* state of the pipeline, continuous, 56 /* state of the pipeline, continuous,
56 * single-shot or stopped 57 * single-shot or stopped
57 */ 58 */
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index e27a988540a6..30b473cfb020 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -389,15 +389,15 @@ static irqreturn_t iss_isr(int irq, void *_iss)
389 * 389 *
390 * Return the total number of users of all video device nodes in the pipeline. 390 * Return the total number of users of all video device nodes in the pipeline.
391 */ 391 */
392static int iss_pipeline_pm_use_count(struct media_entity *entity) 392static int iss_pipeline_pm_use_count(struct media_entity *entity,
393 struct media_entity_graph *graph)
393{ 394{
394 struct media_entity_graph graph;
395 int use = 0; 395 int use = 0;
396 396
397 media_entity_graph_walk_start(&graph, entity); 397 media_entity_graph_walk_start(graph, entity);
398 398
399 while ((entity = media_entity_graph_walk_next(&graph))) { 399 while ((entity = media_entity_graph_walk_next(graph))) {
400 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE) 400 if (is_media_entity_v4l2_io(entity))
401 use += entity->use_count; 401 use += entity->use_count;
402 } 402 }
403 403
@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
419{ 419{
420 struct v4l2_subdev *subdev; 420 struct v4l2_subdev *subdev;
421 421
422 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV 422 subdev = is_media_entity_v4l2_subdev(entity)
423 ? media_entity_to_v4l2_subdev(entity) : NULL; 423 ? media_entity_to_v4l2_subdev(entity) : NULL;
424 424
425 if (entity->use_count == 0 && change > 0 && subdev) { 425 if (entity->use_count == 0 && change > 0 && subdev) {
@@ -449,29 +449,29 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
449 * 449 *
450 * Return 0 on success or a negative error code on failure. 450 * Return 0 on success or a negative error code on failure.
451 */ 451 */
452static int iss_pipeline_pm_power(struct media_entity *entity, int change) 452static int iss_pipeline_pm_power(struct media_entity *entity, int change,
453 struct media_entity_graph *graph)
453{ 454{
454 struct media_entity_graph graph;
455 struct media_entity *first = entity; 455 struct media_entity *first = entity;
456 int ret = 0; 456 int ret = 0;
457 457
458 if (!change) 458 if (!change)
459 return 0; 459 return 0;
460 460
461 media_entity_graph_walk_start(&graph, entity); 461 media_entity_graph_walk_start(graph, entity);
462 462
463 while (!ret && (entity = media_entity_graph_walk_next(&graph))) 463 while (!ret && (entity = media_entity_graph_walk_next(graph)))
464 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 464 if (is_media_entity_v4l2_subdev(entity))
465 ret = iss_pipeline_pm_power_one(entity, change); 465 ret = iss_pipeline_pm_power_one(entity, change);
466 466
467 if (!ret) 467 if (!ret)
468 return 0; 468 return 0;
469 469
470 media_entity_graph_walk_start(&graph, first); 470 media_entity_graph_walk_start(graph, first);
471 471
472 while ((first = media_entity_graph_walk_next(&graph)) && 472 while ((first = media_entity_graph_walk_next(graph)) &&
473 first != entity) 473 first != entity)
474 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE) 474 if (is_media_entity_v4l2_subdev(first))
475 iss_pipeline_pm_power_one(first, -change); 475 iss_pipeline_pm_power_one(first, -change);
476 476
477 return ret; 477 return ret;
@@ -489,23 +489,24 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)
489 * off is assumed to never fail. No failure can occur when the use parameter is 489 * off is assumed to never fail. No failure can occur when the use parameter is
490 * set to 0. 490 * set to 0.
491 */ 491 */
492int omap4iss_pipeline_pm_use(struct media_entity *entity, int use) 492int omap4iss_pipeline_pm_use(struct media_entity *entity, int use,
493 struct media_entity_graph *graph)
493{ 494{
494 int change = use ? 1 : -1; 495 int change = use ? 1 : -1;
495 int ret; 496 int ret;
496 497
497 mutex_lock(&entity->parent->graph_mutex); 498 mutex_lock(&entity->graph_obj.mdev->graph_mutex);
498 499
499 /* Apply use count to node. */ 500 /* Apply use count to node. */
500 entity->use_count += change; 501 entity->use_count += change;
501 WARN_ON(entity->use_count < 0); 502 WARN_ON(entity->use_count < 0);
502 503
503 /* Apply power change to connected non-nodes. */ 504 /* Apply power change to connected non-nodes. */
504 ret = iss_pipeline_pm_power(entity, change); 505 ret = iss_pipeline_pm_power(entity, change, graph);
505 if (ret < 0) 506 if (ret < 0)
506 entity->use_count -= change; 507 entity->use_count -= change;
507 508
508 mutex_unlock(&entity->parent->graph_mutex); 509 mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
509 510
510 return ret; 511 return ret;
511} 512}
@@ -526,34 +527,48 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
526static int iss_pipeline_link_notify(struct media_link *link, u32 flags, 527static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
527 unsigned int notification) 528 unsigned int notification)
528{ 529{
530 struct media_entity_graph *graph =
531 &container_of(link->graph_obj.mdev, struct iss_device,
532 media_dev)->pm_count_graph;
529 struct media_entity *source = link->source->entity; 533 struct media_entity *source = link->source->entity;
530 struct media_entity *sink = link->sink->entity; 534 struct media_entity *sink = link->sink->entity;
531 int source_use = iss_pipeline_pm_use_count(source); 535 int source_use;
532 int sink_use = iss_pipeline_pm_use_count(sink); 536 int sink_use;
533 int ret; 537 int ret;
534 538
539 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
540 ret = media_entity_graph_walk_init(graph,
541 link->graph_obj.mdev);
542 if (ret)
543 return ret;
544 }
545
546 source_use = iss_pipeline_pm_use_count(source, graph);
547 sink_use = iss_pipeline_pm_use_count(sink, graph);
548
535 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 549 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
536 !(link->flags & MEDIA_LNK_FL_ENABLED)) { 550 !(flags & MEDIA_LNK_FL_ENABLED)) {
537 /* Powering off entities is assumed to never fail. */ 551 /* Powering off entities is assumed to never fail. */
538 iss_pipeline_pm_power(source, -sink_use); 552 iss_pipeline_pm_power(source, -sink_use, graph);
539 iss_pipeline_pm_power(sink, -source_use); 553 iss_pipeline_pm_power(sink, -source_use, graph);
540 return 0; 554 return 0;
541 } 555 }
542 556
543 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH && 557 if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
544 (flags & MEDIA_LNK_FL_ENABLED)) { 558 (flags & MEDIA_LNK_FL_ENABLED)) {
545 ret = iss_pipeline_pm_power(source, sink_use); 559 ret = iss_pipeline_pm_power(source, sink_use, graph);
546 if (ret < 0) 560 if (ret < 0)
547 return ret; 561 return ret;
548 562
549 ret = iss_pipeline_pm_power(sink, source_use); 563 ret = iss_pipeline_pm_power(sink, source_use, graph);
550 if (ret < 0) 564 if (ret < 0)
551 iss_pipeline_pm_power(source, -sink_use); 565 iss_pipeline_pm_power(source, -sink_use, graph);
552
553 return ret;
554 } 566 }
555 567
556 return 0; 568 if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH)
569 media_entity_graph_walk_cleanup(graph);
570
571 return ret;
557} 572}
558 573
559/* ----------------------------------------------------------------------------- 574/* -----------------------------------------------------------------------------
@@ -590,8 +605,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,
590 break; 605 break;
591 606
592 pad = media_entity_remote_pad(pad); 607 pad = media_entity_remote_pad(pad);
593 if (!pad || 608 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
594 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
595 break; 609 break;
596 610
597 entity = pad->entity; 611 entity = pad->entity;
@@ -607,7 +621,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,
607 * crashed. Mark it as such, the ISS will be reset when 621 * crashed. Mark it as such, the ISS will be reset when
608 * applications will release it. 622 * applications will release it.
609 */ 623 */
610 iss->crashed |= 1U << subdev->entity.id; 624 media_entity_enum_set(&iss->crashed, &subdev->entity);
611 failure = -ETIMEDOUT; 625 failure = -ETIMEDOUT;
612 } 626 }
613 } 627 }
@@ -642,7 +656,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,
642 * pipeline won't start anyway (those entities would then likely fail to 656 * pipeline won't start anyway (those entities would then likely fail to
643 * stop, making the problem worse). 657 * stop, making the problem worse).
644 */ 658 */
645 if (pipe->entities & iss->crashed) 659 if (media_entity_enum_intersects(&pipe->ent_enum, &iss->crashed))
646 return -EIO; 660 return -EIO;
647 661
648 spin_lock_irqsave(&pipe->lock, flags); 662 spin_lock_irqsave(&pipe->lock, flags);
@@ -658,8 +672,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,
658 break; 672 break;
659 673
660 pad = media_entity_remote_pad(pad); 674 pad = media_entity_remote_pad(pad);
661 if (!pad || 675 if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
662 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
663 break; 676 break;
664 677
665 entity = pad->entity; 678 entity = pad->entity;
@@ -763,7 +776,8 @@ static int iss_reset(struct iss_device *iss)
763 return -ETIMEDOUT; 776 return -ETIMEDOUT;
764 } 777 }
765 778
766 iss->crashed = 0; 779 media_entity_enum_zero(&iss->crashed);
780
767 return 0; 781 return 0;
768} 782}
769 783
@@ -1092,7 +1106,7 @@ void omap4iss_put(struct iss_device *iss)
1092 * be worth investigating whether resetting the ISP only can't 1106 * be worth investigating whether resetting the ISP only can't
1093 * fix the problem in some cases. 1107 * fix the problem in some cases.
1094 */ 1108 */
1095 if (iss->crashed) 1109 if (!media_entity_enum_empty(&iss->crashed))
1096 iss_reset(iss); 1110 iss_reset(iss);
1097 iss_disable_clocks(iss); 1111 iss_disable_clocks(iss);
1098 } 1112 }
@@ -1259,7 +1273,7 @@ static int iss_register_entities(struct iss_device *iss)
1259 goto done; 1273 goto done;
1260 } 1274 }
1261 1275
1262 ret = media_entity_create_link(&sensor->entity, 0, input, pad, 1276 ret = media_create_pad_link(&sensor->entity, 0, input, pad,
1263 flags); 1277 flags);
1264 if (ret < 0) 1278 if (ret < 0)
1265 goto done; 1279 goto done;
@@ -1274,6 +1288,68 @@ done:
1274 return ret; 1288 return ret;
1275} 1289}
1276 1290
1291/*
1292 * iss_create_links() - Pads links creation for the subdevices
1293 * @iss : Pointer to ISS device
1294 *
1295 * return negative error code or zero on success
1296 */
1297static int iss_create_links(struct iss_device *iss)
1298{
1299 int ret;
1300
1301 ret = omap4iss_csi2_create_links(iss);
1302 if (ret < 0) {
1303 dev_err(iss->dev, "CSI2 pads links creation failed\n");
1304 return ret;
1305 }
1306
1307 ret = omap4iss_ipipeif_create_links(iss);
1308 if (ret < 0) {
1309 dev_err(iss->dev, "ISP IPIPEIF pads links creation failed\n");
1310 return ret;
1311 }
1312
1313 ret = omap4iss_resizer_create_links(iss);
1314 if (ret < 0) {
1315 dev_err(iss->dev, "ISP RESIZER pads links creation failed\n");
1316 return ret;
1317 }
1318
1319 /* Connect the submodules. */
1320 ret = media_create_pad_link(
1321 &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
1322 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1323 if (ret < 0)
1324 return ret;
1325
1326 ret = media_create_pad_link(
1327 &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
1328 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1329 if (ret < 0)
1330 return ret;
1331
1332 ret = media_create_pad_link(
1333 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1334 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1335 if (ret < 0)
1336 return ret;
1337
1338 ret = media_create_pad_link(
1339 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1340 &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
1341 if (ret < 0)
1342 return ret;
1343
1344 ret = media_create_pad_link(
1345 &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
1346 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1347 if (ret < 0)
1348 return ret;
1349
1350 return 0;
1351};
1352
1277static void iss_cleanup_modules(struct iss_device *iss) 1353static void iss_cleanup_modules(struct iss_device *iss)
1278{ 1354{
1279 omap4iss_csi2_cleanup(iss); 1355 omap4iss_csi2_cleanup(iss);
@@ -1316,41 +1392,8 @@ static int iss_initialize_modules(struct iss_device *iss)
1316 goto error_resizer; 1392 goto error_resizer;
1317 } 1393 }
1318 1394
1319 /* Connect the submodules. */
1320 ret = media_entity_create_link(
1321 &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
1322 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1323 if (ret < 0)
1324 goto error_link;
1325
1326 ret = media_entity_create_link(
1327 &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
1328 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1329 if (ret < 0)
1330 goto error_link;
1331
1332 ret = media_entity_create_link(
1333 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1334 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1335 if (ret < 0)
1336 goto error_link;
1337
1338 ret = media_entity_create_link(
1339 &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1340 &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
1341 if (ret < 0)
1342 goto error_link;
1343
1344 ret = media_entity_create_link(
1345 &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
1346 &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1347 if (ret < 0)
1348 goto error_link;
1349
1350 return 0; 1395 return 0;
1351 1396
1352error_link:
1353 omap4iss_resizer_cleanup(iss);
1354error_resizer: 1397error_resizer:
1355 omap4iss_ipipe_cleanup(iss); 1398 omap4iss_ipipe_cleanup(iss);
1356error_ipipe: 1399error_ipipe:
@@ -1464,10 +1507,21 @@ static int iss_probe(struct platform_device *pdev)
1464 if (ret < 0) 1507 if (ret < 0)
1465 goto error_modules; 1508 goto error_modules;
1466 1509
1510 ret = media_entity_enum_init(&iss->crashed, &iss->media_dev);
1511 if (ret)
1512 goto error_entities;
1513
1514 ret = iss_create_links(iss);
1515 if (ret < 0)
1516 goto error_entities;
1517
1467 omap4iss_put(iss); 1518 omap4iss_put(iss);
1468 1519
1469 return 0; 1520 return 0;
1470 1521
1522error_entities:
1523 iss_unregister_entities(iss);
1524 media_entity_enum_cleanup(&iss->crashed);
1471error_modules: 1525error_modules:
1472 iss_cleanup_modules(iss); 1526 iss_cleanup_modules(iss);
1473error_iss: 1527error_iss:
@@ -1485,6 +1539,7 @@ static int iss_remove(struct platform_device *pdev)
1485 struct iss_device *iss = platform_get_drvdata(pdev); 1539 struct iss_device *iss = platform_get_drvdata(pdev);
1486 1540
1487 iss_unregister_entities(iss); 1541 iss_unregister_entities(iss);
1542 media_entity_enum_cleanup(&iss->crashed);
1488 iss_cleanup_modules(iss); 1543 iss_cleanup_modules(iss);
1489 1544
1490 return 0; 1545 return 0;
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h
index 5929357fe687..05f08a3caa19 100644
--- a/drivers/staging/media/omap4iss/iss.h
+++ b/drivers/staging/media/omap4iss/iss.h
@@ -82,11 +82,12 @@ struct iss_reg {
82/* 82/*
83 * struct iss_device - ISS device structure. 83 * struct iss_device - ISS device structure.
84 * @syscon: Regmap for the syscon register space 84 * @syscon: Regmap for the syscon register space
85 * @crashed: Bitmask of crashed entities (indexed by entity ID) 85 * @crashed: Crashed entities
86 */ 86 */
87struct iss_device { 87struct iss_device {
88 struct v4l2_device v4l2_dev; 88 struct v4l2_device v4l2_dev;
89 struct media_device media_dev; 89 struct media_device media_dev;
90 struct media_entity_graph pm_count_graph;
90 struct device *dev; 91 struct device *dev;
91 u32 revision; 92 u32 revision;
92 93
@@ -101,7 +102,7 @@ struct iss_device {
101 u64 raw_dmamask; 102 u64 raw_dmamask;
102 103
103 struct mutex iss_mutex; /* For handling ref_count field */ 104 struct mutex iss_mutex; /* For handling ref_count field */
104 unsigned int crashed; 105 struct media_entity_enum crashed;
105 int has_context; 106 int has_context;
106 int ref_count; 107 int ref_count;
107 108
@@ -151,7 +152,8 @@ void omap4iss_isp_subclk_enable(struct iss_device *iss,
151void omap4iss_isp_subclk_disable(struct iss_device *iss, 152void omap4iss_isp_subclk_disable(struct iss_device *iss,
152 enum iss_isp_subclk_resource res); 153 enum iss_isp_subclk_resource res);
153 154
154int omap4iss_pipeline_pm_use(struct media_entity *entity, int use); 155int omap4iss_pipeline_pm_use(struct media_entity *entity, int use,
156 struct media_entity_graph *graph);
155 157
156int omap4iss_register_entities(struct platform_device *pdev, 158int omap4iss_register_entities(struct platform_device *pdev,
157 struct v4l2_device *v4l2_dev); 159 struct v4l2_device *v4l2_dev);
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index b941035139ae..aaca39d751a5 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,
1170 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 1170 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1171 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); 1171 struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1172 struct iss_csi2_ctrl_cfg *ctrl = &csi2->ctrl; 1172 struct iss_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
1173 unsigned int index = local->index;
1174
1175 /* FIXME: this is actually a hack! */
1176 if (is_media_entity_v4l2_subdev(remote->entity))
1177 index |= 2 << 16;
1173 1178
1174 /* 1179 /*
1175 * The ISS core doesn't support pipelines with multiple video outputs. 1180 * The ISS core doesn't support pipelines with multiple video outputs.
1176 * Revisit this when it will be implemented, and return -EBUSY for now. 1181 * Revisit this when it will be implemented, and return -EBUSY for now.
1177 */ 1182 */
1178 1183
1179 switch (local->index | media_entity_type(remote->entity)) { 1184 switch (index) {
1180 case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE: 1185 case CSI2_PAD_SOURCE:
1181 if (flags & MEDIA_LNK_FL_ENABLED) { 1186 if (flags & MEDIA_LNK_FL_ENABLED) {
1182 if (csi2->output & ~CSI2_OUTPUT_MEMORY) 1187 if (csi2->output & ~CSI2_OUTPUT_MEMORY)
1183 return -EBUSY; 1188 return -EBUSY;
@@ -1187,7 +1192,7 @@ static int csi2_link_setup(struct media_entity *entity,
1187 } 1192 }
1188 break; 1193 break;
1189 1194
1190 case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV: 1195 case CSI2_PAD_SOURCE | 2 << 16:
1191 if (flags & MEDIA_LNK_FL_ENABLED) { 1196 if (flags & MEDIA_LNK_FL_ENABLED) {
1192 if (csi2->output & ~CSI2_OUTPUT_IPIPEIF) 1197 if (csi2->output & ~CSI2_OUTPUT_IPIPEIF)
1193 return -EBUSY; 1198 return -EBUSY;
@@ -1271,7 +1276,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
1271 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1276 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1272 1277
1273 me->ops = &csi2_media_ops; 1278 me->ops = &csi2_media_ops;
1274 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0); 1279 ret = media_entity_pads_init(me, CSI2_PADS_NUM, pads);
1275 if (ret < 0) 1280 if (ret < 0)
1276 return ret; 1281 return ret;
1277 1282
@@ -1290,16 +1295,8 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
1290 if (ret < 0) 1295 if (ret < 0)
1291 goto error_video; 1296 goto error_video;
1292 1297
1293 /* Connect the CSI2 subdev to the video node. */
1294 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1295 &csi2->video_out.video.entity, 0, 0);
1296 if (ret < 0)
1297 goto error_link;
1298
1299 return 0; 1298 return 0;
1300 1299
1301error_link:
1302 omap4iss_video_cleanup(&csi2->video_out);
1303error_video: 1300error_video:
1304 media_entity_cleanup(&csi2->subdev.entity); 1301 media_entity_cleanup(&csi2->subdev.entity);
1305 return ret; 1302 return ret;
@@ -1342,6 +1339,33 @@ int omap4iss_csi2_init(struct iss_device *iss)
1342} 1339}
1343 1340
1344/* 1341/*
1342 * omap4iss_csi2_create_links() - CSI2 pads links creation
1343 * @iss: Pointer to ISS device
1344 *
1345 * return negative error code or zero on success
1346 */
1347int omap4iss_csi2_create_links(struct iss_device *iss)
1348{
1349 struct iss_csi2_device *csi2a = &iss->csi2a;
1350 struct iss_csi2_device *csi2b = &iss->csi2b;
1351 int ret;
1352
1353 /* Connect the CSI2a subdev to the video node. */
1354 ret = media_create_pad_link(&csi2a->subdev.entity, CSI2_PAD_SOURCE,
1355 &csi2a->video_out.video.entity, 0, 0);
1356 if (ret < 0)
1357 return ret;
1358
1359 /* Connect the CSI2b subdev to the video node. */
1360 ret = media_create_pad_link(&csi2b->subdev.entity, CSI2_PAD_SOURCE,
1361 &csi2b->video_out.video.entity, 0, 0);
1362 if (ret < 0)
1363 return ret;
1364
1365 return 0;
1366}
1367
1368/*
1345 * omap4iss_csi2_cleanup - Routine for module driver cleanup 1369 * omap4iss_csi2_cleanup - Routine for module driver cleanup
1346 */ 1370 */
1347void omap4iss_csi2_cleanup(struct iss_device *iss) 1371void 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 f2f5343b4a80..24ab378d469f 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 {
151void omap4iss_csi2_isr(struct iss_csi2_device *csi2); 151void omap4iss_csi2_isr(struct iss_csi2_device *csi2);
152int omap4iss_csi2_reset(struct iss_csi2_device *csi2); 152int omap4iss_csi2_reset(struct iss_csi2_device *csi2);
153int omap4iss_csi2_init(struct iss_device *iss); 153int omap4iss_csi2_init(struct iss_device *iss);
154int omap4iss_csi2_create_links(struct iss_device *iss);
154void omap4iss_csi2_cleanup(struct iss_device *iss); 155void omap4iss_csi2_cleanup(struct iss_device *iss);
155void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2); 156void omap4iss_csi2_unregister_entities(struct iss_csi2_device *csi2);
156int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2, 157int omap4iss_csi2_register_entities(struct iss_csi2_device *csi2,
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c
index dd0abeffd893..d38782e8e84c 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,
447 struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd); 447 struct iss_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
448 struct iss_device *iss = to_iss_device(ipipe); 448 struct iss_device *iss = to_iss_device(ipipe);
449 449
450 switch (local->index | media_entity_type(remote->entity)) { 450 if (!is_media_entity_v4l2_subdev(remote->entity))
451 case IPIPE_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 451 return -EINVAL;
452
453 switch (local->index) {
454 case IPIPE_PAD_SINK:
452 /* Read from IPIPEIF. */ 455 /* Read from IPIPEIF. */
453 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 456 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
454 ipipe->input = IPIPE_INPUT_NONE; 457 ipipe->input = IPIPE_INPUT_NONE;
@@ -463,7 +466,7 @@ static int ipipe_link_setup(struct media_entity *entity,
463 466
464 break; 467 break;
465 468
466 case IPIPE_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: 469 case IPIPE_PAD_SOURCE_VP:
467 /* Send to RESIZER */ 470 /* Send to RESIZER */
468 if (flags & MEDIA_LNK_FL_ENABLED) { 471 if (flags & MEDIA_LNK_FL_ENABLED) {
469 if (ipipe->output & ~IPIPE_OUTPUT_VP) 472 if (ipipe->output & ~IPIPE_OUTPUT_VP)
@@ -513,7 +516,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe)
513 pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; 516 pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
514 517
515 me->ops = &ipipe_media_ops; 518 me->ops = &ipipe_media_ops;
516 ret = media_entity_init(me, IPIPE_PADS_NUM, pads, 0); 519 ret = media_entity_pads_init(me, IPIPE_PADS_NUM, pads);
517 if (ret < 0) 520 if (ret < 0)
518 return ret; 521 return ret;
519 522
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index 5f9e449e7007..23de8330731d 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,
662 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 662 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
663 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd); 663 struct iss_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
664 struct iss_device *iss = to_iss_device(ipipeif); 664 struct iss_device *iss = to_iss_device(ipipeif);
665 unsigned int index = local->index;
665 666
666 switch (local->index | media_entity_type(remote->entity)) { 667 /* FIXME: this is actually a hack! */
667 case IPIPEIF_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 668 if (is_media_entity_v4l2_subdev(remote->entity))
669 index |= 2 << 16;
670
671 switch (index) {
672 case IPIPEIF_PAD_SINK | 2 << 16:
668 /* Read from the sensor CSI2a or CSI2b. */ 673 /* Read from the sensor CSI2a or CSI2b. */
669 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 674 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
670 ipipeif->input = IPIPEIF_INPUT_NONE; 675 ipipeif->input = IPIPEIF_INPUT_NONE;
@@ -681,7 +686,7 @@ static int ipipeif_link_setup(struct media_entity *entity,
681 686
682 break; 687 break;
683 688
684 case IPIPEIF_PAD_SOURCE_ISIF_SF | MEDIA_ENT_T_DEVNODE: 689 case IPIPEIF_PAD_SOURCE_ISIF_SF:
685 /* Write to memory */ 690 /* Write to memory */
686 if (flags & MEDIA_LNK_FL_ENABLED) { 691 if (flags & MEDIA_LNK_FL_ENABLED) {
687 if (ipipeif->output & ~IPIPEIF_OUTPUT_MEMORY) 692 if (ipipeif->output & ~IPIPEIF_OUTPUT_MEMORY)
@@ -692,7 +697,7 @@ static int ipipeif_link_setup(struct media_entity *entity,
692 } 697 }
693 break; 698 break;
694 699
695 case IPIPEIF_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV: 700 case IPIPEIF_PAD_SOURCE_VP | 2 << 16:
696 /* Send to IPIPE/RESIZER */ 701 /* Send to IPIPE/RESIZER */
697 if (flags & MEDIA_LNK_FL_ENABLED) { 702 if (flags & MEDIA_LNK_FL_ENABLED) {
698 if (ipipeif->output & ~IPIPEIF_OUTPUT_VP) 703 if (ipipeif->output & ~IPIPEIF_OUTPUT_VP)
@@ -743,7 +748,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
743 pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE; 748 pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
744 749
745 me->ops = &ipipeif_media_ops; 750 me->ops = &ipipeif_media_ops;
746 ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads, 0); 751 ret = media_entity_pads_init(me, IPIPEIF_PADS_NUM, pads);
747 if (ret < 0) 752 if (ret < 0)
748 return ret; 753 return ret;
749 754
@@ -757,18 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
757 ipipeif->video_out.bpl_zero_padding = 1; 762 ipipeif->video_out.bpl_zero_padding = 1;
758 ipipeif->video_out.bpl_max = 0x1ffe0; 763 ipipeif->video_out.bpl_max = 0x1ffe0;
759 764
760 ret = omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF"); 765 return omap4iss_video_init(&ipipeif->video_out, "ISP IPIPEIF");
761 if (ret < 0)
762 return ret;
763
764 /* Connect the IPIPEIF subdev to the video node. */
765 ret = media_entity_create_link(&ipipeif->subdev.entity,
766 IPIPEIF_PAD_SOURCE_ISIF_SF,
767 &ipipeif->video_out.video.entity, 0, 0);
768 if (ret < 0)
769 return ret;
770
771 return 0;
772} 766}
773 767
774void omap4iss_ipipeif_unregister_entities(struct iss_ipipeif_device *ipipeif) 768void omap4iss_ipipeif_unregister_entities(struct iss_ipipeif_device *ipipeif)
@@ -821,6 +815,22 @@ int omap4iss_ipipeif_init(struct iss_device *iss)
821} 815}
822 816
823/* 817/*
818 * omap4iss_ipipeif_create_links() - IPIPEIF pads links creation
819 * @iss: Pointer to ISS device
820 *
821 * return negative error code or zero on success
822 */
823int omap4iss_ipipeif_create_links(struct iss_device *iss)
824{
825 struct iss_ipipeif_device *ipipeif = &iss->ipipeif;
826
827 /* Connect the IPIPEIF subdev to the video node. */
828 return media_create_pad_link(&ipipeif->subdev.entity,
829 IPIPEIF_PAD_SOURCE_ISIF_SF,
830 &ipipeif->video_out.video.entity, 0, 0);
831}
832
833/*
824 * omap4iss_ipipeif_cleanup - IPIPEIF module cleanup. 834 * omap4iss_ipipeif_cleanup - IPIPEIF module cleanup.
825 * @iss: Device pointer specific to the OMAP4 ISS. 835 * @iss: Device pointer specific to the OMAP4 ISS.
826 */ 836 */
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.h b/drivers/staging/media/omap4iss/iss_ipipeif.h
index c6bd96d9656c..bad32b1d6ad8 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 {
78struct iss_device; 78struct iss_device;
79 79
80int omap4iss_ipipeif_init(struct iss_device *iss); 80int omap4iss_ipipeif_init(struct iss_device *iss);
81int omap4iss_ipipeif_create_links(struct iss_device *iss);
81void omap4iss_ipipeif_cleanup(struct iss_device *iss); 82void omap4iss_ipipeif_cleanup(struct iss_device *iss);
82int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif, 83int omap4iss_ipipeif_register_entities(struct iss_ipipeif_device *ipipeif,
83 struct v4l2_device *vdev); 84 struct v4l2_device *vdev);
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 108961e05f53..f1d352c711d5 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -716,9 +716,14 @@ static int resizer_link_setup(struct media_entity *entity,
716 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); 716 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
717 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd); 717 struct iss_resizer_device *resizer = v4l2_get_subdevdata(sd);
718 struct iss_device *iss = to_iss_device(resizer); 718 struct iss_device *iss = to_iss_device(resizer);
719 unsigned int index = local->index;
719 720
720 switch (local->index | media_entity_type(remote->entity)) { 721 /* FIXME: this is actually a hack! */
721 case RESIZER_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV: 722 if (is_media_entity_v4l2_subdev(remote->entity))
723 index |= 2 << 16;
724
725 switch (index) {
726 case RESIZER_PAD_SINK | 2 << 16:
722 /* Read from IPIPE or IPIPEIF. */ 727 /* Read from IPIPE or IPIPEIF. */
723 if (!(flags & MEDIA_LNK_FL_ENABLED)) { 728 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
724 resizer->input = RESIZER_INPUT_NONE; 729 resizer->input = RESIZER_INPUT_NONE;
@@ -735,7 +740,7 @@ static int resizer_link_setup(struct media_entity *entity,
735 740
736 break; 741 break;
737 742
738 case RESIZER_PAD_SOURCE_MEM | MEDIA_ENT_T_DEVNODE: 743 case RESIZER_PAD_SOURCE_MEM:
739 /* Write to memory */ 744 /* Write to memory */
740 if (flags & MEDIA_LNK_FL_ENABLED) { 745 if (flags & MEDIA_LNK_FL_ENABLED) {
741 if (resizer->output & ~RESIZER_OUTPUT_MEMORY) 746 if (resizer->output & ~RESIZER_OUTPUT_MEMORY)
@@ -785,7 +790,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
785 pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE; 790 pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE;
786 791
787 me->ops = &resizer_media_ops; 792 me->ops = &resizer_media_ops;
788 ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0); 793 ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
789 if (ret < 0) 794 if (ret < 0)
790 return ret; 795 return ret;
791 796
@@ -799,18 +804,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
799 resizer->video_out.bpl_zero_padding = 1; 804 resizer->video_out.bpl_zero_padding = 1;
800 resizer->video_out.bpl_max = 0x1ffe0; 805 resizer->video_out.bpl_max = 0x1ffe0;
801 806
802 ret = omap4iss_video_init(&resizer->video_out, "ISP resizer a"); 807 return omap4iss_video_init(&resizer->video_out, "ISP resizer a");
803 if (ret < 0)
804 return ret;
805
806 /* Connect the RESIZER subdev to the video node. */
807 ret = media_entity_create_link(&resizer->subdev.entity,
808 RESIZER_PAD_SOURCE_MEM,
809 &resizer->video_out.video.entity, 0, 0);
810 if (ret < 0)
811 return ret;
812
813 return 0;
814} 808}
815 809
816void omap4iss_resizer_unregister_entities(struct iss_resizer_device *resizer) 810void omap4iss_resizer_unregister_entities(struct iss_resizer_device *resizer)
@@ -863,6 +857,22 @@ int omap4iss_resizer_init(struct iss_device *iss)
863} 857}
864 858
865/* 859/*
860 * omap4iss_resizer_create_links() - RESIZER pads links creation
861 * @iss: Pointer to ISS device
862 *
863 * return negative error code or zero on success
864 */
865int omap4iss_resizer_create_links(struct iss_device *iss)
866{
867 struct iss_resizer_device *resizer = &iss->resizer;
868
869 /* Connect the RESIZER subdev to the video node. */
870 return media_create_pad_link(&resizer->subdev.entity,
871 RESIZER_PAD_SOURCE_MEM,
872 &resizer->video_out.video.entity, 0, 0);
873}
874
875/*
866 * omap4iss_resizer_cleanup - RESIZER module cleanup. 876 * omap4iss_resizer_cleanup - RESIZER module cleanup.
867 * @iss: Device pointer specific to the OMAP4 ISS. 877 * @iss: Device pointer specific to the OMAP4 ISS.
868 */ 878 */
diff --git a/drivers/staging/media/omap4iss/iss_resizer.h b/drivers/staging/media/omap4iss/iss_resizer.h
index 1e145abafc65..8b7c5fe9ffed 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 {
61struct iss_device; 61struct iss_device;
62 62
63int omap4iss_resizer_init(struct iss_device *iss); 63int omap4iss_resizer_init(struct iss_device *iss);
64int omap4iss_resizer_create_links(struct iss_device *iss);
64void omap4iss_resizer_cleanup(struct iss_device *iss); 65void omap4iss_resizer_cleanup(struct iss_device *iss);
65int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer, 66int omap4iss_resizer_register_entities(struct iss_resizer_device *resizer,
66 struct v4l2_device *vdev); 67 struct v4l2_device *vdev);
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index e9aeca08986f..058233a9de67 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -190,8 +190,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad)
190 190
191 remote = media_entity_remote_pad(&video->pad); 191 remote = media_entity_remote_pad(&video->pad);
192 192
193 if (!remote || 193 if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
194 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
195 return NULL; 194 return NULL;
196 195
197 if (pad) 196 if (pad)
@@ -206,17 +205,23 @@ iss_video_far_end(struct iss_video *video)
206{ 205{
207 struct media_entity_graph graph; 206 struct media_entity_graph graph;
208 struct media_entity *entity = &video->video.entity; 207 struct media_entity *entity = &video->video.entity;
209 struct media_device *mdev = entity->parent; 208 struct media_device *mdev = entity->graph_obj.mdev;
210 struct iss_video *far_end = NULL; 209 struct iss_video *far_end = NULL;
211 210
212 mutex_lock(&mdev->graph_mutex); 211 mutex_lock(&mdev->graph_mutex);
212
213 if (media_entity_graph_walk_init(&graph, mdev)) {
214 mutex_unlock(&mdev->graph_mutex);
215 return NULL;
216 }
217
213 media_entity_graph_walk_start(&graph, entity); 218 media_entity_graph_walk_start(&graph, entity);
214 219
215 while ((entity = media_entity_graph_walk_next(&graph))) { 220 while ((entity = media_entity_graph_walk_next(&graph))) {
216 if (entity == &video->video.entity) 221 if (entity == &video->video.entity)
217 continue; 222 continue;
218 223
219 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE) 224 if (!is_media_entity_v4l2_io(entity))
220 continue; 225 continue;
221 226
222 far_end = to_iss_video(media_entity_to_video_device(entity)); 227 far_end = to_iss_video(media_entity_to_video_device(entity));
@@ -227,6 +232,9 @@ iss_video_far_end(struct iss_video *video)
227 } 232 }
228 233
229 mutex_unlock(&mdev->graph_mutex); 234 mutex_unlock(&mdev->graph_mutex);
235
236 media_entity_graph_walk_cleanup(&graph);
237
230 return far_end; 238 return far_end;
231} 239}
232 240
@@ -750,7 +758,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
750 struct iss_video_fh *vfh = to_iss_video_fh(fh); 758 struct iss_video_fh *vfh = to_iss_video_fh(fh);
751 struct iss_video *video = video_drvdata(file); 759 struct iss_video *video = video_drvdata(file);
752 struct media_entity_graph graph; 760 struct media_entity_graph graph;
753 struct media_entity *entity; 761 struct media_entity *entity = &video->video.entity;
754 enum iss_pipeline_state state; 762 enum iss_pipeline_state state;
755 struct iss_pipeline *pipe; 763 struct iss_pipeline *pipe;
756 struct iss_video *far_end; 764 struct iss_video *far_end;
@@ -765,24 +773,30 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
765 /* Start streaming on the pipeline. No link touching an entity in the 773 /* Start streaming on the pipeline. No link touching an entity in the
766 * pipeline can be activated or deactivated once streaming is started. 774 * pipeline can be activated or deactivated once streaming is started.
767 */ 775 */
768 pipe = video->video.entity.pipe 776 pipe = entity->pipe
769 ? to_iss_pipeline(&video->video.entity) : &video->pipe; 777 ? to_iss_pipeline(entity) : &video->pipe;
770 pipe->external = NULL; 778 pipe->external = NULL;
771 pipe->external_rate = 0; 779 pipe->external_rate = 0;
772 pipe->external_bpp = 0; 780 pipe->external_bpp = 0;
773 pipe->entities = 0; 781
782 ret = media_entity_enum_init(&pipe->ent_enum, entity->graph_obj.mdev);
783 if (ret)
784 goto err_graph_walk_init;
785
786 ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
787 if (ret)
788 goto err_graph_walk_init;
774 789
775 if (video->iss->pdata->set_constraints) 790 if (video->iss->pdata->set_constraints)
776 video->iss->pdata->set_constraints(video->iss, true); 791 video->iss->pdata->set_constraints(video->iss, true);
777 792
778 ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe); 793 ret = media_entity_pipeline_start(entity, &pipe->pipe);
779 if (ret < 0) 794 if (ret < 0)
780 goto err_media_entity_pipeline_start; 795 goto err_media_entity_pipeline_start;
781 796
782 entity = &video->video.entity;
783 media_entity_graph_walk_start(&graph, entity); 797 media_entity_graph_walk_start(&graph, entity);
784 while ((entity = media_entity_graph_walk_next(&graph))) 798 while ((entity = media_entity_graph_walk_next(&graph)))
785 pipe->entities |= 1 << entity->id; 799 media_entity_enum_set(&pipe->ent_enum, entity);
786 800
787 /* Verify that the currently configured format matches the output of 801 /* Verify that the currently configured format matches the output of
788 * the connected subdev. 802 * the connected subdev.
@@ -852,7 +866,10 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
852 spin_unlock_irqrestore(&video->qlock, flags); 866 spin_unlock_irqrestore(&video->qlock, flags);
853 } 867 }
854 868
869 media_entity_graph_walk_cleanup(&graph);
870
855 mutex_unlock(&video->stream_lock); 871 mutex_unlock(&video->stream_lock);
872
856 return 0; 873 return 0;
857 874
858err_omap4iss_set_stream: 875err_omap4iss_set_stream:
@@ -864,7 +881,13 @@ err_media_entity_pipeline_start:
864 video->iss->pdata->set_constraints(video->iss, false); 881 video->iss->pdata->set_constraints(video->iss, false);
865 video->queue = NULL; 882 video->queue = NULL;
866 883
884 media_entity_graph_walk_cleanup(&graph);
885
886err_graph_walk_init:
887 media_entity_enum_cleanup(&pipe->ent_enum);
888
867 mutex_unlock(&video->stream_lock); 889 mutex_unlock(&video->stream_lock);
890
868 return ret; 891 return ret;
869} 892}
870 893
@@ -902,6 +925,8 @@ iss_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
902 vb2_streamoff(&vfh->queue, type); 925 vb2_streamoff(&vfh->queue, type);
903 video->queue = NULL; 926 video->queue = NULL;
904 927
928 media_entity_enum_cleanup(&pipe->ent_enum);
929
905 if (video->iss->pdata->set_constraints) 930 if (video->iss->pdata->set_constraints)
906 video->iss->pdata->set_constraints(video->iss, false); 931 video->iss->pdata->set_constraints(video->iss, false);
907 media_entity_pipeline_stop(&video->video.entity); 932 media_entity_pipeline_stop(&video->video.entity);
@@ -984,7 +1009,13 @@ static int iss_video_open(struct file *file)
984 goto done; 1009 goto done;
985 } 1010 }
986 1011
987 ret = omap4iss_pipeline_pm_use(&video->video.entity, 1); 1012 ret = media_entity_graph_walk_init(&handle->graph,
1013 &video->iss->media_dev);
1014 if (ret)
1015 goto done;
1016
1017 ret = omap4iss_pipeline_pm_use(&video->video.entity, 1,
1018 &handle->graph);
988 if (ret < 0) { 1019 if (ret < 0) {
989 omap4iss_put(video->iss); 1020 omap4iss_put(video->iss);
990 goto done; 1021 goto done;
@@ -1023,6 +1054,7 @@ static int iss_video_open(struct file *file)
1023done: 1054done:
1024 if (ret < 0) { 1055 if (ret < 0) {
1025 v4l2_fh_del(&handle->vfh); 1056 v4l2_fh_del(&handle->vfh);
1057 media_entity_graph_walk_cleanup(&handle->graph);
1026 kfree(handle); 1058 kfree(handle);
1027 } 1059 }
1028 1060
@@ -1038,12 +1070,13 @@ static int iss_video_release(struct file *file)
1038 /* Disable streaming and free the buffers queue resources. */ 1070 /* Disable streaming and free the buffers queue resources. */
1039 iss_video_streamoff(file, vfh, video->type); 1071 iss_video_streamoff(file, vfh, video->type);
1040 1072
1041 omap4iss_pipeline_pm_use(&video->video.entity, 0); 1073 omap4iss_pipeline_pm_use(&video->video.entity, 0, &handle->graph);
1042 1074
1043 /* Release the videobuf2 queue */ 1075 /* Release the videobuf2 queue */
1044 vb2_queue_release(&handle->queue); 1076 vb2_queue_release(&handle->queue);
1045 1077
1046 /* Release the file handle. */ 1078 /* Release the file handle. */
1079 media_entity_graph_walk_cleanup(&handle->graph);
1047 v4l2_fh_del(vfh); 1080 v4l2_fh_del(vfh);
1048 kfree(handle); 1081 kfree(handle);
1049 file->private_data = NULL; 1082 file->private_data = NULL;
@@ -1102,7 +1135,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name)
1102 return -EINVAL; 1135 return -EINVAL;
1103 } 1136 }
1104 1137
1105 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); 1138 ret = media_entity_pads_init(&video->video.entity, 1, &video->pad);
1106 if (ret < 0) 1139 if (ret < 0)
1107 return ret; 1140 return ret;
1108 1141
diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h
index 41532eda1277..34588b7176ca 100644
--- a/drivers/staging/media/omap4iss/iss_video.h
+++ b/drivers/staging/media/omap4iss/iss_video.h
@@ -77,7 +77,7 @@ enum iss_pipeline_state {
77 77
78/* 78/*
79 * struct iss_pipeline - An OMAP4 ISS hardware pipeline 79 * struct iss_pipeline - An OMAP4 ISS hardware pipeline
80 * @entities: Bitmask of entities in the pipeline (indexed by entity ID) 80 * @ent_enum: Entities in the pipeline
81 * @error: A hardware error occurred during capture 81 * @error: A hardware error occurred during capture
82 */ 82 */
83struct iss_pipeline { 83struct iss_pipeline {
@@ -87,7 +87,7 @@ struct iss_pipeline {
87 enum iss_pipeline_stream_state stream_state; 87 enum iss_pipeline_stream_state stream_state;
88 struct iss_video *input; 88 struct iss_video *input;
89 struct iss_video *output; 89 struct iss_video *output;
90 unsigned int entities; 90 struct media_entity_enum ent_enum;
91 atomic_t frame_number; 91 atomic_t frame_number;
92 bool do_propagation; /* of frame number */ 92 bool do_propagation; /* of frame number */
93 bool error; 93 bool error;
@@ -183,6 +183,7 @@ struct iss_video_fh {
183 struct vb2_queue queue; 183 struct vb2_queue queue;
184 struct v4l2_format format; 184 struct v4l2_format format;
185 struct v4l2_fract timeperframe; 185 struct v4l2_fract timeperframe;
186 struct media_entity_graph graph;
186}; 187};
187 188
188#define to_iss_video_fh(fh) container_of(fh, struct iss_video_fh, vfh) 189#define to_iss_video_fh(fh) container_of(fh, struct iss_video_fh, vfh)