aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/vga/vga_switcheroo.c
diff options
context:
space:
mode:
authorSeth Forshee <seth.forshee@canonical.com>2012-08-17 12:17:03 -0400
committerMatthew Garrett <mjg@redhat.com>2012-08-17 17:34:41 -0400
commit36704c0c4c64f889d77158d497f6a7e596d1341c (patch)
tree540dbed65a418bb599a729a17aa8cc806a1042af /drivers/gpu/vga/vga_switcheroo.c
parent76b487dd5187a4d7cc6eccd452f65467a8c7768b (diff)
vga_switcheroo: Remove assumptions about registration/unregistration ordering
vga_switcheroo assumes that the handler will be registered before the last client, otherwise switching will not be enabled. Likewise it's assumed that the handler will not be unregistered without at least one client also being unregistered, otherwise switching will remain enabled despite no longer having a handler. These assumptions cannot be enforced if the handler is in a separate driver from both clients, as with the gmux found in Apple laptops. Remove this assumption. Signed-off-by: Seth Forshee <seth.forshee@canonical.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/gpu/vga/vga_switcheroo.c')
-rw-r--r--drivers/gpu/vga/vga_switcheroo.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index 5b3c7d135dc9..e10ba3755dfa 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -70,27 +70,12 @@ static struct vgasr_priv vgasr_priv = {
70 .clients = LIST_HEAD_INIT(vgasr_priv.clients), 70 .clients = LIST_HEAD_INIT(vgasr_priv.clients),
71}; 71};
72 72
73int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) 73static bool vga_switcheroo_ready(void)
74{
75 mutex_lock(&vgasr_mutex);
76 if (vgasr_priv.handler) {
77 mutex_unlock(&vgasr_mutex);
78 return -EINVAL;
79 }
80
81 vgasr_priv.handler = handler;
82 mutex_unlock(&vgasr_mutex);
83 return 0;
84}
85EXPORT_SYMBOL(vga_switcheroo_register_handler);
86
87void vga_switcheroo_unregister_handler(void)
88{ 74{
89 mutex_lock(&vgasr_mutex); 75 /* we're ready if we get two clients + handler */
90 vgasr_priv.handler = NULL; 76 return !vgasr_priv.active &&
91 mutex_unlock(&vgasr_mutex); 77 vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
92} 78}
93EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
94 79
95static void vga_switcheroo_enable(void) 80static void vga_switcheroo_enable(void)
96{ 81{
@@ -113,6 +98,37 @@ static void vga_switcheroo_enable(void)
113 vgasr_priv.active = true; 98 vgasr_priv.active = true;
114} 99}
115 100
101int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
102{
103 mutex_lock(&vgasr_mutex);
104 if (vgasr_priv.handler) {
105 mutex_unlock(&vgasr_mutex);
106 return -EINVAL;
107 }
108
109 vgasr_priv.handler = handler;
110 if (vga_switcheroo_ready()) {
111 printk(KERN_INFO "vga_switcheroo: enabled\n");
112 vga_switcheroo_enable();
113 }
114 mutex_unlock(&vgasr_mutex);
115 return 0;
116}
117EXPORT_SYMBOL(vga_switcheroo_register_handler);
118
119void vga_switcheroo_unregister_handler(void)
120{
121 mutex_lock(&vgasr_mutex);
122 vgasr_priv.handler = NULL;
123 if (vgasr_priv.active) {
124 pr_info("vga_switcheroo: disabled\n");
125 vga_switcheroo_debugfs_fini(&vgasr_priv);
126 vgasr_priv.active = false;
127 }
128 mutex_unlock(&vgasr_mutex);
129}
130EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
131
116static int register_client(struct pci_dev *pdev, 132static int register_client(struct pci_dev *pdev,
117 const struct vga_switcheroo_client_ops *ops, 133 const struct vga_switcheroo_client_ops *ops,
118 int id, bool active) 134 int id, bool active)
@@ -134,9 +150,7 @@ static int register_client(struct pci_dev *pdev,
134 if (client_is_vga(client)) 150 if (client_is_vga(client))
135 vgasr_priv.registered_clients++; 151 vgasr_priv.registered_clients++;
136 152
137 /* if we get two clients + handler */ 153 if (vga_switcheroo_ready()) {
138 if (!vgasr_priv.active &&
139 vgasr_priv.registered_clients == 2 && vgasr_priv.handler) {
140 printk(KERN_INFO "vga_switcheroo: enabled\n"); 154 printk(KERN_INFO "vga_switcheroo: enabled\n");
141 vga_switcheroo_enable(); 155 vga_switcheroo_enable();
142 } 156 }