xref: /dragonfly/sys/dev/video/vga/vga_switcheroo.c (revision d8d5b238)
1 /*
2  * vga_switcheroo.c -- vga_switcheroo driver for DragonFly
3  *
4  * Adapted from linux v4.8: linux-src/drivers/gpu/vga/vga_switcheroo.c
5  *
6  */
7 
8 /*
9  * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
10  *
11  * Copyright (c) 2010 Red Hat Inc.
12  * Author : Dave Airlie <airlied@redhat.com>
13  *
14  * Copyright (c) 2015 Lukas Wunner <lukas@wunner.de>
15  *
16  * Permission is hereby granted, free of charge, to any person obtaining a
17  * copy of this software and associated documentation files (the "Software"),
18  * to deal in the Software without restriction, including without limitation
19  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20  * and/or sell copies of the Software, and to permit persons to whom the
21  * Software is furnished to do so, subject to the following conditions:
22  *
23  * The above copyright notice and this permission notice (including the next
24  * paragraph) shall be included in all copies or substantial portions of the
25  * Software.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
30  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33  * DEALINGS
34  * IN THE SOFTWARE.
35  *
36  */
37 
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/bio.h>
41 #include <sys/bus.h>
42 #include <sys/malloc.h>
43 #include <sys/module.h>
44 #include <sys/proc.h>
45 #include <sys/types.h>
46 #include <sys/sysctl.h>
47 #include <sys/systm.h>
48 #include <sys/device.h>
49 #include <sys/conf.h>
50 #include <sys/rman.h>
51 #include <sys/uio.h>
52 
53 #define pr_fmt(fmt) "vga_switcheroo: " fmt
54 
55 #include <linux/fb.h>
56 #include <linux/fs.h>
57 #include <linux/module.h>
58 #include <linux/pci.h>
59 #include <linux/pci_ids.h>
60 #include <linux/mutex.h>
61 #include <linux/list.h>
62 #include <linux/export.h>
63 
64 #define VGA_SWITCHEROO
65 #include <linux/vga_switcheroo.h>
66 
67 /**
68  * DOC: Overview
69  *
70  * vga_switcheroo is the Linux subsystem for laptop hybrid graphics.
71  * These come in two flavors:
72  *
73  * * muxed: Dual GPUs with a multiplexer chip to switch outputs between GPUs.
74  * * muxless: Dual GPUs but only one of them is connected to outputs.
75  * 	The other one is merely used to offload rendering, its results
76  * 	are copied over PCIe into the framebuffer. On Linux this is
77  * 	supported with DRI PRIME.
78  *
79  * Hybrid graphics started to appear in the late Naughties and were initially
80  * all muxed. Newer laptops moved to a muxless architecture for cost reasons.
81  * A notable exception is the MacBook Pro which continues to use a mux.
82  * Muxes come with varying capabilities: Some switch only the panel, others
83  * can also switch external displays. Some switch all display pins at once
84  * while others can switch just the DDC lines. (To allow EDID probing
85  * for the inactive GPU.) Also, muxes are often used to cut power to the
86  * discrete GPU while it is not used.
87  *
88  * DRM drivers register GPUs with vga_switcheroo, these are henceforth called
89  * clients. The mux is called the handler. Muxless machines also register a
90  * handler to control the power state of the discrete GPU, its ->switchto
91  * callback is a no-op for obvious reasons. The discrete GPU is often equipped
92  * with an HDA controller for the HDMI/DP audio signal, this will also
93  * register as a client so that vga_switcheroo can take care of the correct
94  * suspend/resume order when changing the discrete GPU's power state. In total
95  * there can thus be up to three clients: Two vga clients (GPUs) and one audio
96  * client (on the discrete GPU). The code is mostly prepared to support
97  * machines with more than two GPUs should they become available.
98  *
99  * The GPU to which the outputs are currently switched is called the
100  * active client in vga_switcheroo parlance. The GPU not in use is the
101  * inactive client. When the inactive client's DRM driver is loaded,
102  * it will be unable to probe the panel's EDID and hence depends on
103  * VBIOS to provide its display modes. If the VBIOS modes are bogus or
104  * if there is no VBIOS at all (which is common on the MacBook Pro),
105  * a client may alternatively request that the DDC lines are temporarily
106  * switched to it, provided that the handler supports this. Switching
107  * only the DDC lines and not the entire output avoids unnecessary
108  * flickering.
109  */
110 
111 /**
112  * struct vga_switcheroo_client - registered client
113  * @pdev: client pci device
114  * @fb_info: framebuffer to which console is remapped on switching
115  * @pwr_state: current power state
116  * @ops: client callbacks
117  * @id: client identifier. Determining the id requires the handler,
118  * 	so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID
119  * 	and later given their true id in vga_switcheroo_enable()
120  * @active: whether the outputs are currently switched to this client
121  * @driver_power_control: whether power state is controlled by the driver's
122  * 	runtime pm. If true, writing ON and OFF to the vga_switcheroo debugfs
123  * 	interface is a no-op so as not to interfere with runtime pm
124  * @list: client list
125  *
126  * Registered client. A client can be either a GPU or an audio device on a GPU.
127  * For audio clients, the @fb_info, @active and @driver_power_control members
128  * are bogus.
129  */
130 struct vga_switcheroo_client {
131 	struct pci_dev *pdev;
132 	struct fb_info *fb_info;
133 	enum vga_switcheroo_state pwr_state;
134 	const struct vga_switcheroo_client_ops *ops;
135 	enum vga_switcheroo_client_id id;
136 	bool active;
137 	bool driver_power_control;
138 	struct list_head list;
139 };
140 
141 /*
142  * protects access to struct vgasr_priv
143  */
144 static DEFINE_MUTEX(vgasr_mutex);
145 
146 /**
147  * struct vgasr_priv - vga_switcheroo private data
148  * @active: whether vga_switcheroo is enabled.
149  * 	Prerequisite is the registration of two GPUs and a handler
150  * @delayed_switch_active: whether a delayed switch is pending
151  * @delayed_client_id: client to which a delayed switch is pending
152  * @debugfs_root: directory for vga_switcheroo debugfs interface
153  * @switch_file: file for vga_switcheroo debugfs interface
154  * @registered_clients: number of registered GPUs
155  * 	(counting only vga clients, not audio clients)
156  * @clients: list of registered clients
157  * @handler: registered handler
158  * @handler_flags: flags of registered handler
159  * @mux_hw_lock: protects mux state
160  *	(in particular while DDC lines are temporarily switched)
161  * @old_ddc_owner: client to which DDC lines will be switched back on unlock
162  *
163  * vga_switcheroo private data. Currently only one vga_switcheroo instance
164  * per system is supported.
165  */
166 struct vgasr_priv {
167 	bool active;
168 	bool delayed_switch_active;
169 	enum vga_switcheroo_client_id delayed_client_id;
170 
171 	struct dentry *debugfs_root;
172 	struct dentry *switch_file;
173 
174 	int registered_clients;
175 	struct list_head clients;
176 
177 	const struct vga_switcheroo_handler *handler;
178 	enum vga_switcheroo_handler_flags_t handler_flags;
179 	struct lock mux_hw_lk;
180 	int old_ddc_owner;
181 };
182 
183 #define ID_BIT_AUDIO		0x100
184 #define client_is_audio(c)	((c)->id & ID_BIT_AUDIO)
185 #define client_is_vga(c)	((c)->id == VGA_SWITCHEROO_UNKNOWN_ID || \
186 				 !client_is_audio(c))
187 #define client_id(c)		((c)->id & ~ID_BIT_AUDIO)
188 
189 #if 0
190 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
191 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
192 #endif
193 
194 /* only one switcheroo per system */
195 static struct vgasr_priv *vgasr_priv;
196 
197 static bool
198 vga_switcheroo_ready(void)
199 {
200 	/* we're ready if we get two clients + handler */
201 	return !vgasr_priv->active &&
202 	       vgasr_priv->registered_clients == 2 && vgasr_priv->handler;
203 }
204 
205 static void
206 vga_switcheroo_enable(void)
207 {
208 	int ret;
209 	struct vga_switcheroo_client *client;
210 
211 	/* call the handler to init */
212 	if (vgasr_priv->handler->init)
213 		vgasr_priv->handler->init();
214 
215 	list_for_each_entry(client, &vgasr_priv->clients, list) {
216 		if (client->id != VGA_SWITCHEROO_UNKNOWN_ID)
217 			continue;
218 		ret = vgasr_priv->handler->get_client_id(client->pdev);
219 		if (ret < 0)
220 			return;
221 
222 		client->id = ret;
223 	}
224 	//XXX: TODO
225 	//vga_switcheroo_debugfs_init(&vgasr_priv);
226 	vgasr_priv->active = true;
227 }
228 
229 /**
230  * vga_switcheroo_register_handler() - register handler
231  * @handler: handler callbacks
232  * @handler_flags: handler flags
233  *
234  * Register handler. Enable vga_switcheroo if two vga clients have already
235  * registered.
236  *
237  * Return: 0 on success, -EINVAL if a handler was already registered.
238  */
239 int
240 vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
241 				    enum vga_switcheroo_handler_flags_t handler_flags)
242 {
243 	mutex_lock(&vgasr_mutex);
244 	if (vgasr_priv->handler) {
245 		mutex_unlock(&vgasr_mutex);
246 		return -EINVAL;
247 	}
248 
249 	vgasr_priv->handler = handler;
250 	vgasr_priv->handler_flags = handler_flags;
251 	if (vga_switcheroo_ready()) {
252 		pr_info("enabled\n");
253 		vga_switcheroo_enable();
254 	}
255 	mutex_unlock(&vgasr_mutex);
256 	return 0;
257 }
258 EXPORT_SYMBOL(vga_switcheroo_register_handler);
259 
260 /**
261  * vga_switcheroo_unregister_handler() - unregister handler
262  *
263  * Unregister handler. Disable vga_switcheroo.
264  */
265 void
266 vga_switcheroo_unregister_handler(void)
267 {
268 	mutex_lock(&vgasr_mutex);
269 	mutex_lock(&vgasr_priv->mux_hw_lk);
270 	vgasr_priv->handler_flags = 0;
271 	vgasr_priv->handler = NULL;
272 	if (vgasr_priv->active) {
273 		pr_info("disabled\n");
274 		//XXX TODO:
275 		//vga_switcheroo_debugfs_fini(&vgasr_priv);
276 		vgasr_priv->active = false;
277 	}
278 	mutex_unlock(&vgasr_priv->mux_hw_lk);
279 	mutex_unlock(&vgasr_mutex);
280 }
281 EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
282 
283 /**
284  * vga_switcheroo_handler_flags() - obtain handler flags
285  *
286  * Helper for clients to obtain the handler flags bitmask.
287  *
288  * Return: Handler flags. A value of 0 means that no handler is registered
289  * or that the handler has no special capabilities.
290  */
291 enum vga_switcheroo_handler_flags_t
292 vga_switcheroo_handler_flags(void)
293 {
294 	return vgasr_priv->handler_flags;
295 }
296 EXPORT_SYMBOL(vga_switcheroo_handler_flags);
297 
298 MALLOC_DECLARE(M_VGA_SWITCHEROO_CLIENT);
299 MALLOC_DEFINE(M_VGA_SWITCHEROO_CLIENT, "vga_switcheroo_client", "vga_switcheroo client data");
300 
301 static int
302 register_client(struct pci_dev *pdev,
303 			   const struct vga_switcheroo_client_ops *ops,
304 			   enum vga_switcheroo_client_id id, bool active,
305 			   bool driver_power_control)
306 {
307 	struct vga_switcheroo_client *client;
308 
309 	client = kmalloc(sizeof(*client), M_VGA_SWITCHEROO_CLIENT, M_WAITOK | M_ZERO);
310 	if (!client)
311 		return -ENOMEM;
312 
313 	client->pwr_state = VGA_SWITCHEROO_ON;
314 	client->pdev = pdev;
315 	client->ops = ops;
316 	client->id = id;
317 	client->active = active;
318 	client->driver_power_control = driver_power_control;
319 
320 	mutex_lock(&vgasr_mutex);
321 	list_add_tail(&client->list, &vgasr_priv->clients);
322 	if (client_is_vga(client))
323 		vgasr_priv->registered_clients++;
324 
325 	if (vga_switcheroo_ready()) {
326 		pr_info("enabled\n");
327 		vga_switcheroo_enable();
328 	}
329 	mutex_unlock(&vgasr_mutex);
330 	return 0;
331 }
332 
333 /**
334  * vga_switcheroo_register_client - register vga client
335  * @pdev: client pci device
336  * @ops: client callbacks
337  * @driver_power_control: whether power state is controlled by the driver's
338  * 	runtime pm
339  *
340  * Register vga client (GPU). Enable vga_switcheroo if another GPU and a
341  * handler have already registered. The power state of the client is assumed
342  * to be ON.
343  *
344  * Return: 0 on success, -ENOMEM on memory allocation error.
345  */
346 int
347 vga_switcheroo_register_client(struct pci_dev *pdev,
348 				   const struct vga_switcheroo_client_ops *ops,
349 				   bool driver_power_control)
350 {
351 	int error = 0;
352 	int unit, default_vgapci_unit;
353 	size_t len;
354 
355 	/*
356 	 * We need to find out if video device pci_dev is
357 	 * the active (default) video device: will determine
358 	 * if the pci_dev unit is the default_vgapci_unit
359 	 */
360 	unit = device_get_unit(pdev->dev.bsddev);
361 
362 	len = sizeof(default_vgapci_unit);
363 	error = kernel_sysctlbyname("hw.pci.default_vgapci_unit", &default_vgapci_unit, &len, NULL, 0, NULL);
364 	if (error) {
365 		pr_err("kernel_sysctlbyname: error %d\n", error);
366 		return (error);
367 	}
368 
369 	return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID,
370 			       unit == default_vgapci_unit,
371 			       driver_power_control);
372 }
373 EXPORT_SYMBOL(vga_switcheroo_register_client);
374 
375 /**
376  * vga_switcheroo_register_audio_client - register audio client
377  * @pdev: client pci device
378  * @ops: client callbacks
379  * @id: client identifier
380  *
381  * Register audio client (audio device on a GPU). The power state of the
382  * client is assumed to be ON.
383  *
384  * Return: 0 on success, -ENOMEM on memory allocation error.
385  */
386 int
387 vga_switcheroo_register_audio_client(struct pci_dev *pdev,
388 					 const struct vga_switcheroo_client_ops *ops,
389 					 enum vga_switcheroo_client_id id)
390 {
391 	return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false);
392 }
393 EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
394 
395 static struct vga_switcheroo_client *
396 find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
397 {
398 	struct vga_switcheroo_client *client;
399 
400 	list_for_each_entry(client, head, list)
401 		if (client->pdev == pdev)
402 			return client;
403 	return NULL;
404 }
405 
406 static struct vga_switcheroo_client *
407 find_client_from_id(struct list_head *head,
408 		    enum vga_switcheroo_client_id client_id)
409 {
410 	struct vga_switcheroo_client *client;
411 
412 	list_for_each_entry(client, head, list)
413 		if (client->id == client_id)
414 			return client;
415 	return NULL;
416 }
417 
418 static struct vga_switcheroo_client *
419 find_active_client(struct list_head *head)
420 {
421 	struct vga_switcheroo_client *client;
422 
423 	list_for_each_entry(client, head, list)
424 		if (client->active)
425 			return client;
426 	return NULL;
427 }
428 
429 /**
430  * vga_switcheroo_client_probe_defer() - whether to defer probing a given client
431  * @pdev: client pci device
432  *
433  * Determine whether any prerequisites are not fulfilled to probe a given
434  * client. Drivers shall invoke this early on in their ->probe callback
435  * and return %-EPROBE_DEFER if it evaluates to %true. Thou shalt not
436  * register the client ere thou hast called this.
437  *
438  * Return: %true if probing should be deferred, otherwise %false.
439  */
440  #if 0
441 bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)
442 {
443 	if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
444 		/*
445 		 * apple-gmux is needed on pre-retina MacBook Pro
446 		 * to probe the panel if pdev is the inactive GPU.
447 		 */
448 		if (apple_gmux_present() && pdev != vga_default_device() &&
449 		    !vgasr_priv.handler_flags)
450 			return true;
451 	}
452 
453 	return false;
454 }
455 EXPORT_SYMBOL(vga_switcheroo_client_probe_defer);
456 #endif
457 
458 /**
459  * vga_switcheroo_get_client_state() - obtain power state of a given client
460  * @pdev: client pci device
461  *
462  * Obtain power state of a given client as seen from vga_switcheroo.
463  * The function is only called from hda_intel.c.
464  *
465  * Return: Power state.
466  */
467 enum vga_switcheroo_state
468 vga_switcheroo_get_client_state(struct pci_dev *pdev)
469 {
470 	struct vga_switcheroo_client *client;
471 	enum vga_switcheroo_state ret;
472 
473 	mutex_lock(&vgasr_mutex);
474 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
475 	if (!client)
476 		ret = VGA_SWITCHEROO_NOT_FOUND;
477 	else
478 		ret = client->pwr_state;
479 	mutex_unlock(&vgasr_mutex);
480 	return ret;
481 }
482 EXPORT_SYMBOL(vga_switcheroo_get_client_state);
483 
484 /**
485  * vga_switcheroo_unregister_client() - unregister client
486  * @pdev: client pci device
487  *
488  * Unregister client. Disable vga_switcheroo if this is a vga client (GPU).
489  */
490 void
491 vga_switcheroo_unregister_client(struct pci_dev *pdev)
492 {
493 	struct vga_switcheroo_client *client;
494 
495 	mutex_lock(&vgasr_mutex);
496 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
497 	if (client) {
498 		if (client_is_vga(client))
499 			vgasr_priv->registered_clients--;
500 		list_del(&client->list);
501 		kfree(client, M_VGA_SWITCHEROO_CLIENT);
502 	}
503 	if (vgasr_priv->active && vgasr_priv->registered_clients < 2) {
504 		pr_info("disabled\n");
505 		//XXX: TODO
506 		//vga_switcheroo_debugfs_fini(&vgasr_priv);
507 		vgasr_priv->active = false;
508 	}
509 	mutex_unlock(&vgasr_mutex);
510 }
511 EXPORT_SYMBOL(vga_switcheroo_unregister_client);
512 
513 /**
514  * vga_switcheroo_client_fb_set() - set framebuffer of a given client
515  * @pdev: client pci device
516  * @info: framebuffer
517  *
518  * Set framebuffer of a given client. The console will be remapped to this
519  * on switching.
520  */
521 void
522 vga_switcheroo_client_fb_set(struct pci_dev *pdev,
523 				 struct fb_info *info)
524 {
525 	struct vga_switcheroo_client *client;
526 
527 	mutex_lock(&vgasr_mutex);
528 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
529 	if (client)
530 		client->fb_info = info;
531 	mutex_unlock(&vgasr_mutex);
532 }
533 EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
534 
535 /**
536  * vga_switcheroo_lock_ddc() - temporarily switch DDC lines to a given client
537  * @pdev: client pci device
538  *
539  * Temporarily switch DDC lines to the client identified by @pdev
540  * (but leave the outputs otherwise switched to where they are).
541  * This allows the inactive client to probe EDID. The DDC lines must
542  * afterwards be switched back by calling vga_switcheroo_unlock_ddc(),
543  * even if this function returns an error.
544  *
545  * Return: Previous DDC owner on success or a negative int on error.
546  * Specifically, %-ENODEV if no handler has registered or if the handler
547  * does not support switching the DDC lines. Also, a negative value
548  * returned by the handler is propagated back to the caller.
549  * The return value has merely an informational purpose for any caller
550  * which might be interested in it. It is acceptable to ignore the return
551  * value and simply rely on the result of the subsequent EDID probe,
552  * which will be %NULL if DDC switching failed.
553  */
554 int
555 vga_switcheroo_lock_ddc(struct pci_dev *pdev)
556 {
557 	enum vga_switcheroo_client_id id;
558 
559 	mutex_lock(&vgasr_priv->mux_hw_lk);
560 	if (!vgasr_priv->handler || !vgasr_priv->handler->switch_ddc) {
561 		vgasr_priv->old_ddc_owner = -ENODEV;
562 		return -ENODEV;
563 	}
564 
565 	id = vgasr_priv->handler->get_client_id(pdev);
566 	vgasr_priv->old_ddc_owner = vgasr_priv->handler->switch_ddc(id);
567 	return vgasr_priv->old_ddc_owner;
568 }
569 EXPORT_SYMBOL(vga_switcheroo_lock_ddc);
570 
571 /**
572  * vga_switcheroo_unlock_ddc() - switch DDC lines back to previous owner
573  * @pdev: client pci device
574  *
575  * Switch DDC lines back to the previous owner after calling
576  * vga_switcheroo_lock_ddc(). This must be called even if
577  * vga_switcheroo_lock_ddc() returned an error.
578  *
579  * Return: Previous DDC owner on success (i.e. the client identifier of @pdev)
580  * or a negative int on error.
581  * Specifically, %-ENODEV if no handler has registered or if the handler
582  * does not support switching the DDC lines. Also, a negative value
583  * returned by the handler is propagated back to the caller.
584  * Finally, invoking this function without calling vga_switcheroo_lock_ddc()
585  * first is not allowed and will result in %-EINVAL.
586  */
587 int
588 vga_switcheroo_unlock_ddc(struct pci_dev *pdev)
589 {
590 	enum vga_switcheroo_client_id id;
591 	int ret = vgasr_priv->old_ddc_owner;
592 
593 	if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv->mux_hw_lk)))
594 		return -EINVAL;
595 
596 	if (vgasr_priv->old_ddc_owner >= 0) {
597 		id = vgasr_priv->handler->get_client_id(pdev);
598 		if (vgasr_priv->old_ddc_owner != id)
599 			ret = vgasr_priv->handler->switch_ddc(
600 						     vgasr_priv->old_ddc_owner);
601 	}
602 	mutex_unlock(&vgasr_priv->mux_hw_lk);
603 	return ret;
604 }
605 EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);
606 
607 /**
608  * DOC: Manual switching and manual power control
609  *
610  * In this mode of use, the file /sys/kernel/debug/vgaswitcheroo/switch
611  * can be read to retrieve the current vga_switcheroo state and commands
612  * can be written to it to change the state. The file appears as soon as
613  * two GPU drivers and one handler have registered with vga_switcheroo.
614  * The following commands are understood:
615  *
616  * * OFF: Power off the device not in use.
617  * * ON: Power on the device not in use.
618  * * IGD: Switch to the integrated graphics device.
619  * 	Power on the integrated GPU if necessary, power off the discrete GPU.
620  * 	Prerequisite is that no user space processes (e.g. Xorg, alsactl)
621  * 	have opened device files of the GPUs or the audio client. If the
622  * 	switch fails, the user may invoke lsof(8) or fuser(1) on /dev/dri/
623  * 	and /dev/snd/controlC1 to identify processes blocking the switch.
624  * * DIS: Switch to the discrete graphics device.
625  * * DIGD: Delayed switch to the integrated graphics device.
626  * 	This will perform the switch once the last user space process has
627  * 	closed the device files of the GPUs and the audio client.
628  * * DDIS: Delayed switch to the discrete graphics device.
629  * * MIGD: Mux-only switch to the integrated graphics device.
630  * 	Does not remap console or change the power state of either gpu.
631  * 	If the integrated GPU is currently off, the screen will turn black.
632  * 	If it is on, the screen will show whatever happens to be in VRAM.
633  * 	Either way, the user has to blindly enter the command to switch back.
634  * * MDIS: Mux-only switch to the discrete graphics device.
635  *
636  * For GPUs whose power state is controlled by the driver's runtime pm,
637  * the ON and OFF commands are a no-op (see next section).
638  *
639  * For muxless machines, the IGD/DIS, DIGD/DDIS and MIGD/MDIS commands
640  * should not be used.
641  */
642 
643 #if 0  /* debugfs 1 */
644 static int
645 vga_switcheroo_show(struct seq_file *m, void *v)
646 {
647 	struct vga_switcheroo_client *client;
648 	int i = 0;
649 
650 	mutex_lock(&vgasr_mutex);
651 	list_for_each_entry(client, &vgasr_priv.clients, list) {
652 		seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
653 			   client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" :
654 								     "IGD",
655 			   client_is_vga(client) ? "" : "-Audio",
656 			   client->active ? '+' : ' ',
657 			   client->driver_power_control ? "Dyn" : "",
658 			   client->pwr_state ? "Pwr" : "Off",
659 			   pci_name(client->pdev));
660 		i++;
661 	}
662 	mutex_unlock(&vgasr_mutex);
663 	return 0;
664 }
665 
666 static int
667 vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
668 {
669 	return single_open(file, vga_switcheroo_show, NULL);
670 }
671 #endif /* debugfs 1 */
672 
673 static int
674 vga_switchon(struct vga_switcheroo_client *client)
675 {
676 	if (client->driver_power_control)
677 		return 0;
678 	if (vgasr_priv->handler->power_state)
679 		vgasr_priv->handler->power_state(client->id, VGA_SWITCHEROO_ON);
680 	/* call the driver callback to turn on device */
681 	client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
682 	client->pwr_state = VGA_SWITCHEROO_ON;
683 	return 0;
684 }
685 
686 static int
687 vga_switchoff(struct vga_switcheroo_client *client)
688 {
689 	if (client->driver_power_control)
690 		return 0;
691 	/* call the driver callback to turn off device */
692 	client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
693 	if (vgasr_priv->handler->power_state)
694 		vgasr_priv->handler->power_state(client->id, VGA_SWITCHEROO_OFF);
695 	client->pwr_state = VGA_SWITCHEROO_OFF;
696 	return 0;
697 }
698 
699 static void
700 set_audio_state(enum vga_switcheroo_client_id id,
701 			    enum vga_switcheroo_state state)
702 {
703 	struct vga_switcheroo_client *client;
704 
705 	client = find_client_from_id(&vgasr_priv->clients, id | ID_BIT_AUDIO);
706 	if (client && client->pwr_state != state) {
707 		client->ops->set_gpu_state(client->pdev, state);
708 		client->pwr_state = state;
709 	}
710 }
711 
712 /* stage one happens before delay */
713 static int
714 vga_switchto_stage1(struct vga_switcheroo_client *new_client)
715 {
716 	struct vga_switcheroo_client *active;
717 
718 	active = find_active_client(&vgasr_priv->clients);
719 	if (!active)
720 		return 0;
721 
722 	if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
723 		vga_switchon(new_client);
724 
725 	//XXX CRITICAL TODO:
726 	//vga_set_default_device(new_client->pdev);
727 
728 	return 0;
729 }
730 
731 /* post delay */
732 static int
733 vga_switchto_stage2(struct vga_switcheroo_client *new_client)
734 {
735 	int ret;
736 	struct vga_switcheroo_client *active;
737 
738 	active = find_active_client(&vgasr_priv->clients);
739 	if (!active)
740 		return 0;
741 
742 	active->active = false;
743 
744 	set_audio_state(active->id, VGA_SWITCHEROO_OFF);
745 
746 	/* XXX CRITICAL TODO: set new fb
747 
748 	if (new_client->fb_info) {
749 		struct fb_event event;
750 
751 		console_lock();
752 		event.info = new_client->fb_info;
753 		fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
754 		console_unlock();
755 	}
756 	*/
757 
758 	mutex_lock(&vgasr_priv->mux_hw_lk);
759 	ret = vgasr_priv->handler->switchto(new_client->id);
760 	mutex_unlock(&vgasr_priv->mux_hw_lk);
761 	if (ret)
762 		return ret;
763 
764 	if (new_client->ops->reprobe)
765 		new_client->ops->reprobe(new_client->pdev);
766 
767 	if (active->pwr_state == VGA_SWITCHEROO_ON)
768 		vga_switchoff(active);
769 
770 	set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
771 
772 	new_client->active = true;
773 	return 0;
774 }
775 
776 static bool
777 check_can_switch(void)
778 {
779 	struct vga_switcheroo_client *client;
780 
781 	list_for_each_entry(client, &vgasr_priv->clients, list) {
782 		if (!client->ops->can_switch(client->pdev)) {
783 			pr_err("client %x refused switch\n", client->id);
784 			return false;
785 		}
786 	}
787 	return true;
788 }
789 
790 #if 0  /* debugfs 2 */
791 static ssize_t
792 vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
793 			     size_t cnt, loff_t *ppos)
794 {
795 	char usercmd[64];
796 	int ret;
797 	bool delay = false, can_switch;
798 	bool just_mux = false;
799 	enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
800 	struct vga_switcheroo_client *client = NULL;
801 
802 	if (cnt > 63)
803 		cnt = 63;
804 
805 	if (copy_from_user(usercmd, ubuf, cnt))
806 		return -EFAULT;
807 
808 	mutex_lock(&vgasr_mutex);
809 
810 	if (!vgasr_priv.active) {
811 		cnt = -EINVAL;
812 		goto out;
813 	}
814 
815 	/* pwr off the device not in use */
816 	if (strncmp(usercmd, "OFF", 3) == 0) {
817 		list_for_each_entry(client, &vgasr_priv.clients, list) {
818 			if (client->active || client_is_audio(client))
819 				continue;
820 			if (client->driver_power_control)
821 				continue;
822 			set_audio_state(client->id, VGA_SWITCHEROO_OFF);
823 			if (client->pwr_state == VGA_SWITCHEROO_ON)
824 				vga_switchoff(client);
825 		}
826 		goto out;
827 	}
828 	/* pwr on the device not in use */
829 	if (strncmp(usercmd, "ON", 2) == 0) {
830 		list_for_each_entry(client, &vgasr_priv.clients, list) {
831 			if (client->active || client_is_audio(client))
832 				continue;
833 			if (client->driver_power_control)
834 				continue;
835 			if (client->pwr_state == VGA_SWITCHEROO_OFF)
836 				vga_switchon(client);
837 			set_audio_state(client->id, VGA_SWITCHEROO_ON);
838 		}
839 		goto out;
840 	}
841 
842 	/* request a delayed switch - test can we switch now */
843 	if (strncmp(usercmd, "DIGD", 4) == 0) {
844 		client_id = VGA_SWITCHEROO_IGD;
845 		delay = true;
846 	}
847 
848 	if (strncmp(usercmd, "DDIS", 4) == 0) {
849 		client_id = VGA_SWITCHEROO_DIS;
850 		delay = true;
851 	}
852 
853 	if (strncmp(usercmd, "IGD", 3) == 0)
854 		client_id = VGA_SWITCHEROO_IGD;
855 
856 	if (strncmp(usercmd, "DIS", 3) == 0)
857 		client_id = VGA_SWITCHEROO_DIS;
858 
859 	if (strncmp(usercmd, "MIGD", 4) == 0) {
860 		just_mux = true;
861 		client_id = VGA_SWITCHEROO_IGD;
862 	}
863 	if (strncmp(usercmd, "MDIS", 4) == 0) {
864 		just_mux = true;
865 		client_id = VGA_SWITCHEROO_DIS;
866 	}
867 
868 	if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)
869 		goto out;
870 	client = find_client_from_id(&vgasr_priv.clients, client_id);
871 	if (!client)
872 		goto out;
873 
874 	vgasr_priv.delayed_switch_active = false;
875 
876 	if (just_mux) {
877 		mutex_lock(&vgasr_priv.mux_hw_lock);
878 		ret = vgasr_priv.handler->switchto(client_id);
879 		mutex_unlock(&vgasr_priv.mux_hw_lock);
880 		goto out;
881 	}
882 
883 	if (client->active)
884 		goto out;
885 
886 	/* okay we want a switch - test if devices are willing to switch */
887 	can_switch = check_can_switch();
888 
889 	if (can_switch == false && delay == false)
890 		goto out;
891 
892 	if (can_switch) {
893 		ret = vga_switchto_stage1(client);
894 		if (ret)
895 			pr_err("switching failed stage 1 %d\n", ret);
896 
897 		ret = vga_switchto_stage2(client);
898 		if (ret)
899 			pr_err("switching failed stage 2 %d\n", ret);
900 
901 	} else {
902 		pr_info("setting delayed switch to client %d\n", client->id);
903 		vgasr_priv.delayed_switch_active = true;
904 		vgasr_priv.delayed_client_id = client_id;
905 
906 		ret = vga_switchto_stage1(client);
907 		if (ret)
908 			pr_err("delayed switching stage 1 failed %d\n", ret);
909 	}
910 
911 out:
912 	mutex_unlock(&vgasr_mutex);
913 	return cnt;
914 }
915 
916 #if 0  /* linux specific */
917 static const struct file_operations vga_switcheroo_debugfs_fops = {
918 	.owner = THIS_MODULE,
919 	.open = vga_switcheroo_debugfs_open,
920 	.write = vga_switcheroo_debugfs_write,
921 	.read = seq_read,
922 	.llseek = seq_lseek,
923 	.release = single_release,
924 };
925 #endif
926 
927 static void
928 vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
929 {
930 	debugfs_remove(priv->switch_file);
931 	priv->switch_file = NULL;
932 
933 	debugfs_remove(priv->debugfs_root);
934 	priv->debugfs_root = NULL;
935 }
936 
937 static int
938 vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
939 {
940 	static const char mp[] = "/sys/kernel/debug";
941 
942 	/* already initialised */
943 	if (priv->debugfs_root)
944 		return 0;
945 	priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
946 
947 	if (!priv->debugfs_root) {
948 		pr_err("Cannot create %s/vgaswitcheroo\n", mp);
949 		goto fail;
950 	}
951 
952 	priv->switch_file = debugfs_create_file("switch", 0644,
953 						priv->debugfs_root, NULL,
954 						&vga_switcheroo_debugfs_fops);
955 	if (!priv->switch_file) {
956 		pr_err("cannot create %s/vgaswitcheroo/switch\n", mp);
957 		goto fail;
958 	}
959 	return 0;
960 fail:
961 	vga_switcheroo_debugfs_fini(priv);
962 	return -1;
963 }
964 #endif  /* debugfs 2 */
965 
966 /*
967  * Device infrastructure
968  */
969 #define BUFFERSIZE 255
970 
971 static d_open_t      vga_switcheroo_open;
972 static d_close_t     vga_switcheroo_close;
973 static d_read_t      vga_switcheroo_read;
974 static d_write_t     vga_switcheroo_write;
975 
976 static struct dev_ops vga_switcheroo_ops = {
977 	{ "vga_switcheroo", 0, 0 },
978 	.d_open =	vga_switcheroo_open,
979 	.d_close =	vga_switcheroo_close,
980 	.d_read =	vga_switcheroo_read,
981 	.d_write =	vga_switcheroo_write,
982 };
983 
984 struct s_vga_switcheroo {
985 	char msg[BUFFERSIZE + 1];
986 	int len;
987 };
988 
989 static cdev_t vga_switcheroo_dev;
990 static struct s_vga_switcheroo *vga_switcheroo_buf;
991 
992 MALLOC_DECLARE(M_VGA_SWITCHEROO_BUF);
993 MALLOC_DEFINE(M_VGA_SWITCHEROO_BUF, "vga_switcheroo_buf", "buffer for vga_switcheroo");
994 MALLOC_DECLARE(M_VGA_SWITCHEROO_VGASR_PRIV);
995 MALLOC_DEFINE(M_VGA_SWITCHEROO_VGASR_PRIV, "vga_switcheroo_vgasr_priv", "private data of vga_switcheroo");
996 
997 static int
998 vga_switcheroo_handler(struct module *m __unused, int what, void *arg __unused)
999 {
1000 	int error = 0;
1001 
1002 	switch (what) {
1003 	case MOD_LOAD:                /* kldload */
1004 		vga_switcheroo_dev = make_dev(
1005 		    &vga_switcheroo_ops,
1006 		    0,
1007 		    UID_ROOT,
1008 		    GID_WHEEL,
1009 		    0600,
1010 		    "vga_switcheroo");
1011 		reference_dev(vga_switcheroo_dev);
1012 		if (error != 0)
1013 			break;
1014 
1015 		vga_switcheroo_buf = kmalloc(sizeof(*vga_switcheroo_buf), M_VGA_SWITCHEROO_BUF, M_WAITOK | M_ZERO);
1016 
1017 		//init vgasr_priv
1018 		vgasr_priv = kmalloc(sizeof(*vgasr_priv), M_VGA_SWITCHEROO_VGASR_PRIV, M_WAITOK | M_ZERO);
1019 		vgasr_priv->clients = (struct list_head) { &(vgasr_priv->clients), &(vgasr_priv->clients) };
1020 		lockinit(&vgasr_priv->mux_hw_lk, "mux_hw_lk", 0, LK_CANRECURSE);
1021 		kprintf("vga_switcheroo device loaded\n");
1022 		break;
1023 
1024 	case MOD_UNLOAD:
1025 	case MOD_SHUTDOWN:
1026 		destroy_dev(vga_switcheroo_dev);
1027 		kfree(vga_switcheroo_buf, M_VGA_SWITCHEROO_BUF);
1028 		kfree(vgasr_priv, M_VGA_SWITCHEROO_VGASR_PRIV);
1029 		kprintf("vga_switcheroo device unloaded\n");
1030 		break;
1031 
1032 	default:
1033 		error = EOPNOTSUPP;
1034 		break;
1035 	}
1036 
1037 	return (error);
1038 }
1039 
1040 static int
1041 vga_switcheroo_open(struct dev_open_args *ap)
1042 {
1043 	int error = 0;
1044 
1045 	return (error);
1046 }
1047 
1048 static int
1049 vga_switcheroo_close(struct dev_close_args *ap)
1050 {
1051 	return (0);
1052 }
1053 
1054 static int
1055 vga_switcheroo_read(struct dev_read_args *ap)
1056 {
1057 	struct vga_switcheroo_client *client;
1058 	int i = 0;
1059 
1060 	mutex_lock(&vgasr_mutex);
1061 	list_for_each_entry(client, &vgasr_priv->clients, list) {
1062 		uprintf("%d:%s%s:%c:%s%s:%s\n", i,
1063 			client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
1064 			client_is_vga(client) ? "" : "-Audio",
1065 			client->active ? '+' : ' ',
1066 			client->driver_power_control ? "Dyn" : "",
1067 			client->pwr_state ? "Pwr" : "Off",
1068 			device_get_nameunit(client->pdev->dev.bsddev));
1069 		i++;
1070 	}
1071 	mutex_unlock(&vgasr_mutex);
1072 	return 0;
1073 }
1074 
1075 static int
1076 vga_switcheroo_write(struct dev_write_args *ap)
1077 {
1078 	struct uio *uio = ap->a_uio;
1079 	size_t amt;
1080 	int error = 0;
1081 	int cnt;
1082 	int ret;
1083 	bool can_switch;
1084 	bool delay = false;
1085 	bool just_mux = false;
1086 	enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
1087 	struct vga_switcheroo_client *client = NULL;
1088 
1089 	/*
1090 	 * We either write from the beginning or are appending -- do
1091 	 * not allow random access.
1092 	 */
1093 	if (uio->uio_offset != 0 && (uio->uio_offset != vga_switcheroo_buf->len))
1094 		return (EINVAL);
1095 
1096 	/* This is a new message, reset length */
1097 	if (uio->uio_offset == 0)
1098 		vga_switcheroo_buf->len = 0;
1099 
1100 	/* Copy the string in from user memory to kernel memory */
1101 	amt = MIN(uio->uio_resid, (BUFFERSIZE - vga_switcheroo_buf->len));
1102 	cnt = amt;
1103 
1104 	error = uiomove(vga_switcheroo_buf->msg + uio->uio_offset, amt, uio);
1105 
1106 	vga_switcheroo_buf->len = uio->uio_offset;
1107 	vga_switcheroo_buf->msg[vga_switcheroo_buf->len] = 0;
1108 
1109 	if (error != 0)
1110 		uprintf("Write failed: bad address!\n");
1111 
1112 	mutex_lock(&vgasr_mutex);
1113 
1114 	if (!vgasr_priv->active) {
1115 		error = -EINVAL;
1116 		goto out;
1117 	}
1118 
1119 	/*
1120 	 * START PROCESSING COMMANDS
1121 	 */
1122 
1123 	/* pwr off the device not in use */
1124 	if (strncmp(vga_switcheroo_buf->msg, "OFF", 3) == 0) {
1125 		list_for_each_entry(client, &vgasr_priv->clients, list) {
1126 			if (client->active || client_is_audio(client))
1127 				continue;
1128 			if (client->driver_power_control)
1129 				continue;
1130 			set_audio_state(client->id, VGA_SWITCHEROO_OFF);
1131 			if (client->pwr_state == VGA_SWITCHEROO_ON)
1132 				vga_switchoff(client);
1133 		}
1134 		goto out;
1135 	}
1136 
1137 	/* pwr on the device not in use */
1138 	if (strncmp(vga_switcheroo_buf->msg, "ON", 2) == 0) {
1139 		list_for_each_entry(client, &vgasr_priv->clients, list) {
1140 			if (client->active || client_is_audio(client))
1141 				continue;
1142 			if (client->driver_power_control)
1143 				continue;
1144 			if (client->pwr_state == VGA_SWITCHEROO_OFF)
1145 				vga_switchon(client);
1146 			set_audio_state(client->id, VGA_SWITCHEROO_ON);
1147 		}
1148 		goto out;
1149 	}
1150 
1151 	/* request a delayed switch - test can we switch now */
1152 	if (strncmp(vga_switcheroo_buf->msg, "DIGD", 4) == 0) {
1153 		client_id = VGA_SWITCHEROO_IGD;
1154 		delay = true;
1155 	}
1156 
1157 	if (strncmp(vga_switcheroo_buf->msg, "DDIS", 4) == 0) {
1158 		client_id = VGA_SWITCHEROO_DIS;
1159 		delay = true;
1160 	}
1161 
1162 	if (strncmp(vga_switcheroo_buf->msg, "IGD", 3) == 0)
1163 		client_id = VGA_SWITCHEROO_IGD;
1164 
1165 	if (strncmp(vga_switcheroo_buf->msg, "DIS", 3) == 0)
1166 		client_id = VGA_SWITCHEROO_DIS;
1167 
1168 	if (strncmp(vga_switcheroo_buf->msg, "MIGD", 4) == 0) {
1169 		just_mux = true;
1170 		client_id = VGA_SWITCHEROO_IGD;
1171 	}
1172 
1173 	if (strncmp(vga_switcheroo_buf->msg, "MDIS", 4) == 0) {
1174 		just_mux = true;
1175 		client_id = VGA_SWITCHEROO_DIS;
1176 	}
1177 
1178 	if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)
1179 		goto out;
1180 	client = find_client_from_id(&vgasr_priv->clients, client_id);
1181 	if (!client)
1182 		goto out;
1183 
1184 	vgasr_priv->delayed_switch_active = false;
1185 
1186 	if (just_mux) {
1187 		mutex_lock(&vgasr_priv->mux_hw_lk);
1188 		ret = vgasr_priv->handler->switchto(client_id);
1189 		mutex_unlock(&vgasr_priv->mux_hw_lk);
1190 		goto out;
1191 	}
1192 
1193 	if (client->active)
1194 		goto out;
1195 
1196 	/* okay we want a switch - test if devices are willing to switch */
1197 	can_switch = check_can_switch();
1198 
1199 	if (can_switch == false && delay == false)
1200 		goto out;
1201 
1202 	if (can_switch) {
1203 		ret = vga_switchto_stage1(client);
1204 		if (ret)
1205 			pr_err("switching failed stage 1 %d\n", ret);
1206 
1207 		ret = vga_switchto_stage2(client);
1208 		if (ret)
1209 			pr_err("switching failed stage 2 %d\n", ret);
1210 
1211 	} else {
1212 		pr_info("setting delayed switch to client %d\n", client->id);
1213 		vgasr_priv->delayed_switch_active = true;
1214 		vgasr_priv->delayed_client_id = client_id;
1215 
1216 		ret = vga_switchto_stage1(client);
1217 		if (ret)
1218 			pr_err("delayed switching stage 1 failed %d\n", ret);
1219 	}
1220 
1221 out:
1222 	mutex_unlock(&vgasr_mutex);
1223 	return (error);
1224 }
1225 
1226 #ifdef __DragonFly__
1227 int
1228 vga_switcheroo_force_migd(void)
1229 {
1230 	enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_IGD;
1231 	int ret;
1232 
1233 	mutex_lock(&vgasr_priv->mux_hw_lk);
1234 	ret = vgasr_priv->handler->switchto(client_id);
1235 	mutex_unlock(&vgasr_priv->mux_hw_lk);
1236 	if (ret)
1237 		pr_err("failed to switch gmux to IGD\n");
1238 
1239 	return (ret);
1240 }
1241 #endif
1242 
1243 MODULE_VERSION(vga_switcheroo, 1);
1244 DEV_MODULE(vga_switcheroo, vga_switcheroo_handler, NULL);
1245 
1246 /**
1247  * vga_switcheroo_process_delayed_switch() - helper for delayed switching
1248  *
1249  * Process a delayed switch if one is pending. DRM drivers should call this
1250  * from their ->lastclose callback.
1251  *
1252  * Return: 0 on success. -EINVAL if no delayed switch is pending, if the client
1253  * has unregistered in the meantime or if there are other clients blocking the
1254  * switch. If the actual switch fails, an error is reported and 0 is returned.
1255  */
1256 int
1257 vga_switcheroo_process_delayed_switch(void)
1258 {
1259 	struct vga_switcheroo_client *client;
1260 	int ret;
1261 	int err = -EINVAL;
1262 
1263 	mutex_lock(&vgasr_mutex);
1264 	if (!vgasr_priv->delayed_switch_active)
1265 		goto err;
1266 
1267 	pr_info("processing delayed switch to %d\n",
1268 		vgasr_priv->delayed_client_id);
1269 
1270 	client = find_client_from_id(&vgasr_priv->clients,
1271 				     vgasr_priv->delayed_client_id);
1272 	if (!client || !check_can_switch())
1273 		goto err;
1274 
1275 	ret = vga_switchto_stage2(client);
1276 	if (ret)
1277 		pr_err("delayed switching failed stage 2 %d\n", ret);
1278 
1279 	vgasr_priv->delayed_switch_active = false;
1280 	err = 0;
1281 err:
1282 	mutex_unlock(&vgasr_mutex);
1283 	return err;
1284 }
1285 EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
1286 
1287 /**
1288  * DOC: Driver power control
1289  *
1290  * In this mode of use, the discrete GPU automatically powers up and down at
1291  * the discretion of the driver's runtime pm. On muxed machines, the user may
1292  * still influence the muxer state by way of the debugfs interface, however
1293  * the ON and OFF commands become a no-op for the discrete GPU.
1294  *
1295  * This mode is the default on Nvidia HybridPower/Optimus and ATI PowerXpress.
1296  * Specifying nouveau.runpm=0, radeon.runpm=0 or amdgpu.runpm=0 on the kernel
1297  * command line disables it.
1298  *
1299  * When the driver decides to power up or down, it notifies vga_switcheroo
1300  * thereof so that it can (a) power the audio device on the GPU up or down,
1301  * and (b) update its internal power state representation for the device.
1302  * This is achieved by vga_switcheroo_set_dynamic_switch().
1303  *
1304  * After the GPU has been suspended, the handler needs to be called to cut
1305  * power to the GPU. Likewise it needs to reinstate power before the GPU
1306  * can resume. This is achieved by vga_switcheroo_init_domain_pm_ops(),
1307  * which augments the GPU's suspend/resume functions by the requisite
1308  * calls to the handler.
1309  *
1310  * When the audio device resumes, the GPU needs to be woken. This is achieved
1311  * by vga_switcheroo_init_domain_pm_optimus_hdmi_audio(), which augments the
1312  * audio device's resume function.
1313  *
1314  * On muxed machines, if the mux is initially switched to the discrete GPU,
1315  * the user ends up with a black screen when the GPU powers down after boot.
1316  * As a workaround, the mux is forced to the integrated GPU on runtime suspend,
1317  * cf. https://bugs.freedesktop.org/show_bug.cgi?id=75917
1318  */
1319 
1320 #if 0  /* used in: runtime_suspend/resume() */
1321 static void
1322 vga_switcheroo_power_switch(struct pci_dev *pdev,
1323 					enum vga_switcheroo_state state)
1324 {
1325 	struct vga_switcheroo_client *client;
1326 
1327 	if (!vgasr_priv->handler->power_state)
1328 		return;
1329 
1330 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
1331 	if (!client)
1332 		return;
1333 
1334 	if (!client->driver_power_control)
1335 		return;
1336 
1337 	vgasr_priv->handler->power_state(client->id, state);
1338 }
1339 #endif  /* used in: runtime_suspend/resume() */
1340 
1341 /**
1342  * vga_switcheroo_set_dynamic_switch() - helper for driver power control
1343  * @pdev: client pci device
1344  * @dynamic: new power state
1345  *
1346  * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1347  * When the driver decides to power up or down, it notifies vga_switcheroo
1348  * thereof using this helper so that it can (a) power the audio device on
1349  * the GPU up or down, and (b) update its internal power state representation
1350  * for the device.
1351  */
1352 #if 0  /* TODO: no dynamic_switch yet */
1353 void
1354 vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev,
1355 				       enum vga_switcheroo_state dynamic)
1356 {
1357 	struct vga_switcheroo_client *client;
1358 
1359 	mutex_lock(&vgasr_mutex);
1360 	client = find_client_from_pci(&vgasr_priv.clients, pdev);
1361 	if (!client || !client->driver_power_control) {
1362 		mutex_unlock(&vgasr_mutex);
1363 		return;
1364 	}
1365 
1366 	client->pwr_state = dynamic;
1367 	set_audio_state(client->id, dynamic);
1368 	mutex_unlock(&vgasr_mutex);
1369 }
1370 EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
1371 
1372 /* switcheroo power domain */
1373 static int
1374 vga_switcheroo_runtime_suspend(struct device *dev)
1375 {
1376 	struct pci_dev *pdev = to_pci_dev(dev);
1377 	int ret;
1378 
1379 	ret = dev->bus->pm->runtime_suspend(dev);
1380 	if (ret)
1381 		return ret;
1382 	mutex_lock(&vgasr_mutex);
1383 	if (vgasr_priv.handler->switchto) {
1384 		mutex_lock(&vgasr_priv.mux_hw_lock);
1385 		vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
1386 		mutex_unlock(&vgasr_priv.mux_hw_lock);
1387 	}
1388 	vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
1389 	mutex_unlock(&vgasr_mutex);
1390 	return 0;
1391 }
1392 
1393 static int
1394 vga_switcheroo_runtime_resume(struct device *dev)
1395 {
1396 	struct pci_dev *pdev = to_pci_dev(dev);
1397 	int ret;
1398 
1399 	mutex_lock(&vgasr_mutex);
1400 	vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
1401 	mutex_unlock(&vgasr_mutex);
1402 	ret = dev->bus->pm->runtime_resume(dev);
1403 	if (ret)
1404 		return ret;
1405 
1406 	return 0;
1407 }
1408 #endif  /* TODO: no dynamic_switch yet */
1409 
1410 /**
1411  * vga_switcheroo_init_domain_pm_ops() - helper for driver power control
1412  * @dev: vga client device
1413  * @domain: power domain
1414  *
1415  * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1416  * After the GPU has been suspended, the handler needs to be called to cut
1417  * power to the GPU. Likewise it needs to reinstate power before the GPU
1418  * can resume. To this end, this helper augments the suspend/resume functions
1419  * by the requisite calls to the handler. It needs only be called on platforms
1420  * where the power switch is separate to the device being powered down.
1421  */
1422 #if 0 /* TODO: no pm_ops */
1423 int
1424 vga_switcheroo_init_domain_pm_ops(struct device *dev,
1425 				      struct dev_pm_domain *domain)
1426 {
1427 	/* copy over all the bus versions */
1428 	if (dev->bus && dev->bus->pm) {
1429 		domain->ops = *dev->bus->pm;
1430 		domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
1431 		domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
1432 
1433 		dev_pm_domain_set(dev, domain);
1434 		return 0;
1435 	}
1436 	dev_pm_domain_set(dev, NULL);
1437 	return -EINVAL;
1438 }
1439 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
1440 
1441 void
1442 vga_switcheroo_fini_domain_pm_ops(struct device *dev)
1443 {
1444 	dev_pm_domain_set(dev, NULL);
1445 }
1446 EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
1447 
1448 static int
1449 vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
1450 {
1451 	struct pci_dev *pdev = to_pci_dev(dev);
1452 	struct vga_switcheroo_client *client;
1453 	struct device *video_dev = NULL;
1454 	int ret;
1455 
1456 	/* we need to check if we have to switch back on the video
1457 	   device so the audio device can come back */
1458 	mutex_lock(&vgasr_mutex);
1459 	list_for_each_entry(client, &vgasr_priv.clients, list) {
1460 		if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
1461 		    client_is_vga(client)) {
1462 			video_dev = &client->pdev->dev;
1463 			break;
1464 		}
1465 	}
1466 	mutex_unlock(&vgasr_mutex);
1467 
1468 	if (video_dev) {
1469 		ret = pm_runtime_get_sync(video_dev);
1470 		if (ret && ret != 1)
1471 			return ret;
1472 	}
1473 	ret = dev->bus->pm->runtime_resume(dev);
1474 
1475 	/* put the reference for the gpu */
1476 	if (video_dev) {
1477 		pm_runtime_mark_last_busy(video_dev);
1478 		pm_runtime_put_autosuspend(video_dev);
1479 	}
1480 	return ret;
1481 }
1482 #endif  /* TODO: no pm_ops */
1483 
1484 /**
1485  * vga_switcheroo_init_domain_pm_optimus_hdmi_audio() - helper for driver
1486  * 	power control
1487  * @dev: audio client device
1488  * @domain: power domain
1489  *
1490  * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1491  * When the audio device resumes, the GPU needs to be woken. This helper
1492  * augments the audio device's resume function to do that.
1493  *
1494  * Return: 0 on success, -EINVAL if no power management operations are
1495  * defined for this device.
1496  */
1497 #if 0  /* TODO: no pm */
1498 int
1499 vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
1500 						 struct dev_pm_domain *domain)
1501 {
1502 	/* copy over all the bus versions */
1503 	if (dev->bus && dev->bus->pm) {
1504 		domain->ops = *dev->bus->pm;
1505 		domain->ops.runtime_resume =
1506 			vga_switcheroo_runtime_resume_hdmi_audio;
1507 
1508 		dev_pm_domain_set(dev, domain);
1509 		return 0;
1510 	}
1511 	dev_pm_domain_set(dev, NULL);
1512 	return -EINVAL;
1513 }
1514 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
1515 #endif /* TODO: no pm */
1516