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);
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);
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);
}
/* 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);
}
}
+/* Callers should hold graph_mutex */
static int au0828_enable_source(struct media_entity *entity,
struct media_pipeline *pipe)
{
if (!mdev)
return -ENODEV;
- mutex_lock(&mdev->graph_mutex);
-
dev = mdev->source_priv;
/*
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;
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 &&
* 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)
dev->active_source = NULL;
dev->active_sink = NULL;
}
-
-end:
- mutex_unlock(&mdev->graph_mutex);
}
#endif
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;
}
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);
{
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);
* bridge driver finds the media_device during probe.
* Bridge driver sets source_priv with information
* necessary to run @enable_source and @disable_source handlers.
+ * Callers should hold graph_mutex to access and call @enable_source
+ * and @disable_source handlers.
*/
struct media_device {
/* dev->driver_data points to this struct. */