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