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. */