summaryrefslogtreecommitdiffstats
path: root/drivers/media/usb
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-09-04 21:07:03 +0200
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-01-11 15:18:59 +0100
commitab232e46bf01db5c540a00f478853a3572b0b88b (patch)
tree78b0d8e9e70cd8812a21de802b42dc206c76292e /drivers/media/usb
parent[media] media-entity: enforce check of interface and links creation (diff)
downloadlinux-ab232e46bf01db5c540a00f478853a3572b0b88b.tar.xz
linux-ab232e46bf01db5c540a00f478853a3572b0b88b.zip
[media] cx231xx: enforce check for graph creation
If the graph creation fails, don't register the device. Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 29cf0c268b19..b842bfc799cc 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1185,8 +1185,6 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev)
*/
void cx231xx_release_resources(struct cx231xx *dev)
{
- cx231xx_unregister_media_device(dev);
-
cx231xx_release_analog_resources(dev);
cx231xx_remove_from_devlist(dev);
@@ -1199,6 +1197,8 @@ void cx231xx_release_resources(struct cx231xx *dev)
/* delete v4l2 device */
v4l2_device_unregister(&dev->v4l2_dev);
+ cx231xx_unregister_media_device(dev);
+
usb_put_dev(dev->udev);
/* Mark device as unused */
@@ -1237,15 +1237,16 @@ static void cx231xx_media_device_register(struct cx231xx *dev,
#endif
}
-static void cx231xx_create_media_graph(struct cx231xx *dev)
+static int cx231xx_create_media_graph(struct cx231xx *dev)
{
#ifdef CONFIG_MEDIA_CONTROLLER
struct media_device *mdev = dev->media_dev;
struct media_entity *entity;
struct media_entity *tuner = NULL, *decoder = NULL;
+ int ret;
if (!mdev)
- return;
+ return 0;
media_device_for_each_entity(entity, mdev) {
switch (entity->type) {
@@ -1261,16 +1262,24 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
/* Analog setup, using tuner as a link */
if (!decoder)
- return;
+ return 0;
- if (tuner)
- media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
- MEDIA_LNK_FL_ENABLED);
- media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
- MEDIA_LNK_FL_ENABLED);
- media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
- MEDIA_LNK_FL_ENABLED);
+ if (tuner) {
+ ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret < 0)
+ return ret;
+ }
+ ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret < 0)
+ return ret;
+ ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret < 0)
+ return ret;
#endif
+ return 0;
}
/*
@@ -1732,9 +1741,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
/* load other modules required */
request_modules(dev);
- cx231xx_create_media_graph(dev);
+ retval = cx231xx_create_media_graph(dev);
+ if (retval < 0) {
+ cx231xx_release_resources(dev);
+ }
- return 0;
+ return retval;
err_video_alt:
/* cx231xx_uninit_dev: */
cx231xx_close_extension(dev);