--- a/bbswitch.c 2018-07-21 21:51:36.039044960 +0200 +++ b/bbswitch.c 2018-07-21 21:56:29.706612678 +0200 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -288,17 +289,25 @@ static int bbswitch_pci_runtime_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - + struct drm_device *drm_dev = pci_get_drvdata(pdev); + pr_info("disabling discrete graphics\n"); - /* Ensure that the audio driver knows not to touch us. */ - vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); + drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; + + bbswitch_optimus_dsm(); /* Save state now that the device is still awake, makes PCI layer happy */ pci_save_state(pdev); - /* TODO if _PR3 is supported, should this be PCI_D3hot? */ + pci_disable_device(pdev); + pci_ignore_hotplug(pdev); + + + /* Ensure that the audio driver knows not to touch us. */ + drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; + /* TODO if _PR3 is supported, should this be PCI_D3hot? */ pci_set_power_state(pdev, PCI_D3hot); return 0; } @@ -306,11 +315,22 @@ static int bbswitch_pci_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - + struct drm_device *drm_dev = pci_get_drvdata(pdev); + int ret; pr_debug("Finishing runtime resume.\n"); + pci_restore_state(pdev); + ret = pci_enable_device(pdev); + if (ret) + return ret; + + pci_set_master(pdev); + + + // drm_kms_helper_poll_enable(drm_dev); /* Resume audio driver. */ - vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); + drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; + return 0; }