diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 2424aef..505eed1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -88,8 +88,6 @@ struct detailed_mode_closure {
 #define LEVEL_GTF2	2
 #define LEVEL_CVT	3
 
-static DEFINE_MUTEX(drm_edid_mutex);
-
 static struct edid_quirk {
 	char vendor[4];
 	int product_id;
@@ -1380,16 +1378,8 @@ struct edid *drm_get_edid(struct drm_connector *connector,
 			  struct i2c_adapter *adapter)
 {
 	struct edid *edid;
-	struct pci_dev *pdev = connector->dev->pdev;
-	struct pci_dev *active_pdev = NULL;
-
-	mutex_lock(&drm_edid_mutex);
 
-	if (pdev) {
-		active_pdev = vga_switcheroo_get_active_client();
-		if (active_pdev != pdev)
-			vga_switcheroo_switch_ddc(pdev);
-	}
+	vga_switcheroo_lock_ddc(connector->dev->pdev);
 
 	if (!drm_probe_ddc(adapter))
 		return NULL;
@@ -1398,10 +1388,8 @@ struct edid *drm_get_edid(struct drm_connector *connector,
 	if (edid)
 		drm_get_displayid(connector, edid);
 
-	if (active_pdev && active_pdev != pdev)
-		vga_switcheroo_switch_ddc(active_pdev);
+	vga_switcheroo_unlock_ddc(connector->dev->pdev);
 
-	mutex_unlock(&drm_edid_mutex);
 	return edid;
 }
 EXPORT_SYMBOL(drm_get_edid);
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 620c4ac..0223020 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -57,6 +57,9 @@ struct vgasr_priv {
 	struct list_head clients;
 
 	struct vga_switcheroo_handler *handler;
+
+	struct mutex ddc_lock;
+	struct pci_dev *old_ddc_owner;
 };
 
 #define ID_BIT_AUDIO		0x100
@@ -70,6 +73,7 @@ static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
 /* only one switcheroo per system */
 static struct vgasr_priv vgasr_priv = {
 	.clients = LIST_HEAD_INIT(vgasr_priv.clients),
+	.ddc_lock = __MUTEX_INITIALIZER(vgasr_priv.ddc_lock),
 };
 
 static bool vga_switcheroo_ready(void)
@@ -270,8 +274,9 @@ void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
 }
 EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
 
-int vga_switcheroo_switch_ddc(struct pci_dev *pdev)
+int vga_switcheroo_lock_ddc(struct pci_dev *pdev)
 {
+	struct vga_switcheroo_client *client;
 	int ret = 0;
 	int id;
 
@@ -283,6 +288,18 @@ int vga_switcheroo_switch_ddc(struct pci_dev *pdev)
 	}
 
 	if (vgasr_priv.handler->switch_ddc) {
+		mutex_lock(&vgasr_priv.ddc_lock);
+
+		client = find_active_client(&vgasr_priv.clients);
+		if (!client) {
+			mutex_unlock(&vgasr_priv.ddc_lock);
+			ret = -ENODEV;
+			goto out;
+		}
+		vgasr_priv.old_ddc_owner = client->pdev;
+		if (client->pdev == pdev)
+			goto out;
+
 		id = vgasr_priv.handler->get_client_id(pdev);
 		ret = vgasr_priv.handler->switch_ddc(id);
 	}
@@ -291,7 +308,32 @@ out:
 	mutex_unlock(&vgasr_mutex);
 	return ret;
 }
-EXPORT_SYMBOL(vga_switcheroo_switch_ddc);
+EXPORT_SYMBOL(vga_switcheroo_lock_ddc);
+
+int vga_switcheroo_unlock_ddc(struct pci_dev *pdev)
+{
+	int ret = 0;
+	int id;
+	mutex_lock(&vgasr_mutex);
+
+	if (!vgasr_priv.handler) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (vgasr_priv.handler->switch_ddc) {
+		if (vgasr_priv.old_ddc_owner != pdev) {
+			id = vgasr_priv.handler->get_client_id(vgasr_priv.old_ddc_owner);
+			ret = vgasr_priv.handler->switch_ddc(id);
+		}
+		vgasr_priv.old_ddc_owner = NULL;
+		mutex_unlock(&vgasr_priv.ddc_lock);
+	}
+out:
+	mutex_unlock(&vgasr_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);
 
 static int vga_switcheroo_show(struct seq_file *m, void *v)
 {
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index c81a686..352bef3 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -55,7 +55,8 @@ int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 void vga_switcheroo_client_fb_set(struct pci_dev *dev,
 				  struct fb_info *info);
 
-int vga_switcheroo_switch_ddc(struct pci_dev *pdev);
+int vga_switcheroo_lock_ddc(struct pci_dev *pdev);
+int vga_switcheroo_unlock_ddc(struct pci_dev *pdev);
 
 int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler);
 void vga_switcheroo_unregister_handler(void);
