summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2010-10-05 10:43:00 (GMT)
committerDave Airlie <airlied@redhat.com>2010-10-06 01:29:33 (GMT)
commit094e0fa8b96c9fab5df9597e728d82f3d87ee471 (patch)
tree2cd6825c18acba42fea36b8b3e604266dcdbd5f2
parentd3216a0c3133d8e88ec45c7ecd9f38b421f90c03 (diff)
downloadlinux-094e0fa8b96c9fab5df9597e728d82f3d87ee471.tar.xz
drm/vmwgfx: Fix ACPI S3 & S4 functionality.
Don't suspend or hibernate when there are 3D resources active since we can't restore the device's 3D state. Instead fail with an error message. In other cases, make sure we re-enable the fifo and unlock ttm on resume. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c38
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h1
2 files changed, 37 insertions, 2 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 5c845b6..91eeade 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -751,15 +751,40 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
* Buffer contents is moved to swappable memory.
*/
ttm_bo_swapout_all(&dev_priv->bdev);
+
+ /**
+ * Release 3d reference held by fbdev and potentially
+ * stop fifo.
+ */
+ dev_priv->suspended = true;
+ if (dev_priv->enable_fb)
+ vmw_3d_resource_dec(dev_priv);
+
break;
case PM_POST_HIBERNATION:
case PM_POST_SUSPEND:
+ case PM_POST_RESTORE:
+ if (!dev_priv->suspended) {
+ printk(KERN_WARNING
+ "[%s] Driver is not suspended at resume"
+ " point.\n", VMWGFX_DRIVER_NAME);
+
+ break;
+ }
+
+ /**
+ * Reclaim 3d reference held by fbdev and potentially
+ * start fifo.
+ */
+ if (dev_priv->enable_fb)
+ vmw_3d_resource_inc(dev_priv);
+
+ dev_priv->suspended = false;
ttm_suspend_unlock(&vmaster->lock);
+
break;
case PM_RESTORE_PREPARE:
break;
- case PM_POST_RESTORE:
- break;
default:
break;
}
@@ -772,6 +797,15 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+ struct vmw_private *dev_priv = vmw_priv(dev);
+
+ if (dev_priv->num_3d_resources != 0) {
+ DRM_INFO("Can't suspend or hibernate "
+ "while 3D resources are active.\n");
+ return -EBUSY;
+ }
+
pci_save_state(pdev);
pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 58de639..132cc24 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -286,6 +286,7 @@ struct vmw_private {
struct vmw_master *active_master;
struct vmw_master fbdev_master;
struct notifier_block pm_nb;
+ bool suspended;
struct mutex release_mutex;
uint32_t num_3d_resources;