aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2010-10-05 06:43:01 -0400
committerDave Airlie <airlied@redhat.com>2010-10-05 21:29:37 -0400
commit7fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7 (patch)
tree1e081c1a5c5fc26efb00e258b7f266a099a7a085 /drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
parent094e0fa8b96c9fab5df9597e728d82f3d87ee471 (diff)
drm/vmwgfx: Add new-style PM hooks to improve hibernation behavior
Add the new-style PM hooks prepare and complete. This allows us to power up the device again after the hibernation image has been created, and display output will thus be active until the VM is finally powered off. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c113
1 files changed, 79 insertions, 34 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 91eeade92124..f3e481f9aa86 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -752,34 +752,10 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
752 */ 752 */
753 ttm_bo_swapout_all(&dev_priv->bdev); 753 ttm_bo_swapout_all(&dev_priv->bdev);
754 754
755 /**
756 * Release 3d reference held by fbdev and potentially
757 * stop fifo.
758 */
759 dev_priv->suspended = true;
760 if (dev_priv->enable_fb)
761 vmw_3d_resource_dec(dev_priv);
762
763 break; 755 break;
764 case PM_POST_HIBERNATION: 756 case PM_POST_HIBERNATION:
765 case PM_POST_SUSPEND: 757 case PM_POST_SUSPEND:
766 case PM_POST_RESTORE: 758 case PM_POST_RESTORE:
767 if (!dev_priv->suspended) {
768 printk(KERN_WARNING
769 "[%s] Driver is not suspended at resume"
770 " point.\n", VMWGFX_DRIVER_NAME);
771
772 break;
773 }
774
775 /**
776 * Reclaim 3d reference held by fbdev and potentially
777 * start fifo.
778 */
779 if (dev_priv->enable_fb)
780 vmw_3d_resource_inc(dev_priv);
781
782 dev_priv->suspended = false;
783 ttm_suspend_unlock(&vmaster->lock); 759 ttm_suspend_unlock(&vmaster->lock);
784 760
785 break; 761 break;
@@ -795,7 +771,7 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
795 * These might not be needed with the virtual SVGA device. 771 * These might not be needed with the virtual SVGA device.
796 */ 772 */
797 773
798int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state) 774static int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
799{ 775{
800 struct drm_device *dev = pci_get_drvdata(pdev); 776 struct drm_device *dev = pci_get_drvdata(pdev);
801 struct vmw_private *dev_priv = vmw_priv(dev); 777 struct vmw_private *dev_priv = vmw_priv(dev);
@@ -812,13 +788,81 @@ int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
812 return 0; 788 return 0;
813} 789}
814 790
815int vmw_pci_resume(struct pci_dev *pdev) 791static int vmw_pci_resume(struct pci_dev *pdev)
816{ 792{
817 pci_set_power_state(pdev, PCI_D0); 793 pci_set_power_state(pdev, PCI_D0);
818 pci_restore_state(pdev); 794 pci_restore_state(pdev);
819 return pci_enable_device(pdev); 795 return pci_enable_device(pdev);
820} 796}
821 797
798static int vmw_pm_suspend(struct device *kdev)
799{
800 struct pci_dev *pdev = to_pci_dev(kdev);
801 struct pm_message dummy;
802
803 dummy.event = 0;
804
805 return vmw_pci_suspend(pdev, dummy);
806}
807
808static int vmw_pm_resume(struct device *kdev)
809{
810 struct pci_dev *pdev = to_pci_dev(kdev);
811
812 return vmw_pci_resume(pdev);
813}
814
815static int vmw_pm_prepare(struct device *kdev)
816{
817 struct pci_dev *pdev = to_pci_dev(kdev);
818 struct drm_device *dev = pci_get_drvdata(pdev);
819 struct vmw_private *dev_priv = vmw_priv(dev);
820
821 /**
822 * Release 3d reference held by fbdev and potentially
823 * stop fifo.
824 */
825 dev_priv->suspended = true;
826 if (dev_priv->enable_fb)
827 vmw_3d_resource_dec(dev_priv);
828
829 if (dev_priv->num_3d_resources != 0) {
830
831 DRM_INFO("Can't suspend or hibernate "
832 "while 3D resources are active.\n");
833
834 if (dev_priv->enable_fb)
835 vmw_3d_resource_inc(dev_priv);
836 dev_priv->suspended = false;
837 return -EBUSY;
838 }
839
840 return 0;
841}
842
843static void vmw_pm_complete(struct device *kdev)
844{
845 struct pci_dev *pdev = to_pci_dev(kdev);
846 struct drm_device *dev = pci_get_drvdata(pdev);
847 struct vmw_private *dev_priv = vmw_priv(dev);
848
849 /**
850 * Reclaim 3d reference held by fbdev and potentially
851 * start fifo.
852 */
853 if (dev_priv->enable_fb)
854 vmw_3d_resource_inc(dev_priv);
855
856 dev_priv->suspended = false;
857}
858
859static const struct dev_pm_ops vmw_pm_ops = {
860 .prepare = vmw_pm_prepare,
861 .complete = vmw_pm_complete,
862 .suspend = vmw_pm_suspend,
863 .resume = vmw_pm_resume,
864};
865
822static struct drm_driver driver = { 866static struct drm_driver driver = {
823 .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 867 .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
824 DRIVER_MODESET, 868 DRIVER_MODESET,
@@ -852,15 +896,16 @@ static struct drm_driver driver = {
852#if defined(CONFIG_COMPAT) 896#if defined(CONFIG_COMPAT)
853 .compat_ioctl = drm_compat_ioctl, 897 .compat_ioctl = drm_compat_ioctl,
854#endif 898#endif
855 }, 899 },
856 .pci_driver = { 900 .pci_driver = {
857 .name = VMWGFX_DRIVER_NAME, 901 .name = VMWGFX_DRIVER_NAME,
858 .id_table = vmw_pci_id_list, 902 .id_table = vmw_pci_id_list,
859 .probe = vmw_probe, 903 .probe = vmw_probe,
860 .remove = vmw_remove, 904 .remove = vmw_remove,
861 .suspend = vmw_pci_suspend, 905 .driver = {
862 .resume = vmw_pci_resume 906 .pm = &vmw_pm_ops
863 }, 907 }
908 },
864 .name = VMWGFX_DRIVER_NAME, 909 .name = VMWGFX_DRIVER_NAME,
865 .desc = VMWGFX_DRIVER_DESC, 910 .desc = VMWGFX_DRIVER_DESC,
866 .date = VMWGFX_DRIVER_DATE, 911 .date = VMWGFX_DRIVER_DATE,