summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c24
-rw-r--r--drivers/media/usb/au0828/au0828-core.c21
-rw-r--r--drivers/media/v4l2-core/v4l2-mc.c26
3 files changed, 45 insertions, 26 deletions
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 13dca47ea91e..85ae3669aa66 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -2533,9 +2533,13 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
fepriv->voltage = -1;
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
- if (fe->dvb->mdev && fe->dvb->mdev->enable_source) {
- ret = fe->dvb->mdev->enable_source(dvbdev->entity,
+ if (fe->dvb->mdev) {
+ mutex_lock(&fe->dvb->mdev->graph_mutex);
+ if (fe->dvb->mdev->enable_source)
+ ret = fe->dvb->mdev->enable_source(
+ dvbdev->entity,
&fepriv->pipe);
+ mutex_unlock(&fe->dvb->mdev->graph_mutex);
if (ret) {
dev_err(fe->dvb->device,
"Tuner is busy. Error %d\n", ret);
@@ -2559,8 +2563,12 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
err3:
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
- if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
- fe->dvb->mdev->disable_source(dvbdev->entity);
+ if (fe->dvb->mdev) {
+ mutex_lock(&fe->dvb->mdev->graph_mutex);
+ if (fe->dvb->mdev->disable_source)
+ fe->dvb->mdev->disable_source(dvbdev->entity);
+ mutex_unlock(&fe->dvb->mdev->graph_mutex);
+ }
err2:
#endif
dvb_generic_release(inode, file);
@@ -2592,8 +2600,12 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if (dvbdev->users == -1) {
wake_up(&fepriv->wait_queue);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
- if (fe->dvb->mdev && fe->dvb->mdev->disable_source)
- fe->dvb->mdev->disable_source(dvbdev->entity);
+ if (fe->dvb->mdev) {
+ mutex_lock(&fe->dvb->mdev->graph_mutex);
+ if (fe->dvb->mdev->disable_source)
+ fe->dvb->mdev->disable_source(dvbdev->entity);
+ mutex_unlock(&fe->dvb->mdev->graph_mutex);
+ }
#endif
if (fe->exit != DVB_FE_NO_EXIT)
wake_up(&dvbdev->wait_queue);
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 8c0494042d06..739df61cec4f 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -149,9 +149,11 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
}
/* clear enable_source, disable_source */
+ mutex_lock(&mdev->graph_mutex);
dev->media_dev->source_priv = NULL;
dev->media_dev->enable_source = NULL;
dev->media_dev->disable_source = NULL;
+ mutex_unlock(&mdev->graph_mutex);
media_device_unregister(dev->media_dev);
media_device_cleanup(dev->media_dev);
@@ -274,6 +276,7 @@ create_link:
}
}
+/* Callers should hold graph_mutex */
static int au0828_enable_source(struct media_entity *entity,
struct media_pipeline *pipe)
{
@@ -287,8 +290,6 @@ static int au0828_enable_source(struct media_entity *entity,
if (!mdev)
return -ENODEV;
- mutex_lock(&mdev->graph_mutex);
-
dev = mdev->source_priv;
/*
@@ -415,12 +416,12 @@ static int au0828_enable_source(struct media_entity *entity,
dev->active_source->name, dev->active_sink->name,
dev->active_link_owner->name, ret);
end:
- mutex_unlock(&mdev->graph_mutex);
pr_debug("au0828_enable_source() end %s %d %d\n",
entity->name, entity->function, ret);
return ret;
}
+/* Callers should hold graph_mutex */
static void au0828_disable_source(struct media_entity *entity)
{
int ret = 0;
@@ -430,13 +431,10 @@ static void au0828_disable_source(struct media_entity *entity)
if (!mdev)
return;
- mutex_lock(&mdev->graph_mutex);
dev = mdev->source_priv;
- if (!dev->active_link) {
- ret = -ENODEV;
- goto end;
- }
+ if (!dev->active_link)
+ return;
/* link is active - stop pipeline from source (tuner) */
if (dev->active_link->sink->entity == dev->active_sink &&
@@ -446,7 +444,7 @@ static void au0828_disable_source(struct media_entity *entity)
* has active pipeline
*/
if (dev->active_link_owner != entity)
- goto end;
+ return;
__media_pipeline_stop(entity);
ret = __media_entity_setup_link(dev->active_link, 0);
if (ret)
@@ -461,9 +459,6 @@ static void au0828_disable_source(struct media_entity *entity)
dev->active_source = NULL;
dev->active_sink = NULL;
}
-
-end:
- mutex_unlock(&mdev->graph_mutex);
}
#endif
@@ -545,9 +540,11 @@ static int au0828_media_device_register(struct au0828_dev *dev,
return ret;
}
/* set enable_source */
+ mutex_lock(&dev->media_dev->graph_mutex);
dev->media_dev->source_priv = (void *) dev;
dev->media_dev->enable_source = au0828_enable_source;
dev->media_dev->disable_source = au0828_disable_source;
+ mutex_unlock(&dev->media_dev->graph_mutex);
#endif
return 0;
}
diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c
index fcf614a82bb8..303980b71aae 100644
--- a/drivers/media/v4l2-core/v4l2-mc.c
+++ b/drivers/media/v4l2-core/v4l2-mc.c
@@ -198,14 +198,20 @@ EXPORT_SYMBOL_GPL(v4l2_mc_create_media_graph);
int v4l_enable_media_source(struct video_device *vdev)
{
struct media_device *mdev = vdev->entity.graph_obj.mdev;
- int ret;
+ int ret = 0, err;
- if (!mdev || !mdev->enable_source)
+ if (!mdev)
return 0;
- ret = mdev->enable_source(&vdev->entity, &vdev->pipe);
- if (ret)
- return -EBUSY;
- return 0;
+
+ mutex_lock(&mdev->graph_mutex);
+ if (!mdev->enable_source)
+ goto end;
+ err = mdev->enable_source(&vdev->entity, &vdev->pipe);
+ if (err)
+ ret = -EBUSY;
+end:
+ mutex_unlock(&mdev->graph_mutex);
+ return ret;
}
EXPORT_SYMBOL_GPL(v4l_enable_media_source);
@@ -213,8 +219,12 @@ void v4l_disable_media_source(struct video_device *vdev)
{
struct media_device *mdev = vdev->entity.graph_obj.mdev;
- if (mdev && mdev->disable_source)
- mdev->disable_source(&vdev->entity);
+ if (mdev) {
+ mutex_lock(&mdev->graph_mutex);
+ if (mdev->disable_source)
+ mdev->disable_source(&vdev->entity);
+ mutex_unlock(&mdev->graph_mutex);
+ }
}
EXPORT_SYMBOL_GPL(v4l_disable_media_source);