summaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-09-04 16:08:02 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-01-11 12:19:00 -0200
commit4e26f3abafa9d0f635e105c8b9021f3b5bae6702 (patch)
treef6ceebd633e06f2673c4a7bdabcde561950ec550 /drivers/media
parentab232e46bf01db5c540a00f478853a3572b0b88b (diff)
[media] au0828: 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')
-rw-r--r--drivers/media/usb/au0828/au0828-core.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0d77e9cc303b..27679e5cdca1 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -172,9 +172,9 @@ static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev)
struct au0828_dev *dev =
container_of(v4l2_dev, struct au0828_dev, v4l2_dev);
- au0828_usb_v4l2_media_release(dev);
v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl);
v4l2_device_unregister(&dev->v4l2_dev);
+ au0828_usb_v4l2_media_release(dev);
au0828_usb_release(dev);
}
#endif
@@ -253,16 +253,16 @@ static void au0828_media_device_register(struct au0828_dev *dev,
}
-static void au0828_create_media_graph(struct au0828_dev *dev)
+static int au0828_create_media_graph(struct au0828_dev *dev)
{
#ifdef CONFIG_MEDIA_CONTROLLER
struct media_device *mdev = dev->media_dev;
struct media_entity *entity;
struct media_entity *tuner = NULL, *decoder = NULL;
- int i;
+ int i, ret;
if (!mdev)
- return;
+ return 0;
media_device_for_each_entity(entity, mdev) {
switch (entity->type) {
@@ -279,15 +279,23 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
/* Something bad happened! */
if (!decoder)
- return;
-
- if (tuner)
- media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT, decoder, 0,
- MEDIA_LNK_FL_ENABLED);
- media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
- MEDIA_LNK_FL_ENABLED);
- media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
- MEDIA_LNK_FL_ENABLED);
+ return -EINVAL;
+
+ if (tuner) {
+ ret = media_create_pad_link(tuner, TUNER_PAD_IF_OUTPUT,
+ decoder, 0,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
+ }
+ ret = media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
+ ret = media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
for (i = 0; i < AU0828_MAX_INPUT; i++) {
struct media_entity *ent = &dev->input_ent[i];
@@ -299,20 +307,27 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
case AU0828_VMUX_CABLE:
case AU0828_VMUX_TELEVISION:
case AU0828_VMUX_DVB:
- if (tuner)
- media_create_pad_link(ent, 0, tuner,
- TUNER_PAD_RF_INPUT,
- MEDIA_LNK_FL_ENABLED);
+ if (!tuner)
+ break;
+
+ ret = media_create_pad_link(ent, 0, tuner,
+ TUNER_PAD_RF_INPUT,
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ return ret;
break;
case AU0828_VMUX_COMPOSITE:
case AU0828_VMUX_SVIDEO:
default: /* AU0828_VMUX_DEBUG */
/* FIXME: fix the decoder PAD */
- media_create_pad_link(ent, 0, decoder, 0, 0);
+ ret = media_create_pad_link(ent, 0, decoder, 0, 0);
+ if (ret)
+ return ret;
break;
}
}
#endif
+ return 0;
}
static int au0828_usb_probe(struct usb_interface *interface,
@@ -427,7 +442,12 @@ static int au0828_usb_probe(struct usb_interface *interface,
mutex_unlock(&dev->lock);
- au0828_create_media_graph(dev);
+ retval = au0828_create_media_graph(dev);
+ if (retval) {
+ pr_err("%s() au0282_dev_register failed to create graph\n",
+ __func__);
+ au0828_usb_disconnect(interface);
+ }
return retval;
}