1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#define pr_fmt(fmt) "vga_switcheroo: " fmt
32
33#include <linux/console.h>
34#include <linux/debugfs.h>
35#include <linux/fb.h>
36#include <linux/fs.h>
37#include <linux/module.h>
38#include <linux/pci.h>
39#include <linux/pm_domain.h>
40#include <linux/pm_runtime.h>
41#include <linux/seq_file.h>
42#include <linux/uaccess.h>
43#include <linux/vgaarb.h>
44#include <linux/vga_switcheroo.h>
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109struct vga_switcheroo_client {
110 struct pci_dev *pdev;
111 struct fb_info *fb_info;
112 enum vga_switcheroo_state pwr_state;
113 const struct vga_switcheroo_client_ops *ops;
114 enum vga_switcheroo_client_id id;
115 bool active;
116 bool driver_power_control;
117 struct list_head list;
118};
119
120
121
122
123static DEFINE_MUTEX(vgasr_mutex);
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145struct vgasr_priv {
146 bool active;
147 bool delayed_switch_active;
148 enum vga_switcheroo_client_id delayed_client_id;
149
150 struct dentry *debugfs_root;
151 struct dentry *switch_file;
152
153 int registered_clients;
154 struct list_head clients;
155
156 const struct vga_switcheroo_handler *handler;
157 enum vga_switcheroo_handler_flags_t handler_flags;
158 struct mutex mux_hw_lock;
159 int old_ddc_owner;
160};
161
162#define ID_BIT_AUDIO 0x100
163#define client_is_audio(c) ((c)->id & ID_BIT_AUDIO)
164#define client_is_vga(c) ((c)->id == VGA_SWITCHEROO_UNKNOWN_ID || \
165 !client_is_audio(c))
166#define client_id(c) ((c)->id & ~ID_BIT_AUDIO)
167
168static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
169static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
170
171
172static struct vgasr_priv vgasr_priv = {
173 .clients = LIST_HEAD_INIT(vgasr_priv.clients),
174 .mux_hw_lock = __MUTEX_INITIALIZER(vgasr_priv.mux_hw_lock),
175};
176
177static bool vga_switcheroo_ready(void)
178{
179
180 return !vgasr_priv.active &&
181 vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
182}
183
184static void vga_switcheroo_enable(void)
185{
186 int ret;
187 struct vga_switcheroo_client *client;
188
189
190 if (vgasr_priv.handler->init)
191 vgasr_priv.handler->init();
192
193 list_for_each_entry(client, &vgasr_priv.clients, list) {
194 if (client->id != VGA_SWITCHEROO_UNKNOWN_ID)
195 continue;
196 ret = vgasr_priv.handler->get_client_id(client->pdev);
197 if (ret < 0)
198 return;
199
200 client->id = ret;
201 }
202 vga_switcheroo_debugfs_init(&vgasr_priv);
203 vgasr_priv.active = true;
204}
205
206
207
208
209
210
211
212
213
214
215
216int vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
217 enum vga_switcheroo_handler_flags_t handler_flags)
218{
219 mutex_lock(&vgasr_mutex);
220 if (vgasr_priv.handler) {
221 mutex_unlock(&vgasr_mutex);
222 return -EINVAL;
223 }
224
225 vgasr_priv.handler = handler;
226 vgasr_priv.handler_flags = handler_flags;
227 if (vga_switcheroo_ready()) {
228 pr_info("enabled\n");
229 vga_switcheroo_enable();
230 }
231 mutex_unlock(&vgasr_mutex);
232 return 0;
233}
234EXPORT_SYMBOL(vga_switcheroo_register_handler);
235
236
237
238
239
240
241void vga_switcheroo_unregister_handler(void)
242{
243 mutex_lock(&vgasr_mutex);
244 mutex_lock(&vgasr_priv.mux_hw_lock);
245 vgasr_priv.handler_flags = 0;
246 vgasr_priv.handler = NULL;
247 if (vgasr_priv.active) {
248 pr_info("disabled\n");
249 vga_switcheroo_debugfs_fini(&vgasr_priv);
250 vgasr_priv.active = false;
251 }
252 mutex_unlock(&vgasr_priv.mux_hw_lock);
253 mutex_unlock(&vgasr_mutex);
254}
255EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
256
257
258
259
260
261
262
263
264
265enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void)
266{
267 return vgasr_priv.handler_flags;
268}
269EXPORT_SYMBOL(vga_switcheroo_handler_flags);
270
271static int register_client(struct pci_dev *pdev,
272 const struct vga_switcheroo_client_ops *ops,
273 enum vga_switcheroo_client_id id, bool active,
274 bool driver_power_control)
275{
276 struct vga_switcheroo_client *client;
277
278 client = kzalloc(sizeof(*client), GFP_KERNEL);
279 if (!client)
280 return -ENOMEM;
281
282 client->pwr_state = VGA_SWITCHEROO_ON;
283 client->pdev = pdev;
284 client->ops = ops;
285 client->id = id;
286 client->active = active;
287 client->driver_power_control = driver_power_control;
288
289 mutex_lock(&vgasr_mutex);
290 list_add_tail(&client->list, &vgasr_priv.clients);
291 if (client_is_vga(client))
292 vgasr_priv.registered_clients++;
293
294 if (vga_switcheroo_ready()) {
295 pr_info("enabled\n");
296 vga_switcheroo_enable();
297 }
298 mutex_unlock(&vgasr_mutex);
299 return 0;
300}
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315int vga_switcheroo_register_client(struct pci_dev *pdev,
316 const struct vga_switcheroo_client_ops *ops,
317 bool driver_power_control)
318{
319 return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID,
320 pdev == vga_default_device(),
321 driver_power_control);
322}
323EXPORT_SYMBOL(vga_switcheroo_register_client);
324
325
326
327
328
329
330
331
332
333
334
335
336int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
337 const struct vga_switcheroo_client_ops *ops,
338 enum vga_switcheroo_client_id id)
339{
340 return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false);
341}
342EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
343
344static struct vga_switcheroo_client *
345find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
346{
347 struct vga_switcheroo_client *client;
348
349 list_for_each_entry(client, head, list)
350 if (client->pdev == pdev)
351 return client;
352 return NULL;
353}
354
355static struct vga_switcheroo_client *
356find_client_from_id(struct list_head *head,
357 enum vga_switcheroo_client_id client_id)
358{
359 struct vga_switcheroo_client *client;
360
361 list_for_each_entry(client, head, list)
362 if (client->id == client_id)
363 return client;
364 return NULL;
365}
366
367static struct vga_switcheroo_client *
368find_active_client(struct list_head *head)
369{
370 struct vga_switcheroo_client *client;
371
372 list_for_each_entry(client, head, list)
373 if (client->active)
374 return client;
375 return NULL;
376}
377
378
379
380
381
382
383
384
385
386
387enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *pdev)
388{
389 struct vga_switcheroo_client *client;
390 enum vga_switcheroo_state ret;
391
392 mutex_lock(&vgasr_mutex);
393 client = find_client_from_pci(&vgasr_priv.clients, pdev);
394 if (!client)
395 ret = VGA_SWITCHEROO_NOT_FOUND;
396 else
397 ret = client->pwr_state;
398 mutex_unlock(&vgasr_mutex);
399 return ret;
400}
401EXPORT_SYMBOL(vga_switcheroo_get_client_state);
402
403
404
405
406
407
408
409void vga_switcheroo_unregister_client(struct pci_dev *pdev)
410{
411 struct vga_switcheroo_client *client;
412
413 mutex_lock(&vgasr_mutex);
414 client = find_client_from_pci(&vgasr_priv.clients, pdev);
415 if (client) {
416 if (client_is_vga(client))
417 vgasr_priv.registered_clients--;
418 list_del(&client->list);
419 kfree(client);
420 }
421 if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
422 pr_info("disabled\n");
423 vga_switcheroo_debugfs_fini(&vgasr_priv);
424 vgasr_priv.active = false;
425 }
426 mutex_unlock(&vgasr_mutex);
427}
428EXPORT_SYMBOL(vga_switcheroo_unregister_client);
429
430
431
432
433
434
435
436
437
438void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
439 struct fb_info *info)
440{
441 struct vga_switcheroo_client *client;
442
443 mutex_lock(&vgasr_mutex);
444 client = find_client_from_pci(&vgasr_priv.clients, pdev);
445 if (client)
446 client->fb_info = info;
447 mutex_unlock(&vgasr_mutex);
448}
449EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470int vga_switcheroo_lock_ddc(struct pci_dev *pdev)
471{
472 enum vga_switcheroo_client_id id;
473
474 mutex_lock(&vgasr_priv.mux_hw_lock);
475 if (!vgasr_priv.handler || !vgasr_priv.handler->switch_ddc) {
476 vgasr_priv.old_ddc_owner = -ENODEV;
477 return -ENODEV;
478 }
479
480 id = vgasr_priv.handler->get_client_id(pdev);
481 vgasr_priv.old_ddc_owner = vgasr_priv.handler->switch_ddc(id);
482 return vgasr_priv.old_ddc_owner;
483}
484EXPORT_SYMBOL(vga_switcheroo_lock_ddc);
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502int vga_switcheroo_unlock_ddc(struct pci_dev *pdev)
503{
504 enum vga_switcheroo_client_id id;
505 int ret = vgasr_priv.old_ddc_owner;
506
507 if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv.mux_hw_lock)))
508 return -EINVAL;
509
510 if (vgasr_priv.old_ddc_owner >= 0) {
511 id = vgasr_priv.handler->get_client_id(pdev);
512 if (vgasr_priv.old_ddc_owner != id)
513 ret = vgasr_priv.handler->switch_ddc(
514 vgasr_priv.old_ddc_owner);
515 }
516 mutex_unlock(&vgasr_priv.mux_hw_lock);
517 return ret;
518}
519EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557static int vga_switcheroo_show(struct seq_file *m, void *v)
558{
559 struct vga_switcheroo_client *client;
560 int i = 0;
561
562 mutex_lock(&vgasr_mutex);
563 list_for_each_entry(client, &vgasr_priv.clients, list) {
564 seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
565 client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" :
566 "IGD",
567 client_is_vga(client) ? "" : "-Audio",
568 client->active ? '+' : ' ',
569 client->driver_power_control ? "Dyn" : "",
570 client->pwr_state ? "Pwr" : "Off",
571 pci_name(client->pdev));
572 i++;
573 }
574 mutex_unlock(&vgasr_mutex);
575 return 0;
576}
577
578static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
579{
580 return single_open(file, vga_switcheroo_show, NULL);
581}
582
583static int vga_switchon(struct vga_switcheroo_client *client)
584{
585 if (client->driver_power_control)
586 return 0;
587 if (vgasr_priv.handler->power_state)
588 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
589
590 client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
591 client->pwr_state = VGA_SWITCHEROO_ON;
592 return 0;
593}
594
595static int vga_switchoff(struct vga_switcheroo_client *client)
596{
597 if (client->driver_power_control)
598 return 0;
599
600 client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
601 if (vgasr_priv.handler->power_state)
602 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
603 client->pwr_state = VGA_SWITCHEROO_OFF;
604 return 0;
605}
606
607static void set_audio_state(enum vga_switcheroo_client_id id,
608 enum vga_switcheroo_state state)
609{
610 struct vga_switcheroo_client *client;
611
612 client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
613 if (client && client->pwr_state != state) {
614 client->ops->set_gpu_state(client->pdev, state);
615 client->pwr_state = state;
616 }
617}
618
619
620static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
621{
622 struct vga_switcheroo_client *active;
623
624 active = find_active_client(&vgasr_priv.clients);
625 if (!active)
626 return 0;
627
628 if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
629 vga_switchon(new_client);
630
631 vga_set_default_device(new_client->pdev);
632 return 0;
633}
634
635
636static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
637{
638 int ret;
639 struct vga_switcheroo_client *active;
640
641 active = find_active_client(&vgasr_priv.clients);
642 if (!active)
643 return 0;
644
645 active->active = false;
646
647 set_audio_state(active->id, VGA_SWITCHEROO_OFF);
648
649 if (new_client->fb_info) {
650 struct fb_event event;
651
652 console_lock();
653 event.info = new_client->fb_info;
654 fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
655 console_unlock();
656 }
657
658 mutex_lock(&vgasr_priv.mux_hw_lock);
659 ret = vgasr_priv.handler->switchto(new_client->id);
660 mutex_unlock(&vgasr_priv.mux_hw_lock);
661 if (ret)
662 return ret;
663
664 if (new_client->ops->reprobe)
665 new_client->ops->reprobe(new_client->pdev);
666
667 if (active->pwr_state == VGA_SWITCHEROO_ON)
668 vga_switchoff(active);
669
670 set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
671
672 new_client->active = true;
673 return 0;
674}
675
676static bool check_can_switch(void)
677{
678 struct vga_switcheroo_client *client;
679
680 list_for_each_entry(client, &vgasr_priv.clients, list) {
681 if (!client->ops->can_switch(client->pdev)) {
682 pr_err("client %x refused switch\n", client->id);
683 return false;
684 }
685 }
686 return true;
687}
688
689static ssize_t
690vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
691 size_t cnt, loff_t *ppos)
692{
693 char usercmd[64];
694 int ret;
695 bool delay = false, can_switch;
696 bool just_mux = false;
697 enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
698 struct vga_switcheroo_client *client = NULL;
699
700 if (cnt > 63)
701 cnt = 63;
702
703 if (copy_from_user(usercmd, ubuf, cnt))
704 return -EFAULT;
705
706 mutex_lock(&vgasr_mutex);
707
708 if (!vgasr_priv.active) {
709 cnt = -EINVAL;
710 goto out;
711 }
712
713
714 if (strncmp(usercmd, "OFF", 3) == 0) {
715 list_for_each_entry(client, &vgasr_priv.clients, list) {
716 if (client->active || client_is_audio(client))
717 continue;
718 if (client->driver_power_control)
719 continue;
720 set_audio_state(client->id, VGA_SWITCHEROO_OFF);
721 if (client->pwr_state == VGA_SWITCHEROO_ON)
722 vga_switchoff(client);
723 }
724 goto out;
725 }
726
727 if (strncmp(usercmd, "ON", 2) == 0) {
728 list_for_each_entry(client, &vgasr_priv.clients, list) {
729 if (client->active || client_is_audio(client))
730 continue;
731 if (client->driver_power_control)
732 continue;
733 if (client->pwr_state == VGA_SWITCHEROO_OFF)
734 vga_switchon(client);
735 set_audio_state(client->id, VGA_SWITCHEROO_ON);
736 }
737 goto out;
738 }
739
740
741 if (strncmp(usercmd, "DIGD", 4) == 0) {
742 client_id = VGA_SWITCHEROO_IGD;
743 delay = true;
744 }
745
746 if (strncmp(usercmd, "DDIS", 4) == 0) {
747 client_id = VGA_SWITCHEROO_DIS;
748 delay = true;
749 }
750
751 if (strncmp(usercmd, "IGD", 3) == 0)
752 client_id = VGA_SWITCHEROO_IGD;
753
754 if (strncmp(usercmd, "DIS", 3) == 0)
755 client_id = VGA_SWITCHEROO_DIS;
756
757 if (strncmp(usercmd, "MIGD", 4) == 0) {
758 just_mux = true;
759 client_id = VGA_SWITCHEROO_IGD;
760 }
761 if (strncmp(usercmd, "MDIS", 4) == 0) {
762 just_mux = true;
763 client_id = VGA_SWITCHEROO_DIS;
764 }
765
766 if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)
767 goto out;
768 client = find_client_from_id(&vgasr_priv.clients, client_id);
769 if (!client)
770 goto out;
771
772 vgasr_priv.delayed_switch_active = false;
773
774 if (just_mux) {
775 mutex_lock(&vgasr_priv.mux_hw_lock);
776 ret = vgasr_priv.handler->switchto(client_id);
777 mutex_unlock(&vgasr_priv.mux_hw_lock);
778 goto out;
779 }
780
781 if (client->active)
782 goto out;
783
784
785 can_switch = check_can_switch();
786
787 if (can_switch == false && delay == false)
788 goto out;
789
790 if (can_switch) {
791 ret = vga_switchto_stage1(client);
792 if (ret)
793 pr_err("switching failed stage 1 %d\n", ret);
794
795 ret = vga_switchto_stage2(client);
796 if (ret)
797 pr_err("switching failed stage 2 %d\n", ret);
798
799 } else {
800 pr_info("setting delayed switch to client %d\n", client->id);
801 vgasr_priv.delayed_switch_active = true;
802 vgasr_priv.delayed_client_id = client_id;
803
804 ret = vga_switchto_stage1(client);
805 if (ret)
806 pr_err("delayed switching stage 1 failed %d\n", ret);
807 }
808
809out:
810 mutex_unlock(&vgasr_mutex);
811 return cnt;
812}
813
814static const struct file_operations vga_switcheroo_debugfs_fops = {
815 .owner = THIS_MODULE,
816 .open = vga_switcheroo_debugfs_open,
817 .write = vga_switcheroo_debugfs_write,
818 .read = seq_read,
819 .llseek = seq_lseek,
820 .release = single_release,
821};
822
823static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
824{
825 debugfs_remove(priv->switch_file);
826 priv->switch_file = NULL;
827
828 debugfs_remove(priv->debugfs_root);
829 priv->debugfs_root = NULL;
830}
831
832static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
833{
834 static const char mp[] = "/sys/kernel/debug";
835
836
837 if (priv->debugfs_root)
838 return 0;
839 priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
840
841 if (!priv->debugfs_root) {
842 pr_err("Cannot create %s/vgaswitcheroo\n", mp);
843 goto fail;
844 }
845
846 priv->switch_file = debugfs_create_file("switch", 0644,
847 priv->debugfs_root, NULL,
848 &vga_switcheroo_debugfs_fops);
849 if (!priv->switch_file) {
850 pr_err("cannot create %s/vgaswitcheroo/switch\n", mp);
851 goto fail;
852 }
853 return 0;
854fail:
855 vga_switcheroo_debugfs_fini(priv);
856 return -1;
857}
858
859
860
861
862
863
864
865
866
867
868
869int vga_switcheroo_process_delayed_switch(void)
870{
871 struct vga_switcheroo_client *client;
872 int ret;
873 int err = -EINVAL;
874
875 mutex_lock(&vgasr_mutex);
876 if (!vgasr_priv.delayed_switch_active)
877 goto err;
878
879 pr_info("processing delayed switch to %d\n",
880 vgasr_priv.delayed_client_id);
881
882 client = find_client_from_id(&vgasr_priv.clients,
883 vgasr_priv.delayed_client_id);
884 if (!client || !check_can_switch())
885 goto err;
886
887 ret = vga_switchto_stage2(client);
888 if (ret)
889 pr_err("delayed switching failed stage 2 %d\n", ret);
890
891 vgasr_priv.delayed_switch_active = false;
892 err = 0;
893err:
894 mutex_unlock(&vgasr_mutex);
895 return err;
896}
897EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932static void vga_switcheroo_power_switch(struct pci_dev *pdev,
933 enum vga_switcheroo_state state)
934{
935 struct vga_switcheroo_client *client;
936
937 if (!vgasr_priv.handler->power_state)
938 return;
939
940 client = find_client_from_pci(&vgasr_priv.clients, pdev);
941 if (!client)
942 return;
943
944 if (!client->driver_power_control)
945 return;
946
947 vgasr_priv.handler->power_state(client->id, state);
948}
949
950
951
952
953
954
955
956
957
958
959
960
961void vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev,
962 enum vga_switcheroo_state dynamic)
963{
964 struct vga_switcheroo_client *client;
965
966 mutex_lock(&vgasr_mutex);
967 client = find_client_from_pci(&vgasr_priv.clients, pdev);
968 if (!client || !client->driver_power_control) {
969 mutex_unlock(&vgasr_mutex);
970 return;
971 }
972
973 client->pwr_state = dynamic;
974 set_audio_state(client->id, dynamic);
975 mutex_unlock(&vgasr_mutex);
976}
977EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
978
979
980static int vga_switcheroo_runtime_suspend(struct device *dev)
981{
982 struct pci_dev *pdev = to_pci_dev(dev);
983 int ret;
984
985 ret = dev->bus->pm->runtime_suspend(dev);
986 if (ret)
987 return ret;
988 mutex_lock(&vgasr_mutex);
989 if (vgasr_priv.handler->switchto) {
990 mutex_lock(&vgasr_priv.mux_hw_lock);
991 vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
992 mutex_unlock(&vgasr_priv.mux_hw_lock);
993 }
994 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
995 mutex_unlock(&vgasr_mutex);
996 return 0;
997}
998
999static int vga_switcheroo_runtime_resume(struct device *dev)
1000{
1001 struct pci_dev *pdev = to_pci_dev(dev);
1002 int ret;
1003
1004 mutex_lock(&vgasr_mutex);
1005 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
1006 mutex_unlock(&vgasr_mutex);
1007 ret = dev->bus->pm->runtime_resume(dev);
1008 if (ret)
1009 return ret;
1010
1011 return 0;
1012}
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026int vga_switcheroo_init_domain_pm_ops(struct device *dev,
1027 struct dev_pm_domain *domain)
1028{
1029
1030 if (dev->bus && dev->bus->pm) {
1031 domain->ops = *dev->bus->pm;
1032 domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
1033 domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
1034
1035 dev_pm_domain_set(dev, domain);
1036 return 0;
1037 }
1038 dev_pm_domain_set(dev, NULL);
1039 return -EINVAL;
1040}
1041EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
1042
1043void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
1044{
1045 dev_pm_domain_set(dev, NULL);
1046}
1047EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
1048
1049static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
1050{
1051 struct pci_dev *pdev = to_pci_dev(dev);
1052 struct vga_switcheroo_client *client;
1053 struct device *video_dev = NULL;
1054 int ret;
1055
1056
1057
1058 mutex_lock(&vgasr_mutex);
1059 list_for_each_entry(client, &vgasr_priv.clients, list) {
1060 if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
1061 client_is_vga(client)) {
1062 video_dev = &client->pdev->dev;
1063 break;
1064 }
1065 }
1066 mutex_unlock(&vgasr_mutex);
1067
1068 if (video_dev) {
1069 ret = pm_runtime_get_sync(video_dev);
1070 if (ret && ret != 1)
1071 return ret;
1072 }
1073 ret = dev->bus->pm->runtime_resume(dev);
1074
1075
1076 if (video_dev) {
1077 pm_runtime_mark_last_busy(video_dev);
1078 pm_runtime_put_autosuspend(video_dev);
1079 }
1080 return ret;
1081}
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096int
1097vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
1098 struct dev_pm_domain *domain)
1099{
1100
1101 if (dev->bus && dev->bus->pm) {
1102 domain->ops = *dev->bus->pm;
1103 domain->ops.runtime_resume =
1104 vga_switcheroo_runtime_resume_hdmi_audio;
1105
1106 dev_pm_domain_set(dev, domain);
1107 return 0;
1108 }
1109 dev_pm_domain_set(dev, NULL);
1110 return -EINVAL;
1111}
1112EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
1113