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