0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #define pr_fmt(fmt) "vga_switcheroo: " fmt
0032
0033 #include <linux/apple-gmux.h>
0034 #include <linux/console.h>
0035 #include <linux/debugfs.h>
0036 #include <linux/fb.h>
0037 #include <linux/fs.h>
0038 #include <linux/fbcon.h>
0039 #include <linux/module.h>
0040 #include <linux/pci.h>
0041 #include <linux/pm_domain.h>
0042 #include <linux/pm_runtime.h>
0043 #include <linux/seq_file.h>
0044 #include <linux/uaccess.h>
0045 #include <linux/vgaarb.h>
0046 #include <linux/vga_switcheroo.h>
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 struct vga_switcheroo_client {
0114 struct pci_dev *pdev;
0115 struct fb_info *fb_info;
0116 enum vga_switcheroo_state pwr_state;
0117 const struct vga_switcheroo_client_ops *ops;
0118 enum vga_switcheroo_client_id id;
0119 bool active;
0120 bool driver_power_control;
0121 struct list_head list;
0122 struct pci_dev *vga_dev;
0123 };
0124
0125
0126
0127
0128 static DEFINE_MUTEX(vgasr_mutex);
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 struct vgasr_priv {
0150 bool active;
0151 bool delayed_switch_active;
0152 enum vga_switcheroo_client_id delayed_client_id;
0153
0154 struct dentry *debugfs_root;
0155
0156 int registered_clients;
0157 struct list_head clients;
0158
0159 const struct vga_switcheroo_handler *handler;
0160 enum vga_switcheroo_handler_flags_t handler_flags;
0161 struct mutex mux_hw_lock;
0162 int old_ddc_owner;
0163 };
0164
0165 #define ID_BIT_AUDIO 0x100
0166 #define client_is_audio(c) ((c)->id & ID_BIT_AUDIO)
0167 #define client_is_vga(c) (!client_is_audio(c))
0168 #define client_id(c) ((c)->id & ~ID_BIT_AUDIO)
0169
0170 static void vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
0171 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
0172
0173
0174 static struct vgasr_priv vgasr_priv = {
0175 .clients = LIST_HEAD_INIT(vgasr_priv.clients),
0176 .mux_hw_lock = __MUTEX_INITIALIZER(vgasr_priv.mux_hw_lock),
0177 };
0178
0179 static bool vga_switcheroo_ready(void)
0180 {
0181
0182 return !vgasr_priv.active &&
0183 vgasr_priv.registered_clients == 2 && vgasr_priv.handler;
0184 }
0185
0186 static void vga_switcheroo_enable(void)
0187 {
0188 int ret;
0189 struct vga_switcheroo_client *client;
0190
0191
0192 if (vgasr_priv.handler->init)
0193 vgasr_priv.handler->init();
0194
0195 list_for_each_entry(client, &vgasr_priv.clients, list) {
0196 if (!client_is_vga(client) ||
0197 client_id(client) != VGA_SWITCHEROO_UNKNOWN_ID)
0198 continue;
0199
0200 ret = vgasr_priv.handler->get_client_id(client->pdev);
0201 if (ret < 0)
0202 return;
0203
0204 client->id = ret;
0205 }
0206
0207 list_for_each_entry(client, &vgasr_priv.clients, list) {
0208 if (!client_is_audio(client) ||
0209 client_id(client) != VGA_SWITCHEROO_UNKNOWN_ID)
0210 continue;
0211
0212 ret = vgasr_priv.handler->get_client_id(client->vga_dev);
0213 if (ret < 0)
0214 return;
0215
0216 client->id = ret | ID_BIT_AUDIO;
0217 if (client->ops->gpu_bound)
0218 client->ops->gpu_bound(client->pdev, ret);
0219 }
0220
0221 vga_switcheroo_debugfs_init(&vgasr_priv);
0222 vgasr_priv.active = true;
0223 }
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 int vga_switcheroo_register_handler(
0236 const struct vga_switcheroo_handler *handler,
0237 enum vga_switcheroo_handler_flags_t handler_flags)
0238 {
0239 mutex_lock(&vgasr_mutex);
0240 if (vgasr_priv.handler) {
0241 mutex_unlock(&vgasr_mutex);
0242 return -EINVAL;
0243 }
0244
0245 vgasr_priv.handler = handler;
0246 vgasr_priv.handler_flags = handler_flags;
0247 if (vga_switcheroo_ready()) {
0248 pr_info("enabled\n");
0249 vga_switcheroo_enable();
0250 }
0251 mutex_unlock(&vgasr_mutex);
0252 return 0;
0253 }
0254 EXPORT_SYMBOL(vga_switcheroo_register_handler);
0255
0256
0257
0258
0259
0260
0261 void vga_switcheroo_unregister_handler(void)
0262 {
0263 mutex_lock(&vgasr_mutex);
0264 mutex_lock(&vgasr_priv.mux_hw_lock);
0265 vgasr_priv.handler_flags = 0;
0266 vgasr_priv.handler = NULL;
0267 if (vgasr_priv.active) {
0268 pr_info("disabled\n");
0269 vga_switcheroo_debugfs_fini(&vgasr_priv);
0270 vgasr_priv.active = false;
0271 }
0272 mutex_unlock(&vgasr_priv.mux_hw_lock);
0273 mutex_unlock(&vgasr_mutex);
0274 }
0275 EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void)
0286 {
0287 return vgasr_priv.handler_flags;
0288 }
0289 EXPORT_SYMBOL(vga_switcheroo_handler_flags);
0290
0291 static int register_client(struct pci_dev *pdev,
0292 const struct vga_switcheroo_client_ops *ops,
0293 enum vga_switcheroo_client_id id,
0294 struct pci_dev *vga_dev,
0295 bool active,
0296 bool driver_power_control)
0297 {
0298 struct vga_switcheroo_client *client;
0299
0300 client = kzalloc(sizeof(*client), GFP_KERNEL);
0301 if (!client)
0302 return -ENOMEM;
0303
0304 client->pwr_state = VGA_SWITCHEROO_ON;
0305 client->pdev = pdev;
0306 client->ops = ops;
0307 client->id = id;
0308 client->active = active;
0309 client->driver_power_control = driver_power_control;
0310 client->vga_dev = vga_dev;
0311
0312 mutex_lock(&vgasr_mutex);
0313 list_add_tail(&client->list, &vgasr_priv.clients);
0314 if (client_is_vga(client))
0315 vgasr_priv.registered_clients++;
0316
0317 if (vga_switcheroo_ready()) {
0318 pr_info("enabled\n");
0319 vga_switcheroo_enable();
0320 }
0321 mutex_unlock(&vgasr_mutex);
0322 return 0;
0323 }
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 int vga_switcheroo_register_client(struct pci_dev *pdev,
0340 const struct vga_switcheroo_client_ops *ops,
0341 bool driver_power_control)
0342 {
0343 return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID, NULL,
0344 pdev == vga_default_device(),
0345 driver_power_control);
0346 }
0347 EXPORT_SYMBOL(vga_switcheroo_register_client);
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362 int vga_switcheroo_register_audio_client(struct pci_dev *pdev,
0363 const struct vga_switcheroo_client_ops *ops,
0364 struct pci_dev *vga_dev)
0365 {
0366 enum vga_switcheroo_client_id id = VGA_SWITCHEROO_UNKNOWN_ID;
0367
0368
0369
0370
0371
0372
0373
0374
0375 mutex_lock(&vgasr_mutex);
0376 if (vgasr_priv.active) {
0377 id = vgasr_priv.handler->get_client_id(vga_dev);
0378 if (id < 0) {
0379 mutex_unlock(&vgasr_mutex);
0380 return -EINVAL;
0381 }
0382
0383 if (ops->gpu_bound)
0384 ops->gpu_bound(pdev, id);
0385 }
0386 mutex_unlock(&vgasr_mutex);
0387
0388 return register_client(pdev, ops, id | ID_BIT_AUDIO, vga_dev,
0389 false, true);
0390 }
0391 EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
0392
0393 static struct vga_switcheroo_client *
0394 find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
0395 {
0396 struct vga_switcheroo_client *client;
0397
0398 list_for_each_entry(client, head, list)
0399 if (client->pdev == pdev)
0400 return client;
0401 return NULL;
0402 }
0403
0404 static struct vga_switcheroo_client *
0405 find_client_from_id(struct list_head *head,
0406 enum vga_switcheroo_client_id client_id)
0407 {
0408 struct vga_switcheroo_client *client;
0409
0410 list_for_each_entry(client, head, list)
0411 if (client->id == client_id)
0412 return client;
0413 return NULL;
0414 }
0415
0416 static struct vga_switcheroo_client *
0417 find_active_client(struct list_head *head)
0418 {
0419 struct vga_switcheroo_client *client;
0420
0421 list_for_each_entry(client, head, list)
0422 if (client->active)
0423 return client;
0424 return NULL;
0425 }
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)
0439 {
0440 if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
0441
0442
0443
0444
0445 if (apple_gmux_present() && pdev != vga_default_device() &&
0446 !vgasr_priv.handler_flags)
0447 return true;
0448 }
0449
0450 return false;
0451 }
0452 EXPORT_SYMBOL(vga_switcheroo_client_probe_defer);
0453
0454 static enum vga_switcheroo_state
0455 vga_switcheroo_pwr_state(struct vga_switcheroo_client *client)
0456 {
0457 if (client->driver_power_control)
0458 if (pm_runtime_enabled(&client->pdev->dev) &&
0459 pm_runtime_active(&client->pdev->dev))
0460 return VGA_SWITCHEROO_ON;
0461 else
0462 return VGA_SWITCHEROO_OFF;
0463 else
0464 return client->pwr_state;
0465 }
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476 enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *pdev)
0477 {
0478 struct vga_switcheroo_client *client;
0479 enum vga_switcheroo_state ret;
0480
0481 mutex_lock(&vgasr_mutex);
0482 client = find_client_from_pci(&vgasr_priv.clients, pdev);
0483 if (!client)
0484 ret = VGA_SWITCHEROO_NOT_FOUND;
0485 else
0486 ret = vga_switcheroo_pwr_state(client);
0487 mutex_unlock(&vgasr_mutex);
0488 return ret;
0489 }
0490 EXPORT_SYMBOL(vga_switcheroo_get_client_state);
0491
0492
0493
0494
0495
0496
0497
0498 void vga_switcheroo_unregister_client(struct pci_dev *pdev)
0499 {
0500 struct vga_switcheroo_client *client;
0501
0502 mutex_lock(&vgasr_mutex);
0503 client = find_client_from_pci(&vgasr_priv.clients, pdev);
0504 if (client) {
0505 if (client_is_vga(client))
0506 vgasr_priv.registered_clients--;
0507 list_del(&client->list);
0508 kfree(client);
0509 }
0510 if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {
0511 pr_info("disabled\n");
0512 vga_switcheroo_debugfs_fini(&vgasr_priv);
0513 vgasr_priv.active = false;
0514 }
0515 mutex_unlock(&vgasr_mutex);
0516 }
0517 EXPORT_SYMBOL(vga_switcheroo_unregister_client);
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527 void vga_switcheroo_client_fb_set(struct pci_dev *pdev,
0528 struct fb_info *info)
0529 {
0530 struct vga_switcheroo_client *client;
0531
0532 mutex_lock(&vgasr_mutex);
0533 client = find_client_from_pci(&vgasr_priv.clients, pdev);
0534 if (client)
0535 client->fb_info = info;
0536 mutex_unlock(&vgasr_mutex);
0537 }
0538 EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559 int vga_switcheroo_lock_ddc(struct pci_dev *pdev)
0560 {
0561 enum vga_switcheroo_client_id id;
0562
0563 mutex_lock(&vgasr_priv.mux_hw_lock);
0564 if (!vgasr_priv.handler || !vgasr_priv.handler->switch_ddc) {
0565 vgasr_priv.old_ddc_owner = -ENODEV;
0566 return -ENODEV;
0567 }
0568
0569 id = vgasr_priv.handler->get_client_id(pdev);
0570 vgasr_priv.old_ddc_owner = vgasr_priv.handler->switch_ddc(id);
0571 return vgasr_priv.old_ddc_owner;
0572 }
0573 EXPORT_SYMBOL(vga_switcheroo_lock_ddc);
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591 int vga_switcheroo_unlock_ddc(struct pci_dev *pdev)
0592 {
0593 enum vga_switcheroo_client_id id;
0594 int ret = vgasr_priv.old_ddc_owner;
0595
0596 if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv.mux_hw_lock)))
0597 return -EINVAL;
0598
0599 if (vgasr_priv.old_ddc_owner >= 0) {
0600 id = vgasr_priv.handler->get_client_id(pdev);
0601 if (vgasr_priv.old_ddc_owner != id)
0602 ret = vgasr_priv.handler->switch_ddc(
0603 vgasr_priv.old_ddc_owner);
0604 }
0605 mutex_unlock(&vgasr_priv.mux_hw_lock);
0606 return ret;
0607 }
0608 EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646 static int vga_switcheroo_show(struct seq_file *m, void *v)
0647 {
0648 struct vga_switcheroo_client *client;
0649 int i = 0;
0650
0651 mutex_lock(&vgasr_mutex);
0652 list_for_each_entry(client, &vgasr_priv.clients, list) {
0653 seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
0654 client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" :
0655 "IGD",
0656 client_is_vga(client) ? "" : "-Audio",
0657 client->active ? '+' : ' ',
0658 client->driver_power_control ? "Dyn" : "",
0659 vga_switcheroo_pwr_state(client) ? "Pwr" : "Off",
0660 pci_name(client->pdev));
0661 i++;
0662 }
0663 mutex_unlock(&vgasr_mutex);
0664 return 0;
0665 }
0666
0667 static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
0668 {
0669 return single_open(file, vga_switcheroo_show, NULL);
0670 }
0671
0672 static int vga_switchon(struct vga_switcheroo_client *client)
0673 {
0674 if (client->driver_power_control)
0675 return 0;
0676 if (vgasr_priv.handler->power_state)
0677 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);
0678
0679 client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
0680 client->pwr_state = VGA_SWITCHEROO_ON;
0681 return 0;
0682 }
0683
0684 static int vga_switchoff(struct vga_switcheroo_client *client)
0685 {
0686 if (client->driver_power_control)
0687 return 0;
0688
0689 client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
0690 if (vgasr_priv.handler->power_state)
0691 vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);
0692 client->pwr_state = VGA_SWITCHEROO_OFF;
0693 return 0;
0694 }
0695
0696 static void set_audio_state(enum vga_switcheroo_client_id id,
0697 enum vga_switcheroo_state state)
0698 {
0699 struct vga_switcheroo_client *client;
0700
0701 client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);
0702 if (client)
0703 client->ops->set_gpu_state(client->pdev, state);
0704 }
0705
0706
0707 static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
0708 {
0709 struct vga_switcheroo_client *active;
0710
0711 active = find_active_client(&vgasr_priv.clients);
0712 if (!active)
0713 return 0;
0714
0715 if (vga_switcheroo_pwr_state(new_client) == VGA_SWITCHEROO_OFF)
0716 vga_switchon(new_client);
0717
0718 vga_set_default_device(new_client->pdev);
0719 return 0;
0720 }
0721
0722
0723 static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
0724 {
0725 int ret;
0726 struct vga_switcheroo_client *active;
0727
0728 active = find_active_client(&vgasr_priv.clients);
0729 if (!active)
0730 return 0;
0731
0732 active->active = false;
0733
0734
0735 if (!active->driver_power_control)
0736 set_audio_state(active->id, VGA_SWITCHEROO_OFF);
0737
0738 if (new_client->fb_info)
0739 fbcon_remap_all(new_client->fb_info);
0740
0741 mutex_lock(&vgasr_priv.mux_hw_lock);
0742 ret = vgasr_priv.handler->switchto(new_client->id);
0743 mutex_unlock(&vgasr_priv.mux_hw_lock);
0744 if (ret)
0745 return ret;
0746
0747 if (new_client->ops->reprobe)
0748 new_client->ops->reprobe(new_client->pdev);
0749
0750 if (vga_switcheroo_pwr_state(active) == VGA_SWITCHEROO_ON)
0751 vga_switchoff(active);
0752
0753
0754 if (!new_client->driver_power_control)
0755 set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
0756
0757 new_client->active = true;
0758 return 0;
0759 }
0760
0761 static bool check_can_switch(void)
0762 {
0763 struct vga_switcheroo_client *client;
0764
0765 list_for_each_entry(client, &vgasr_priv.clients, list) {
0766 if (!client->ops->can_switch(client->pdev)) {
0767 pr_err("client %x refused switch\n", client->id);
0768 return false;
0769 }
0770 }
0771 return true;
0772 }
0773
0774 static ssize_t
0775 vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
0776 size_t cnt, loff_t *ppos)
0777 {
0778 char usercmd[64];
0779 int ret;
0780 bool delay = false, can_switch;
0781 bool just_mux = false;
0782 enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
0783 struct vga_switcheroo_client *client = NULL;
0784
0785 if (cnt > 63)
0786 cnt = 63;
0787
0788 if (copy_from_user(usercmd, ubuf, cnt))
0789 return -EFAULT;
0790
0791 mutex_lock(&vgasr_mutex);
0792
0793 if (!vgasr_priv.active) {
0794 cnt = -EINVAL;
0795 goto out;
0796 }
0797
0798
0799 if (strncmp(usercmd, "OFF", 3) == 0) {
0800 list_for_each_entry(client, &vgasr_priv.clients, list) {
0801 if (client->active || client_is_audio(client))
0802 continue;
0803 if (client->driver_power_control)
0804 continue;
0805 set_audio_state(client->id, VGA_SWITCHEROO_OFF);
0806 if (client->pwr_state == VGA_SWITCHEROO_ON)
0807 vga_switchoff(client);
0808 }
0809 goto out;
0810 }
0811
0812 if (strncmp(usercmd, "ON", 2) == 0) {
0813 list_for_each_entry(client, &vgasr_priv.clients, list) {
0814 if (client->active || client_is_audio(client))
0815 continue;
0816 if (client->driver_power_control)
0817 continue;
0818 if (client->pwr_state == VGA_SWITCHEROO_OFF)
0819 vga_switchon(client);
0820 set_audio_state(client->id, VGA_SWITCHEROO_ON);
0821 }
0822 goto out;
0823 }
0824
0825
0826 if (strncmp(usercmd, "DIGD", 4) == 0) {
0827 client_id = VGA_SWITCHEROO_IGD;
0828 delay = true;
0829 }
0830
0831 if (strncmp(usercmd, "DDIS", 4) == 0) {
0832 client_id = VGA_SWITCHEROO_DIS;
0833 delay = true;
0834 }
0835
0836 if (strncmp(usercmd, "IGD", 3) == 0)
0837 client_id = VGA_SWITCHEROO_IGD;
0838
0839 if (strncmp(usercmd, "DIS", 3) == 0)
0840 client_id = VGA_SWITCHEROO_DIS;
0841
0842 if (strncmp(usercmd, "MIGD", 4) == 0) {
0843 just_mux = true;
0844 client_id = VGA_SWITCHEROO_IGD;
0845 }
0846 if (strncmp(usercmd, "MDIS", 4) == 0) {
0847 just_mux = true;
0848 client_id = VGA_SWITCHEROO_DIS;
0849 }
0850
0851 if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)
0852 goto out;
0853 client = find_client_from_id(&vgasr_priv.clients, client_id);
0854 if (!client)
0855 goto out;
0856
0857 vgasr_priv.delayed_switch_active = false;
0858
0859 if (just_mux) {
0860 mutex_lock(&vgasr_priv.mux_hw_lock);
0861 ret = vgasr_priv.handler->switchto(client_id);
0862 mutex_unlock(&vgasr_priv.mux_hw_lock);
0863 goto out;
0864 }
0865
0866 if (client->active)
0867 goto out;
0868
0869
0870 can_switch = check_can_switch();
0871
0872 if (can_switch == false && delay == false)
0873 goto out;
0874
0875 if (can_switch) {
0876 ret = vga_switchto_stage1(client);
0877 if (ret)
0878 pr_err("switching failed stage 1 %d\n", ret);
0879
0880 ret = vga_switchto_stage2(client);
0881 if (ret)
0882 pr_err("switching failed stage 2 %d\n", ret);
0883
0884 } else {
0885 pr_info("setting delayed switch to client %d\n", client->id);
0886 vgasr_priv.delayed_switch_active = true;
0887 vgasr_priv.delayed_client_id = client_id;
0888
0889 ret = vga_switchto_stage1(client);
0890 if (ret)
0891 pr_err("delayed switching stage 1 failed %d\n", ret);
0892 }
0893
0894 out:
0895 mutex_unlock(&vgasr_mutex);
0896 return cnt;
0897 }
0898
0899 static const struct file_operations vga_switcheroo_debugfs_fops = {
0900 .owner = THIS_MODULE,
0901 .open = vga_switcheroo_debugfs_open,
0902 .write = vga_switcheroo_debugfs_write,
0903 .read = seq_read,
0904 .llseek = seq_lseek,
0905 .release = single_release,
0906 };
0907
0908 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
0909 {
0910 debugfs_remove_recursive(priv->debugfs_root);
0911 priv->debugfs_root = NULL;
0912 }
0913
0914 static void vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
0915 {
0916
0917 if (priv->debugfs_root)
0918 return;
0919
0920 priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
0921
0922 debugfs_create_file("switch", 0644, priv->debugfs_root, NULL,
0923 &vga_switcheroo_debugfs_fops);
0924 }
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936 int vga_switcheroo_process_delayed_switch(void)
0937 {
0938 struct vga_switcheroo_client *client;
0939 int ret;
0940 int err = -EINVAL;
0941
0942 mutex_lock(&vgasr_mutex);
0943 if (!vgasr_priv.delayed_switch_active)
0944 goto err;
0945
0946 pr_info("processing delayed switch to %d\n",
0947 vgasr_priv.delayed_client_id);
0948
0949 client = find_client_from_id(&vgasr_priv.clients,
0950 vgasr_priv.delayed_client_id);
0951 if (!client || !check_can_switch())
0952 goto err;
0953
0954 ret = vga_switchto_stage2(client);
0955 if (ret)
0956 pr_err("delayed switching failed stage 2 %d\n", ret);
0957
0958 vgasr_priv.delayed_switch_active = false;
0959 err = 0;
0960 err:
0961 mutex_unlock(&vgasr_mutex);
0962 return err;
0963 }
0964 EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995 static void vga_switcheroo_power_switch(struct pci_dev *pdev,
0996 enum vga_switcheroo_state state)
0997 {
0998 struct vga_switcheroo_client *client;
0999
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
1014 static 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
1034 static int vga_switcheroo_runtime_resume(struct device *dev)
1035 {
1036 struct pci_dev *pdev = to_pci_dev(dev);
1037
1038 mutex_lock(&vgasr_mutex);
1039 vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
1040 mutex_unlock(&vgasr_mutex);
1041 pci_resume_bus(pdev->bus);
1042 return dev->bus->pm->runtime_resume(dev);
1043 }
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 int 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 }
1072 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
1073
1074 void vga_switcheroo_fini_domain_pm_ops(struct device *dev)
1075 {
1076 dev_pm_domain_set(dev, NULL);
1077 }
1078 EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);