0001
0002
0003
0004
0005
0006 #include <linux/vga_switcheroo.h>
0007
0008 #include "i915_driver.h"
0009 #include "i915_drv.h"
0010 #include "i915_switcheroo.h"
0011
0012 static void i915_switcheroo_set_state(struct pci_dev *pdev,
0013 enum vga_switcheroo_state state)
0014 {
0015 struct drm_i915_private *i915 = pdev_to_i915(pdev);
0016 pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
0017
0018 if (!i915) {
0019 dev_err(&pdev->dev, "DRM not initialized, aborting switch.\n");
0020 return;
0021 }
0022
0023 if (state == VGA_SWITCHEROO_ON) {
0024 drm_info(&i915->drm, "switched on\n");
0025 i915->drm.switch_power_state = DRM_SWITCH_POWER_CHANGING;
0026
0027 pci_set_power_state(pdev, PCI_D0);
0028 i915_driver_resume_switcheroo(i915);
0029 i915->drm.switch_power_state = DRM_SWITCH_POWER_ON;
0030 } else {
0031 drm_info(&i915->drm, "switched off\n");
0032 i915->drm.switch_power_state = DRM_SWITCH_POWER_CHANGING;
0033 i915_driver_suspend_switcheroo(i915, pmm);
0034 i915->drm.switch_power_state = DRM_SWITCH_POWER_OFF;
0035 }
0036 }
0037
0038 static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
0039 {
0040 struct drm_i915_private *i915 = pdev_to_i915(pdev);
0041
0042
0043
0044
0045
0046
0047 return i915 && atomic_read(&i915->drm.open_count) == 0;
0048 }
0049
0050 static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
0051 .set_gpu_state = i915_switcheroo_set_state,
0052 .reprobe = NULL,
0053 .can_switch = i915_switcheroo_can_switch,
0054 };
0055
0056 int i915_switcheroo_register(struct drm_i915_private *i915)
0057 {
0058 struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
0059
0060 return vga_switcheroo_register_client(pdev, &i915_switcheroo_ops, false);
0061 }
0062
0063 void i915_switcheroo_unregister(struct drm_i915_private *i915)
0064 {
0065 struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
0066
0067 vga_switcheroo_unregister_client(pdev);
0068 }