xref: /openbmc/linux/drivers/gpu/vga/vga_switcheroo.c (revision 4f38b9f2)
1 /*
2  * Copyright (c) 2010 Red Hat Inc.
3  * Author : Dave Airlie <airlied@redhat.com>
4  *
5  *
6  * Licensed under GPLv2
7  *
8  * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
9  *
10  * Switcher interface - methods require for ATPX and DCM
11  * - switchto - this throws the output MUX switch
12  * - discrete_set_power - sets the power state for the discrete card
13  *
14  * GPU driver interface
15  * - set_gpu_state - this should do the equiv of s/r for the card
16  *                 - this should *not* set the discrete power state
17  * - switch_check  - check if the device is in a position to switch now
18  */
19 
20 #define pr_fmt(fmt) "vga_switcheroo: " fmt
21 
22 #include <linux/module.h>
23 #include <linux/seq_file.h>
24 #include <linux/uaccess.h>
25 #include <linux/fs.h>
26 #include <linux/debugfs.h>
27 #include <linux/fb.h>
28 
29 #include <linux/pci.h>
30 #include <linux/console.h>
31 #include <linux/vga_switcheroo.h>
32 #include <linux/pm_runtime.h>
33 
34 #include <linux/vgaarb.h>
35 
36 struct vga_switcheroo_client {
37 	struct pci_dev *pdev;
38 	struct fb_info *fb_info;
39 	int pwr_state;
40 	const struct vga_switcheroo_client_ops *ops;
41 	int id;
42 	bool active;
43 	bool driver_power_control;
44 	struct list_head list;
45 };
46 
47 static DEFINE_MUTEX(vgasr_mutex);
48 
49 struct vgasr_priv {
50 
51 	bool active;
52 	bool delayed_switch_active;
53 	enum vga_switcheroo_client_id delayed_client_id;
54 
55 	struct dentry *debugfs_root;
56 	struct dentry *switch_file;
57 
58 	int registered_clients;
59 	struct list_head clients;
60 
61 	struct vga_switcheroo_handler *handler;
62 };
63 
64 #define ID_BIT_AUDIO		0x100
65 #define client_is_audio(c)	((c)->id & ID_BIT_AUDIO)
66 #define client_is_vga(c)	((c)->id == -1 || !client_is_audio(c))
67 #define client_id(c)		((c)->id & ~ID_BIT_AUDIO)
68 
69 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
70 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
71 
72 /* only one switcheroo per system */
73 static struct vgasr_priv vgasr_priv = {
74 	.clients = LIST_HEAD_INIT(vgasr_priv.clients),
75 };
76 
77 static bool vga_switcheroo_ready(void)
78 {
79 	/* we're ready if we get two clients + handler */
80 	return !vgasr_priv.active &&
81 	       vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
82 }
83 
84 static void vga_switcheroo_enable(void)
85 {
86 	int ret;
87 	struct vga_switcheroo_client *client;
88 
89 	/* call the handler to init */
90 	if (vgasr_priv.handler->init)
91 		vgasr_priv.handler->init();
92 
93 	list_for_each_entry(client, &vgasr_priv.clients, list) {
94 		if (client->id != -1)
95 			continue;
96 		ret = vgasr_priv.handler->get_client_id(client->pdev);
97 		if (ret < 0)
98 			return;
99 
100 		client->id = ret;
101 	}
102 	vga_switcheroo_debugfs_init(&vgasr_priv);
103 	vgasr_priv.active = true;
104 }
105 
106 int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler)
107 {
108 	mutex_lock(&vgasr_mutex);
109 	if (vgasr_priv.handler) {
110 		mutex_unlock(&vgasr_mutex);
111 		return -EINVAL;
112 	}
113 
114 	vgasr_priv.handler = handler;
115 	if (vga_switcheroo_ready()) {
116 		pr_info("enabled\n");
117 		vga_switcheroo_enable();
118 	}
119 	mutex_unlock(&vgasr_mutex);
120 	return 0;
121 }
122 EXPORT_SYMBOL(vga_switcheroo_register_handler);
123 
124 void vga_switcheroo_unregister_handler(void)
125 {
126 	mutex_lock(&vgasr_mutex);
127 	vgasr_priv.handler = NULL;
128 	if (vgasr_priv.active) {
129 		pr_info("disabled\n");
130 		vga_switcheroo_debugfs_fini(&vgasr_priv);
131 		vgasr_priv.active = false;
132 	}
133 	mutex_unlock(&vgasr_mutex);
134 }
135 EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
136 
137 static int register_client(struct pci_dev *pdev,
138 			   const struct vga_switcheroo_client_ops *ops,
139 			   int id, bool active, bool driver_power_control)
140 {
141 	struct vga_switcheroo_client *client;
142 
143 	client = kzalloc(sizeof(*client), GFP_KERNEL);
144 	if (!client)
145 		return -ENOMEM;
146 
147 	client->pwr_state = VGA_SWITCHEROO_ON;
148 	client->pdev = pdev;
149 	client->ops = ops;
150 	client->id = id;
151 	client->active = active;
152 	client->driver_power_control = driver_power_control;
153 
154 	mutex_lock(&vgasr_mutex);
155 	list_add_tail(&client->list, &vgasr_priv.clients);
156 	if (client_is_vga(client))
157 		vgasr_priv.registered_clients++;
158 
159 	if (vga_switcheroo_ready()) {
160 		pr_info("enabled\n");
161 		vga_switcheroo_enable();
162 	}
163 	mutex_unlock(&vgasr_mutex);
164 	return 0;
165 }
166 
167 int vga_switcheroo_register_client(struct pci_dev *pdev,
168 				   const struct vga_switcheroo_client_ops *ops,
169 				   bool driver_power_control)
170 {
171 	return register_client(pdev, ops, -1,
172 			       pdev == vga_default_device(),
173 			       driver_power_control);
174 }
175 EXPORT_SYMBOL(vga_switcheroo_register_client);
176 
177 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
178 					 const struct vga_switcheroo_client_ops *ops,
179 					 int id, bool active)
180 {
181 	return register_client(pdev, ops, id | ID_BIT_AUDIO, active, false);
182 }
183 EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
184 
185 static struct vga_switcheroo_client *
186 find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
187 {
188 	struct vga_switcheroo_client *client;
189 
190 	list_for_each_entry(client, head, list)
191 		if (client->pdev == pdev)
192 			return client;
193 	return NULL;
194 }
195 
196 static struct vga_switcheroo_client *
197 find_client_from_id(struct list_head *head, int client_id)
198 {
199 	struct vga_switcheroo_client *client;
200 
201 	list_for_each_entry(client, head, list)
202 		if (client->id == client_id)
203 			return client;
204 	return NULL;
205 }
206 
207 static struct vga_switcheroo_client *
208 find_active_client(struct list_head *head)
209 {
210 	struct vga_switcheroo_client *client;
211 
212 	list_for_each_entry(client, head, list)
213 		if (client->active && client_is_vga(client))
214 			return client;
215 	return NULL;
216 }
217 
218 int vga_switcheroo_get_client_state(struct pci_dev *pdev)
219 {
220 	struct vga_switcheroo_client *client;
221 
222 	client = find_client_from_pci(&vgasr_priv.clients, pdev);
223 	if (!client)
224 		return VGA_SWITCHEROO_NOT_FOUND;
225 	if (!vgasr_priv.active)
226 		return VGA_SWITCHEROO_INIT;
227 	return client->pwr_state;
228 }
229 EXPORT_SYMBOL(vga_switcheroo_get_client_state);
230 
231 void vga_switcheroo_unregister_client(struct pci_dev *pdev)
232 {
233 	struct vga_switcheroo_client *client;
234 
235 	mutex_lock(&vgasr_mutex);
236 	client = find_client_from_pci(&vgasr_priv.clients, pdev);
237 	if (client) {
238 		if (client_is_vga(client))
239 			vgasr_priv.registered_clients--;
240 		list_del(&client->list);
241 		kfree(client);
242 	}
243 	if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
244 		pr_info("disabled\n");
245 		vga_switcheroo_debugfs_fini(&vgasr_priv);
246 		vgasr_priv.active = false;
247 	}
248 	mutex_unlock(&vgasr_mutex);
249 }
250 EXPORT_SYMBOL(vga_switcheroo_unregister_client);
251 
252 void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
253 				 struct fb_info *info)
254 {
255 	struct vga_switcheroo_client *client;
256 
257 	mutex_lock(&vgasr_mutex);
258 	client = find_client_from_pci(&vgasr_priv.clients, pdev);
259 	if (client)
260 		client->fb_info = info;
261 	mutex_unlock(&vgasr_mutex);
262 }
263 EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
264 
265 static int vga_switcheroo_show(struct seq_file *m, void *v)
266 {
267 	struct vga_switcheroo_client *client;
268 	int i = 0;
269 
270 	mutex_lock(&vgasr_mutex);
271 	list_for_each_entry(client, &vgasr_priv.clients, list) {
272 		seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
273 			   client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" :
274 								     "IGD",
275 			   client_is_vga(client) ? "" : "-Audio",
276 			   client->active ? '+' : ' ',
277 			   client->driver_power_control ? "Dyn" : "",
278 			   client->pwr_state ? "Pwr" : "Off",
279 			   pci_name(client->pdev));
280 		i++;
281 	}
282 	mutex_unlock(&vgasr_mutex);
283 	return 0;
284 }
285 
286 static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
287 {
288 	return single_open(file, vga_switcheroo_show, NULL);
289 }
290 
291 static int vga_switchon(struct vga_switcheroo_client *client)
292 {
293 	if (client->driver_power_control)
294 		return 0;
295 	if (vgasr_priv.handler->power_state)
296 		vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
297 	/* call the driver callback to turn on device */
298 	client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
299 	client->pwr_state = VGA_SWITCHEROO_ON;
300 	return 0;
301 }
302 
303 static int vga_switchoff(struct vga_switcheroo_client *client)
304 {
305 	if (client->driver_power_control)
306 		return 0;
307 	/* call the driver callback to turn off device */
308 	client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
309 	if (vgasr_priv.handler->power_state)
310 		vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
311 	client->pwr_state = VGA_SWITCHEROO_OFF;
312 	return 0;
313 }
314 
315 static void set_audio_state(int id, int state)
316 {
317 	struct vga_switcheroo_client *client;
318 
319 	client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
320 	if (client && client->pwr_state != state) {
321 		client->ops->set_gpu_state(client->pdev, state);
322 		client->pwr_state = state;
323 	}
324 }
325 
326 /* stage one happens before delay */
327 static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
328 {
329 	struct vga_switcheroo_client *active;
330 
331 	active = find_active_client(&vgasr_priv.clients);
332 	if (!active)
333 		return 0;
334 
335 	if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
336 		vga_switchon(new_client);
337 
338 	vga_set_default_device(new_client->pdev);
339 	return 0;
340 }
341 
342 /* post delay */
343 static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
344 {
345 	int ret;
346 	struct vga_switcheroo_client *active;
347 
348 	active = find_active_client(&vgasr_priv.clients);
349 	if (!active)
350 		return 0;
351 
352 	active->active = false;
353 
354 	set_audio_state(active->id, VGA_SWITCHEROO_OFF);
355 
356 	if (new_client->fb_info) {
357 		struct fb_event event;
358 
359 		console_lock();
360 		event.info = new_client->fb_info;
361 		fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
362 		console_unlock();
363 	}
364 
365 	ret = vgasr_priv.handler->switchto(new_client->id);
366 	if (ret)
367 		return ret;
368 
369 	if (new_client->ops->reprobe)
370 		new_client->ops->reprobe(new_client->pdev);
371 
372 	if (active->pwr_state == VGA_SWITCHEROO_ON)
373 		vga_switchoff(active);
374 
375 	set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
376 
377 	new_client->active = true;
378 	return 0;
379 }
380 
381 static bool check_can_switch(void)
382 {
383 	struct vga_switcheroo_client *client;
384 
385 	list_for_each_entry(client, &vgasr_priv.clients, list) {
386 		if (!client->ops->can_switch(client->pdev)) {
387 			pr_err("client %x refused switch\n", client->id);
388 			return false;
389 		}
390 	}
391 	return true;
392 }
393 
394 static ssize_t
395 vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
396 			     size_t cnt, loff_t *ppos)
397 {
398 	char usercmd[64];
399 	int ret;
400 	bool delay = false, can_switch;
401 	bool just_mux = false;
402 	int client_id = -1;
403 	struct vga_switcheroo_client *client = NULL;
404 
405 	if (cnt > 63)
406 		cnt = 63;
407 
408 	if (copy_from_user(usercmd, ubuf, cnt))
409 		return -EFAULT;
410 
411 	mutex_lock(&vgasr_mutex);
412 
413 	if (!vgasr_priv.active) {
414 		cnt = -EINVAL;
415 		goto out;
416 	}
417 
418 	/* pwr off the device not in use */
419 	if (strncmp(usercmd, "OFF", 3) == 0) {
420 		list_for_each_entry(client, &vgasr_priv.clients, list) {
421 			if (client->active || client_is_audio(client))
422 				continue;
423 			if (client->driver_power_control)
424 				continue;
425 			set_audio_state(client->id, VGA_SWITCHEROO_OFF);
426 			if (client->pwr_state == VGA_SWITCHEROO_ON)
427 				vga_switchoff(client);
428 		}
429 		goto out;
430 	}
431 	/* pwr on the device not in use */
432 	if (strncmp(usercmd, "ON", 2) == 0) {
433 		list_for_each_entry(client, &vgasr_priv.clients, list) {
434 			if (client->active || client_is_audio(client))
435 				continue;
436 			if (client->driver_power_control)
437 				continue;
438 			if (client->pwr_state == VGA_SWITCHEROO_OFF)
439 				vga_switchon(client);
440 			set_audio_state(client->id, VGA_SWITCHEROO_ON);
441 		}
442 		goto out;
443 	}
444 
445 	/* request a delayed switch - test can we switch now */
446 	if (strncmp(usercmd, "DIGD", 4) == 0) {
447 		client_id = VGA_SWITCHEROO_IGD;
448 		delay = true;
449 	}
450 
451 	if (strncmp(usercmd, "DDIS", 4) == 0) {
452 		client_id = VGA_SWITCHEROO_DIS;
453 		delay = true;
454 	}
455 
456 	if (strncmp(usercmd, "IGD", 3) == 0)
457 		client_id = VGA_SWITCHEROO_IGD;
458 
459 	if (strncmp(usercmd, "DIS", 3) == 0)
460 		client_id = VGA_SWITCHEROO_DIS;
461 
462 	if (strncmp(usercmd, "MIGD", 4) == 0) {
463 		just_mux = true;
464 		client_id = VGA_SWITCHEROO_IGD;
465 	}
466 	if (strncmp(usercmd, "MDIS", 4) == 0) {
467 		just_mux = true;
468 		client_id = VGA_SWITCHEROO_DIS;
469 	}
470 
471 	if (client_id == -1)
472 		goto out;
473 	client = find_client_from_id(&vgasr_priv.clients, client_id);
474 	if (!client)
475 		goto out;
476 
477 	vgasr_priv.delayed_switch_active = false;
478 
479 	if (just_mux) {
480 		ret = vgasr_priv.handler->switchto(client_id);
481 		goto out;
482 	}
483 
484 	if (client->active)
485 		goto out;
486 
487 	/* okay we want a switch - test if devices are willing to switch */
488 	can_switch = check_can_switch();
489 
490 	if (can_switch == false && delay == false)
491 		goto out;
492 
493 	if (can_switch) {
494 		ret = vga_switchto_stage1(client);
495 		if (ret)
496 			pr_err("switching failed stage 1 %d\n", ret);
497 
498 		ret = vga_switchto_stage2(client);
499 		if (ret)
500 			pr_err("switching failed stage 2 %d\n", ret);
501 
502 	} else {
503 		pr_info("setting delayed switch to client %d\n", client->id);
504 		vgasr_priv.delayed_switch_active = true;
505 		vgasr_priv.delayed_client_id = client_id;
506 
507 		ret = vga_switchto_stage1(client);
508 		if (ret)
509 			pr_err("delayed switching stage 1 failed %d\n", ret);
510 	}
511 
512 out:
513 	mutex_unlock(&vgasr_mutex);
514 	return cnt;
515 }
516 
517 static const struct file_operations vga_switcheroo_debugfs_fops = {
518 	.owner = THIS_MODULE,
519 	.open = vga_switcheroo_debugfs_open,
520 	.write = vga_switcheroo_debugfs_write,
521 	.read = seq_read,
522 	.llseek = seq_lseek,
523 	.release = single_release,
524 };
525 
526 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
527 {
528 	debugfs_remove(priv->switch_file);
529 	priv->switch_file = NULL;
530 
531 	debugfs_remove(priv->debugfs_root);
532 	priv->debugfs_root = NULL;
533 }
534 
535 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
536 {
537 	static const char mp[] = "/sys/kernel/debug";
538 
539 	/* already initialised */
540 	if (priv->debugfs_root)
541 		return 0;
542 	priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
543 
544 	if (!priv->debugfs_root) {
545 		pr_err("Cannot create %s/vgaswitcheroo\n", mp);
546 		goto fail;
547 	}
548 
549 	priv->switch_file = debugfs_create_file("switch", 0644,
550 						priv->debugfs_root, NULL,
551 						&vga_switcheroo_debugfs_fops);
552 	if (!priv->switch_file) {
553 		pr_err("cannot create %s/vgaswitcheroo/switch\n", mp);
554 		goto fail;
555 	}
556 	return 0;
557 fail:
558 	vga_switcheroo_debugfs_fini(priv);
559 	return -1;
560 }
561 
562 int vga_switcheroo_process_delayed_switch(void)
563 {
564 	struct vga_switcheroo_client *client;
565 	int ret;
566 	int err = -EINVAL;
567 
568 	mutex_lock(&vgasr_mutex);
569 	if (!vgasr_priv.delayed_switch_active)
570 		goto err;
571 
572 	pr_info("processing delayed switch to %d\n",
573 		vgasr_priv.delayed_client_id);
574 
575 	client = find_client_from_id(&vgasr_priv.clients,
576 				     vgasr_priv.delayed_client_id);
577 	if (!client || !check_can_switch())
578 		goto err;
579 
580 	ret = vga_switchto_stage2(client);
581 	if (ret)
582 		pr_err("delayed switching failed stage 2 %d\n", ret);
583 
584 	vgasr_priv.delayed_switch_active = false;
585 	err = 0;
586 err:
587 	mutex_unlock(&vgasr_mutex);
588 	return err;
589 }
590 EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
591 
592 static void vga_switcheroo_power_switch(struct pci_dev *pdev,
593 					enum vga_switcheroo_state state)
594 {
595 	struct vga_switcheroo_client *client;
596 
597 	if (!vgasr_priv.handler->power_state)
598 		return;
599 
600 	client = find_client_from_pci(&vgasr_priv.clients, pdev);
601 	if (!client)
602 		return;
603 
604 	if (!client->driver_power_control)
605 		return;
606 
607 	vgasr_priv.handler->power_state(client->id, state);
608 }
609 
610 /* force a PCI device to a certain state - mainly to turn off audio clients */
611 
612 void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev,
613 				       enum vga_switcheroo_state dynamic)
614 {
615 	struct vga_switcheroo_client *client;
616 
617 	client = find_client_from_pci(&vgasr_priv.clients, pdev);
618 	if (!client)
619 		return;
620 
621 	if (!client->driver_power_control)
622 		return;
623 
624 	client->pwr_state = dynamic;
625 	set_audio_state(client->id, dynamic);
626 }
627 EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
628 
629 /* switcheroo power domain */
630 static int vga_switcheroo_runtime_suspend(struct device *dev)
631 {
632 	struct pci_dev *pdev = to_pci_dev(dev);
633 	int ret;
634 
635 	ret = dev->bus->pm->runtime_suspend(dev);
636 	if (ret)
637 		return ret;
638 	if (vgasr_priv.handler->switchto)
639 		vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
640 	vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
641 	return 0;
642 }
643 
644 static int vga_switcheroo_runtime_resume(struct device *dev)
645 {
646 	struct pci_dev *pdev = to_pci_dev(dev);
647 	int ret;
648 
649 	vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
650 	ret = dev->bus->pm->runtime_resume(dev);
651 	if (ret)
652 		return ret;
653 
654 	return 0;
655 }
656 
657 /* this version is for the case where the power switch is separate
658    to the device being powered down. */
659 int vga_switcheroo_init_domain_pm_ops(struct device *dev,
660 				      struct dev_pm_domain *domain)
661 {
662 	/* copy over all the bus versions */
663 	if (dev->bus && dev->bus->pm) {
664 		domain->ops = *dev->bus->pm;
665 		domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
666 		domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
667 
668 		dev->pm_domain = domain;
669 		return 0;
670 	}
671 	dev->pm_domain = NULL;
672 	return -EINVAL;
673 }
674 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
675 
676 void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
677 {
678 	dev->pm_domain = NULL;
679 }
680 EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
681 
682 static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
683 {
684 	struct pci_dev *pdev = to_pci_dev(dev);
685 	int ret;
686 	struct vga_switcheroo_client *client, *found = NULL;
687 
688 	/* we need to check if we have to switch back on the video
689 	   device so the audio device can come back */
690 	list_for_each_entry(client, &vgasr_priv.clients, list) {
691 		if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
692 		    client_is_vga(client)) {
693 			found = client;
694 			ret = pm_runtime_get_sync(&client->pdev->dev);
695 			if (ret) {
696 				if (ret != 1)
697 					return ret;
698 			}
699 			break;
700 		}
701 	}
702 	ret = dev->bus->pm->runtime_resume(dev);
703 
704 	/* put the reference for the gpu */
705 	if (found) {
706 		pm_runtime_mark_last_busy(&found->pdev->dev);
707 		pm_runtime_put_autosuspend(&found->pdev->dev);
708 	}
709 	return ret;
710 }
711 
712 int
713 vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
714 						 struct dev_pm_domain *domain)
715 {
716 	/* copy over all the bus versions */
717 	if (dev->bus && dev->bus->pm) {
718 		domain->ops = *dev->bus->pm;
719 		domain->ops.runtime_resume =
720 			vga_switcheroo_runtime_resume_hdmi_audio;
721 
722 		dev->pm_domain = domain;
723 		return 0;
724 	}
725 	dev->pm_domain = NULL;
726 	return -EINVAL;
727 }
728 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
729