linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] Fixes for hybrid graphics Apple machines
@ 2012-09-07 15:22 Seth Forshee
  2012-09-07 15:22 ` [PATCH 1/7] vga_switcheroo: Add support for switching only the DDC Seth Forshee
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

Many hybrid graphics Apple laptops fail to set up LVDS on the secondary
GPU due to missing or incorrect mode information for the panel at init
time. The only way to get the LVDS mode on these machines is via the
DDC, but this is muxed to the active GPU at boot. However, the graphics
mux on these machines supports muxing the i2c idependently of the
display, making it possible for the secondary graphics driver to read
the EDID without a full display switch.

In order to support this, these patches modify vga_switcheroo to allow
muxing of the DDC idependently of the display. apple-gmux is updated to
support this new functionality, and drm_get_edid() is modified to switch
the DDC mux as needed.

For this to work we also need to ensure that sufficient switcheroo
suport is available before initializing the secondary GPU. This is done
by adding any non-active GPUs that try to initialize before switcheroo
is ready to a list and initializing these devices once switcheroo
becomes ready. This behavior is restricted to Apple laptops to prevent
causing problems on other machines.

Thanks,
Seth

Seth Forshee (7):
  vga_switcheroo: Add support for switching only the DDC
  vga_switcheroo: Add helper function to get the active client
  vga_switcheroo: Add notifier call chain for switcheroo events
  apple-gmux: Add switch_ddc support
  drm/edid: Switch DDC when reading the EDID
  drm/pci: Add drm_put_pci_dev()
  drm/pci: Defer initialization of secondary graphics devices until
    switcheroo is ready

 drivers/gpu/drm/ast/ast_drv.c         |    2 +-
 drivers/gpu/drm/cirrus/cirrus_drv.c   |    2 +-
 drivers/gpu/drm/drm_drv.c             |    3 +
 drivers/gpu/drm/drm_edid.c            |   17 ++++
 drivers/gpu/drm/drm_pci.c             |  172 +++++++++++++++++++++++++++++----
 drivers/gpu/drm/gma500/psb_drv.c      |    2 +-
 drivers/gpu/drm/i915/i915_drv.c       |    2 +-
 drivers/gpu/drm/mgag200/mgag200_drv.c |    2 +-
 drivers/gpu/drm/nouveau/nouveau_drv.c |    2 +-
 drivers/gpu/drm/radeon/radeon_drv.c   |    2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |    2 +-
 drivers/gpu/vga/vga_switcheroo.c      |   87 ++++++++++++++++-
 drivers/platform/x86/apple-gmux.c     |   12 ++-
 include/drm/drmP.h                    |    3 +
 include/linux/vga_switcheroo.h        |   20 ++++
 15 files changed, 302 insertions(+), 28 deletions(-)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/7] vga_switcheroo: Add support for switching only the DDC
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
@ 2012-09-07 15:22 ` Seth Forshee
  2012-09-07 15:22 ` [PATCH 2/7] vga_switcheroo: Add helper function to get the active client Seth Forshee
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

During graphics driver initialization its useful to be able to mux only
the DDC to the inactive client in order to read the EDID. Add a
switch_ddc callback to allow capable handlers to provide this
functionality, and add vga_switcheroo_switch_ddc() to allow DRM to mux
only the DDC.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 drivers/gpu/vga/vga_switcheroo.c |   39 +++++++++++++++++++++++++++++++++++++-
 include/linux/vga_switcheroo.h   |    4 ++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index e25cf31..ea6bcc2 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -252,6 +252,29 @@ 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 ret = 0;
+	int id;
+
+	mutex_lock(&vgasr_mutex);
+
+	if (!vgasr_priv.handler) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (vgasr_priv.handler->switch_ddc) {
+		id = vgasr_priv.handler->get_client_id(pdev);
+		ret = vgasr_priv.handler->switch_ddc(id);
+	}
+
+out:
+	mutex_unlock(&vgasr_mutex);
+	return ret;
+}
+EXPORT_SYMBOL(vga_switcheroo_switch_ddc);
+
 static int vga_switcheroo_show(struct seq_file *m, void *v)
 {
 	struct vga_switcheroo_client *client;
@@ -342,9 +365,15 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
 		fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
 	}
 
+	if (vgasr_priv.handler->switch_ddc) {
+		ret = vgasr_priv.handler->switch_ddc(new_client->id);
+		if (ret)
+			return ret;
+	}
+
 	ret = vgasr_priv.handler->switchto(new_client->id);
 	if (ret)
-		return ret;
+		goto restore_ddc;
 
 	if (new_client->ops->reprobe)
 		new_client->ops->reprobe(new_client->pdev);
@@ -356,6 +385,14 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
 
 	new_client->active = true;
 	return 0;
+
+restore_ddc:
+	if (vgasr_priv.handler->switch_ddc) {
+		int id = (new_client->id == VGA_SWITCHEROO_IGD) ?
+				VGA_SWITCHEROO_DIS : VGA_SWITCHEROO_IGD;
+		ret = vgasr_priv.handler->switch_ddc(id);
+	}
+	return ret;
 }
 
 static bool check_can_switch(void)
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index ddb419c..b0d0839 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -29,6 +29,7 @@ enum vga_switcheroo_client_id {
 };
 
 struct vga_switcheroo_handler {
+	int (*switch_ddc)(enum vga_switcheroo_client_id id);
 	int (*switchto)(enum vga_switcheroo_client_id id);
 	int (*power_state)(enum vga_switcheroo_client_id id,
 			   enum vga_switcheroo_state state);
@@ -53,6 +54,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_register_handler(struct vga_switcheroo_handler *handler);
 void vga_switcheroo_unregister_handler(void);
 
@@ -66,6 +69,7 @@ static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
 static inline int vga_switcheroo_register_client(struct pci_dev *dev,
 		const struct vga_switcheroo_client_ops *ops) { return 0; }
 static inline void vga_switcheroo_client_fb_set(struct pci_dev *dev, struct fb_info *info) {}
+static inline void vga_switcheroo_switch_ddc(struct pci_dev *pdev) { return NULL; }
 static inline int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) { return 0; }
 static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 	const struct vga_switcheroo_client_ops *ops,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/7] vga_switcheroo: Add helper function to get the active client
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
  2012-09-07 15:22 ` [PATCH 1/7] vga_switcheroo: Add support for switching only the DDC Seth Forshee
@ 2012-09-07 15:22 ` Seth Forshee
  2012-09-07 15:22 ` [PATCH 3/7] vga_switcheroo: Add notifier call chain for switcheroo events Seth Forshee
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

Add vga_switcheroo_get_active_client() to allow drivers to get the
active video client. This will be used by drivers wishing to temporarily
mux only the DDC to the inactive client.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 drivers/gpu/vga/vga_switcheroo.c |   14 ++++++++++++++
 include/linux/vga_switcheroo.h   |    2 ++
 2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index ea6bcc2..e53f67d 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -205,6 +205,20 @@ find_active_client(struct list_head *head)
 	return NULL;
 }
 
+struct pci_dev *vga_switcheroo_get_active_client(void)
+{
+	struct vga_switcheroo_client *client;
+	struct pci_dev *pdev = NULL;
+
+	mutex_lock(&vgasr_mutex);
+	client = find_active_client(&vgasr_priv.clients);
+	if (client)
+		pdev = client->pdev;
+	mutex_unlock(&vgasr_mutex);
+	return pdev;
+}
+EXPORT_SYMBOL(vga_switcheroo_get_active_client);
+
 int vga_switcheroo_get_client_state(struct pci_dev *pdev)
 {
 	struct vga_switcheroo_client *client;
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index b0d0839..e361858 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -61,6 +61,7 @@ void vga_switcheroo_unregister_handler(void);
 
 int vga_switcheroo_process_delayed_switch(void);
 
+struct pci_dev *vga_switcheroo_get_active_client(void);
 int vga_switcheroo_get_client_state(struct pci_dev *dev);
 
 #else
@@ -76,6 +77,7 @@ static inline int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
 	int id, bool active) { return 0; }
 static inline void vga_switcheroo_unregister_handler(void) {}
 static inline int vga_switcheroo_process_delayed_switch(void) { return 0; }
+static inline struct pci_dev *vga_switcheroo_get_active_client(void) { return NULL; }
 static inline int vga_switcheroo_get_client_state(struct pci_dev *dev) { return VGA_SWITCHEROO_ON; }
 
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/7] vga_switcheroo: Add notifier call chain for switcheroo events
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
  2012-09-07 15:22 ` [PATCH 1/7] vga_switcheroo: Add support for switching only the DDC Seth Forshee
  2012-09-07 15:22 ` [PATCH 2/7] vga_switcheroo: Add helper function to get the active client Seth Forshee
@ 2012-09-07 15:22 ` Seth Forshee
  2012-09-07 15:22 ` [PATCH 4/7] apple-gmux: Add switch_ddc support Seth Forshee
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

DRM needs to be notified of client and handler registration in order to
defer initialization of the secondary GPU until the EDID can be read
from the LVDS panel. To support this add a notifier call chain to
vga_switcheroo for subscribing to switcheroo events. Events are
generated for registration and unregistration of handlers and clients.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 drivers/gpu/vga/vga_switcheroo.c |   34 ++++++++++++++++++++++++++++++++++
 include/linux/vga_switcheroo.h   |   14 ++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index e53f67d..d5cd274 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -24,6 +24,7 @@
 #include <linux/fs.h>
 #include <linux/debugfs.h>
 #include <linux/fb.h>
+#include <linux/notifier.h>
 
 #include <linux/pci.h>
 #include <linux/vga_switcheroo.h>
@@ -70,6 +71,28 @@ static struct vgasr_priv vgasr_priv = {
 	.clients = LIST_HEAD_INIT(vgasr_priv.clients),
 };
 
+static BLOCKING_NOTIFIER_HEAD(vga_switcheroo_notifier_list);
+
+int vga_switcheroo_register_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&vga_switcheroo_notifier_list,
+						nb);
+}
+EXPORT_SYMBOL(vga_switcheroo_register_notifier);
+
+int vga_switcheroo_unregister_notifier(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&vga_switcheroo_notifier_list,
+						  nb);
+}
+EXPORT_SYMBOL(vga_switcheroo_unregister_notifier);
+
+static int vga_switcheroo_notifier_call_chain(enum vga_switcheroo_event event)
+{
+	return blocking_notifier_call_chain(&vga_switcheroo_notifier_list,
+					    event, NULL);
+}
+
 static bool vga_switcheroo_ready(void)
 {
 	/* we're ready if we get two clients + handler */
@@ -113,10 +136,18 @@ int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
 		vga_switcheroo_enable();
 	}
 	mutex_unlock(&vgasr_mutex);
+
+	vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_HANDLER_REGISTERED);
 	return 0;
 }
 EXPORT_SYMBOL(vga_switcheroo_register_handler);
 
+bool vga_switcheroo_handler_registered(void)
+{
+	return !!vgasr_priv.handler;
+}
+EXPORT_SYMBOL(vga_switcheroo_handler_registered);
+
 void vga_switcheroo_unregister_handler(void)
 {
 	mutex_lock(&vgasr_mutex);
@@ -127,6 +158,7 @@ void vga_switcheroo_unregister_handler(void)
 		vgasr_priv.active = false;
 	}
 	mutex_unlock(&vgasr_mutex);
+	vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_HANDLER_UNREGISTERED);
 }
 EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
 
@@ -156,6 +188,7 @@ static int register_client(struct pci_dev *pdev,
 		vga_switcheroo_enable();
 	}
 	mutex_unlock(&vgasr_mutex);
+	vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_CLIENT_REGISTERED);
 	return 0;
 }
 
@@ -250,6 +283,7 @@ void vga_switcheroo_unregister_client(struct pci_dev *pdev)
 		vgasr_priv.active = false;
 	}
 	mutex_unlock(&vgasr_mutex);
+	vga_switcheroo_notifier_call_chain(VGA_SWITCHEROO_CLIENT_UNREGISTERED);
 }
 EXPORT_SYMBOL(vga_switcheroo_unregister_client);
 
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h
index e361858..c3d7c6f 100644
--- a/include/linux/vga_switcheroo.h
+++ b/include/linux/vga_switcheroo.h
@@ -11,6 +11,7 @@
 #define _LINUX_VGA_SWITCHEROO_H_
 
 #include <linux/fb.h>
+#include <linux/notifier.h>
 
 struct pci_dev;
 
@@ -28,6 +29,13 @@ enum vga_switcheroo_client_id {
 	VGA_SWITCHEROO_MAX_CLIENTS,
 };
 
+enum vga_switcheroo_event {
+	VGA_SWITCHEROO_CLIENT_REGISTERED,
+	VGA_SWITCHEROO_CLIENT_UNREGISTERED,
+	VGA_SWITCHEROO_HANDLER_REGISTERED,
+	VGA_SWITCHEROO_HANDLER_UNREGISTERED,
+};
+
 struct vga_switcheroo_handler {
 	int (*switch_ddc)(enum vga_switcheroo_client_id id);
 	int (*switchto)(enum vga_switcheroo_client_id id);
@@ -44,6 +52,9 @@ struct vga_switcheroo_client_ops {
 };
 
 #if defined(CONFIG_VGA_SWITCHEROO)
+int vga_switcheroo_register_notifier(struct notifier_block *nb);
+int vga_switcheroo_unregister_notifier(struct notifier_block *nb);
+bool vga_switcheroo_handler_registered(void);
 void vga_switcheroo_unregister_client(struct pci_dev *dev);
 int vga_switcheroo_register_client(struct pci_dev *dev,
 				   const struct vga_switcheroo_client_ops *ops);
@@ -66,6 +77,9 @@ int vga_switcheroo_get_client_state(struct pci_dev *dev);
 
 #else
 
+static inline int vga_switcheroo_register_notifier(struct notifier_block *nb) { return 0; }
+static inline int vga_switcheroo_unregister_notifier(struct notifier_block *nb) { return 0; }
+static inline bool vga_switcheroo_handler_registered(void) { return false; }
 static inline void vga_switcheroo_unregister_client(struct pci_dev *dev) {}
 static inline int vga_switcheroo_register_client(struct pci_dev *dev,
 		const struct vga_switcheroo_client_ops *ops) { return 0; }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/7] apple-gmux: Add switch_ddc support
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
                   ` (2 preceding siblings ...)
  2012-09-07 15:22 ` [PATCH 3/7] vga_switcheroo: Add notifier call chain for switcheroo events Seth Forshee
@ 2012-09-07 15:22 ` Seth Forshee
  2012-09-07 15:22 ` [PATCH 5/7] drm/edid: Switch DDC when reading the EDID Seth Forshee
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

The gmux allows muxing the DDC independently from the display, so
support this functionality. This will allow reading the EDID for the
inactive GPU, fixing issues with machines that either don't have a VBT
or have invalid mode data in the VBT.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 drivers/platform/x86/apple-gmux.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
index dfb1a92..d1e372d 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -269,14 +269,21 @@ static const struct backlight_ops gmux_bl_ops = {
 	.update_status = gmux_update_status,
 };
 
+static int gmux_switch_ddc(enum vga_switcheroo_client_id id)
+{
+	if (id == VGA_SWITCHEROO_IGD)
+		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
+	else
+		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
+	return 0;
+}
+
 static int gmux_switchto(enum vga_switcheroo_client_id id)
 {
 	if (id == VGA_SWITCHEROO_IGD) {
-		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
 		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2);
 		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2);
 	} else {
-		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
 		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3);
 		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
 	}
@@ -343,6 +350,7 @@ gmux_active_client(struct apple_gmux_data *gmux_data)
 }
 
 static struct vga_switcheroo_handler gmux_handler = {
+	.switch_ddc = gmux_switch_ddc,
 	.switchto = gmux_switchto,
 	.power_state = gmux_set_power_state,
 	.get_client_id = gmux_get_client_id,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/7] drm/edid: Switch DDC when reading the EDID
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
                   ` (3 preceding siblings ...)
  2012-09-07 15:22 ` [PATCH 4/7] apple-gmux: Add switch_ddc support Seth Forshee
@ 2012-09-07 15:22 ` Seth Forshee
  2012-09-07 15:22 ` [PATCH 6/7] drm/pci: Add drm_put_pci_dev() Seth Forshee
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

Some dual graphics machines support muxing the DDC separately from the
display, so make use of this functionality when reading the EDID on the
inactive GPU. Also serialize drm_get_edid() with a mutex to avoid races
on the DDC mux state.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 drivers/gpu/drm/drm_edid.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index b7ee230..b389269 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
+#include <linux/vga_switcheroo.h>
 #include "drmP.h"
 #include "drm_edid.h"
 #include "drm_edid_modes.h"
@@ -82,6 +83,8 @@ 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;
@@ -398,12 +401,26 @@ struct edid *drm_get_edid(struct drm_connector *connector,
 			  struct i2c_adapter *adapter)
 {
 	struct edid *edid = NULL;
+	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);
+	}
 
 	if (drm_probe_ddc(adapter))
 		edid = (struct edid *)drm_do_get_edid(connector, adapter);
 
+	if (active_pdev && active_pdev != pdev)
+		vga_switcheroo_switch_ddc(active_pdev);
+
 	connector->display_info.raw_edid = (char *)edid;
 
+	mutex_unlock(&drm_edid_mutex);
 	return edid;
 
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/7] drm/pci: Add drm_put_pci_dev()
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
                   ` (4 preceding siblings ...)
  2012-09-07 15:22 ` [PATCH 5/7] drm/edid: Switch DDC when reading the EDID Seth Forshee
@ 2012-09-07 15:22 ` Seth Forshee
  2012-09-07 15:22 ` [PATCH 7/7] drm/pci: Defer initialization of secondary graphics devices until switcheroo is ready Seth Forshee
  2012-09-07 21:35 ` [PATCH 0/7] Fixes for hybrid graphics Apple machines Dave Airlie
  7 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

When deferred initialization support for pci devices is added some
additional cleanup will be needed. Add a pci-specific put function to
serve this purpose, and convert the pci drivers over to using it. For
now it just calls drm_put_dev(), so this commit has no functional
change.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 drivers/gpu/drm/ast/ast_drv.c         |    2 +-
 drivers/gpu/drm/cirrus/cirrus_drv.c   |    2 +-
 drivers/gpu/drm/drm_pci.c             |    8 +++++++-
 drivers/gpu/drm/gma500/psb_drv.c      |    2 +-
 drivers/gpu/drm/i915/i915_drv.c       |    2 +-
 drivers/gpu/drm/mgag200/mgag200_drv.c |    2 +-
 drivers/gpu/drm/nouveau/nouveau_drv.c |    2 +-
 drivers/gpu/drm/radeon/radeon_drv.c   |    2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |    2 +-
 include/drm/drmP.h                    |    1 +
 10 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index d0c4574..001298d 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -72,7 +72,7 @@ ast_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 7053140..c7ca02b 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -64,7 +64,7 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 static const struct file_operations cirrus_driver_fops = {
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 5320364..55eb824 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -388,6 +388,12 @@ err_g1:
 }
 EXPORT_SYMBOL(drm_get_pci_dev);
 
+void drm_put_pci_dev(struct drm_device *dev)
+{
+	drm_put_dev(dev);
+}
+EXPORT_SYMBOL(drm_put_pci_dev);
+
 /**
  * PCI device initialization. Called direct from modules at load time.
  *
@@ -460,7 +466,7 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
 		pci_unregister_driver(pdriver);
 	} else {
 		list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
-			drm_put_dev(dev);
+			drm_put_pci_dev(dev);
 	}
 	DRM_INFO("Module unloaded\n");
 }
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 0c47374..d7c3c9c 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -585,7 +585,7 @@ static void psb_driver_preclose(struct drm_device *dev, struct drm_file *priv)
 static void psb_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 static const struct dev_pm_ops psb_pm_ops = {
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a24ffbe..86ae5a2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -856,7 +856,7 @@ i915_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 static int i915_pm_suspend(struct device *dev)
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index ea1024d..a3b0a4a 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -73,7 +73,7 @@ static void mga_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 static const struct file_operations mgag200_driver_fops = {
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 9a36f5f..b74b02a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -168,7 +168,7 @@ nouveau_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 int
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 8c593ea..05d2ebc 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -310,7 +310,7 @@ radeon_pci_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 static int
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 4d9edea..cf901cc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -982,7 +982,7 @@ static void vmw_remove(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
-	drm_put_dev(dev);
+	drm_put_pci_dev(dev);
 }
 
 static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index d6b67bb..eb99e96 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1748,6 +1748,7 @@ extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
 extern int drm_get_pci_dev(struct pci_dev *pdev,
 			   const struct pci_device_id *ent,
 			   struct drm_driver *driver);
+extern void drm_put_pci_dev(struct drm_device *dev);
 
 #define DRM_PCIE_SPEED_25 1
 #define DRM_PCIE_SPEED_50 2
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/7] drm/pci: Defer initialization of secondary graphics devices until switcheroo is ready
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
                   ` (5 preceding siblings ...)
  2012-09-07 15:22 ` [PATCH 6/7] drm/pci: Add drm_put_pci_dev() Seth Forshee
@ 2012-09-07 15:22 ` Seth Forshee
  2012-09-07 21:35 ` [PATCH 0/7] Fixes for hybrid graphics Apple machines Dave Airlie
  7 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-07 15:22 UTC (permalink / raw)
  To: dri-devel, linux-kernel
  Cc: David Airlie, Matthew Garrett, Daniel Vetter, Andreas Heider,
	Seth Forshee

Many Apple laptops with hybrid graphics require switching the i2c mux to
the integrated GPU when that device is being initialized in order to get
correct mode information for the LVDS panel. This requires that switcheroo
is ready at the time the device is initialized, which is not guaranteed.

To support this, delay calling the driver load() callback until the
vga_switcheroo handler and active client have been registered. This is
restricted to Apple notebooks via DMI data to avoid causing problems on
machines without switcheroo support.

Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
---
 drivers/gpu/drm/drm_drv.c |    3 +
 drivers/gpu/drm/drm_pci.c |  164 ++++++++++++++++++++++++++++++++++++++++-----
 include/drm/drmP.h        |    2 +
 3 files changed, 153 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 9238de4..124fd8a 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -276,6 +276,8 @@ static int __init drm_core_init(void)
 		goto err_p3;
 	}
 
+	drm_pci_module_init();
+
 	DRM_INFO("Initialized %s %d.%d.%d %s\n",
 		 CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
 	return 0;
@@ -291,6 +293,7 @@ err_p1:
 
 static void __exit drm_core_exit(void)
 {
+	drm_pci_module_exit();
 	remove_proc_entry("dri", NULL);
 	debugfs_remove(drm_debugfs_root);
 	drm_sysfs_destroy();
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index 55eb824..a5c9068 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -40,6 +40,10 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
+#include <linux/dmi.h>
+#include <linux/notifier.h>
+#include <linux/vgaarb.h>
+#include <linux/vga_switcheroo.h>
 #include "drmP.h"
 
 /**********************************************************************/
@@ -297,19 +301,8 @@ static struct drm_bus drm_pci_bus = {
 	.agp_init = drm_pci_agp_init,
 };
 
-/**
- * Register.
- *
- * \param pdev - PCI device structure
- * \param ent entry from the PCI ID table with device type flags
- * \return zero on success or a negative number on failure.
- *
- * Attempt to gets inter module "drm" information. If we are first
- * then register the character device and inter module information.
- * Try and register, if we fail to register, backout previous work.
- */
-int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
-		    struct drm_driver *driver)
+int __drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+		      struct drm_driver *driver)
 {
 	struct drm_device *dev;
 	int ret;
@@ -334,8 +327,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 	dev->hose = pdev->sysdata;
 #endif
 
-	mutex_lock(&drm_global_mutex);
-
 	if ((ret = drm_fill_in_dev(dev, ent, driver))) {
 		printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
 		goto err_g2;
@@ -371,7 +362,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 		 driver->name, driver->major, driver->minor, driver->patchlevel,
 		 driver->date, pci_name(pdev), dev->primary->index);
 
-	mutex_unlock(&drm_global_mutex);
 	return 0;
 
 err_g4:
@@ -386,10 +376,140 @@ err_g1:
 	mutex_unlock(&drm_global_mutex);
 	return ret;
 }
+
+/*
+ * List of machines that require delaying initialization of the secondary
+ * GPU until vga_switcheroo is ready.
+ */
+static struct dmi_system_id deferred_init_dmi_table[] = {
+	{
+		.ident = "Apple Laptop",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
+		},
+	},
+};
+
+struct deferred_init_data {
+	struct list_head list;
+	struct pci_dev *pdev;
+	const struct pci_device_id *ent;
+	struct drm_driver *driver;
+};
+
+static LIST_HEAD(deferred_init_list);
+
+static bool drm_pci_switcheroo_ready(void)
+{
+	if (!vga_switcheroo_handler_registered())
+		return false;
+	if (!vga_switcheroo_get_active_client())
+		return false;
+	return true;
+}
+
+static void drm_deferred_init_work_fn(struct work_struct *work)
+{
+	struct deferred_init_data *di_data, *temp;
+
+	mutex_lock(&drm_global_mutex);
+
+	if (!drm_pci_switcheroo_ready()) {
+		mutex_unlock(&drm_global_mutex);
+		return;
+	}
+
+	list_for_each_entry_safe(di_data, temp, &deferred_init_list, list) {
+		if (__drm_get_pci_dev(di_data->pdev, di_data->ent,
+				      di_data->driver))
+			DRM_ERROR("pci device initialization failed\n");
+		list_del(&di_data->list);
+		kfree(di_data);
+	}
+	mutex_unlock(&drm_global_mutex);
+}
+static DECLARE_WORK(deferred_init_work, drm_deferred_init_work_fn);
+
+static int drm_switcheroo_notifier_fn(struct notifier_block *nb,
+				      unsigned long val, void *unused)
+{
+	if (val == VGA_SWITCHEROO_CLIENT_REGISTERED ||
+	    val == VGA_SWITCHEROO_HANDLER_REGISTERED)
+		queue_work(system_nrt_wq, &deferred_init_work);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block drm_switcheroo_notifier = {
+	.notifier_call = drm_switcheroo_notifier_fn,
+};
+
+static bool drm_pci_needs_deferred_init(struct pci_dev *pdev)
+{
+	if (!dmi_check_system(deferred_init_dmi_table))
+		return false;
+	if (vga_default_device() == pdev)
+		return false;
+	return !drm_pci_switcheroo_ready();
+}
+
+/**
+ * Register.
+ *
+ * \param pdev - PCI device structure
+ * \param ent entry from the PCI ID table with device type flags
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+		    struct drm_driver *driver)
+{
+	int ret = 0;
+
+	mutex_lock(&drm_global_mutex);
+
+	/*
+	 * On some machines secondary graphics devices shouldn't be
+	 * initialized until the handler and primary graphics device
+	 * have been registered with vga_switcheroo.
+	 */
+	if (drm_pci_needs_deferred_init(pdev)) {
+		struct deferred_init_data *di_data =
+			kmalloc(sizeof(*di_data), GFP_KERNEL);
+		if (!di_data) {
+			ret = -ENOMEM;
+		} else {
+			di_data->pdev = pdev;
+			di_data->ent = ent;
+			di_data->driver = driver;
+			list_add_tail(&di_data->list, &deferred_init_list);
+		}
+	} else {
+		ret = __drm_get_pci_dev(pdev, ent, driver);
+	}
+
+	mutex_unlock(&drm_global_mutex);
+	return ret;
+}
 EXPORT_SYMBOL(drm_get_pci_dev);
 
 void drm_put_pci_dev(struct drm_device *dev)
 {
+	struct deferred_init_data *di_data;
+
+	mutex_lock(&drm_global_mutex);
+	list_for_each_entry(di_data, &deferred_init_list, list) {
+		if (di_data->pdev == dev->pdev) {
+			list_del(&di_data->list);
+			kfree(di_data);
+			break;
+		}
+	}
+	mutex_unlock(&drm_global_mutex);
+
 	drm_put_dev(dev);
 }
 EXPORT_SYMBOL(drm_put_pci_dev);
@@ -520,3 +640,15 @@ int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
 	return 0;
 }
 EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask);
+
+int drm_pci_module_init(void)
+{
+	return vga_switcheroo_register_notifier(&drm_switcheroo_notifier);
+}
+EXPORT_SYMBOL(drm_pci_module_init);
+
+void drm_pci_module_exit(void)
+{
+	vga_switcheroo_unregister_notifier(&drm_switcheroo_notifier);
+}
+EXPORT_SYMBOL(drm_pci_module_exit);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index eb99e96..0e9401f 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1749,6 +1749,8 @@ extern int drm_get_pci_dev(struct pci_dev *pdev,
 			   const struct pci_device_id *ent,
 			   struct drm_driver *driver);
 extern void drm_put_pci_dev(struct drm_device *dev);
+extern int drm_pci_module_init(void);
+extern void drm_pci_module_exit(void);
 
 #define DRM_PCIE_SPEED_25 1
 #define DRM_PCIE_SPEED_50 2
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/7] Fixes for hybrid graphics Apple machines
  2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
                   ` (6 preceding siblings ...)
  2012-09-07 15:22 ` [PATCH 7/7] drm/pci: Defer initialization of secondary graphics devices until switcheroo is ready Seth Forshee
@ 2012-09-07 21:35 ` Dave Airlie
  2012-09-08  5:07   ` Seth Forshee
  7 siblings, 1 reply; 10+ messages in thread
From: Dave Airlie @ 2012-09-07 21:35 UTC (permalink / raw)
  To: Seth Forshee
  Cc: dri-devel, linux-kernel, David Airlie, Matthew Garrett,
	Daniel Vetter, Andreas Heider

On Fri, Sep 7, 2012 at 4:22 PM, Seth Forshee <seth.forshee@canonical.com> wrote:
> Many hybrid graphics Apple laptops fail to set up LVDS on the secondary
> GPU due to missing or incorrect mode information for the panel at init
> time. The only way to get the LVDS mode on these machines is via the
> DDC, but this is muxed to the active GPU at boot. However, the graphics
> mux on these machines supports muxing the i2c idependently of the
> display, making it possible for the secondary graphics driver to read
> the EDID without a full display switch.
>
> In order to support this, these patches modify vga_switcheroo to allow
> muxing of the DDC idependently of the display. apple-gmux is updated to
> support this new functionality, and drm_get_edid() is modified to switch
> the DDC mux as needed.
>
> For this to work we also need to ensure that sufficient switcheroo
> suport is available before initializing the secondary GPU. This is done
> by adding any non-active GPUs that try to initialize before switcheroo
> is ready to a list and initializing these devices once switcheroo
> becomes ready. This behavior is restricted to Apple laptops to prevent
> causing problems on other machines.

I hate this idea, no delaying stuff. We either need to have some sort
of enforced ordering or make some stuff only work built-in.

But sticking things on a delayed list just in case seems wrong to me.

Dave.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/7] Fixes for hybrid graphics Apple machines
  2012-09-07 21:35 ` [PATCH 0/7] Fixes for hybrid graphics Apple machines Dave Airlie
@ 2012-09-08  5:07   ` Seth Forshee
  0 siblings, 0 replies; 10+ messages in thread
From: Seth Forshee @ 2012-09-08  5:07 UTC (permalink / raw)
  To: Dave Airlie
  Cc: dri-devel, linux-kernel, David Airlie, Matthew Garrett,
	Daniel Vetter, Andreas Heider

On Fri, Sep 07, 2012 at 10:35:04PM +0100, Dave Airlie wrote:
> On Fri, Sep 7, 2012 at 4:22 PM, Seth Forshee <seth.forshee@canonical.com> wrote:
> > Many hybrid graphics Apple laptops fail to set up LVDS on the secondary
> > GPU due to missing or incorrect mode information for the panel at init
> > time. The only way to get the LVDS mode on these machines is via the
> > DDC, but this is muxed to the active GPU at boot. However, the graphics
> > mux on these machines supports muxing the i2c idependently of the
> > display, making it possible for the secondary graphics driver to read
> > the EDID without a full display switch.
> >
> > In order to support this, these patches modify vga_switcheroo to allow
> > muxing of the DDC idependently of the display. apple-gmux is updated to
> > support this new functionality, and drm_get_edid() is modified to switch
> > the DDC mux as needed.
> >
> > For this to work we also need to ensure that sufficient switcheroo
> > suport is available before initializing the secondary GPU. This is done
> > by adding any non-active GPUs that try to initialize before switcheroo
> > is ready to a list and initializing these devices once switcheroo
> > becomes ready. This behavior is restricted to Apple laptops to prevent
> > causing problems on other machines.
> 
> I hate this idea, no delaying stuff. We either need to have some sort
> of enforced ordering or make some stuff only work built-in.
> 
> But sticking things on a delayed list just in case seems wrong to me.

I really don't like it either. My preferred solution would be to have
i915 register the LVDS connector whenever we can reasonably expect that
an LVDS panel might be present, then treat the panel as disconnected
until we can get the mode information. I was headed down this path with
the first patches I sent, but both Daniel and Matthew responded
unfavorably to this approach.

Otherwise I'm open to suggestions on how enforcing the ordering of the
device initializations. Forcing apple-gmux to be built-in or making i915
depend on it might solve the problem, but I don't find either of these
to be very desirable either.

Thanks,
Seth


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-09-08  5:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-07 15:22 [PATCH 0/7] Fixes for hybrid graphics Apple machines Seth Forshee
2012-09-07 15:22 ` [PATCH 1/7] vga_switcheroo: Add support for switching only the DDC Seth Forshee
2012-09-07 15:22 ` [PATCH 2/7] vga_switcheroo: Add helper function to get the active client Seth Forshee
2012-09-07 15:22 ` [PATCH 3/7] vga_switcheroo: Add notifier call chain for switcheroo events Seth Forshee
2012-09-07 15:22 ` [PATCH 4/7] apple-gmux: Add switch_ddc support Seth Forshee
2012-09-07 15:22 ` [PATCH 5/7] drm/edid: Switch DDC when reading the EDID Seth Forshee
2012-09-07 15:22 ` [PATCH 6/7] drm/pci: Add drm_put_pci_dev() Seth Forshee
2012-09-07 15:22 ` [PATCH 7/7] drm/pci: Defer initialization of secondary graphics devices until switcheroo is ready Seth Forshee
2012-09-07 21:35 ` [PATCH 0/7] Fixes for hybrid graphics Apple machines Dave Airlie
2012-09-08  5:07   ` Seth Forshee

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).