diff options
| -rw-r--r-- | linux-core/drmP.h | 2 | ||||
| -rw-r--r-- | linux-core/drm_irq.c | 49 | ||||
| -rw-r--r-- | linux-core/drm_sysfs.c | 2 | ||||
| -rw-r--r-- | linux-core/i915_drv.c | 13 | 
4 files changed, 44 insertions, 22 deletions
| diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 297d8d60..0f42d5b6 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -647,7 +647,7 @@ struct drm_driver {  	void (*postclose) (struct drm_device *, struct drm_file *);  	void (*lastclose) (struct drm_device *);  	int (*unload) (struct drm_device *); -	int (*suspend) (struct drm_device *); +	int (*suspend) (struct drm_device *, pm_message_t state);  	int (*resume) (struct drm_device *);  	int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);  	void (*dma_ready) (struct drm_device *); diff --git a/linux-core/drm_irq.c b/linux-core/drm_irq.c index cb279bcd..9df4ed24 100644 --- a/linux-core/drm_irq.c +++ b/linux-core/drm_irq.c @@ -88,6 +88,36 @@ static void vblank_disable_fn(unsigned long arg)  	}  } +static void drm_vblank_cleanup(struct drm_device *dev) +{ +	/* Bail if the driver didn't call drm_vblank_init() */ +	if (dev->num_crtcs == 0) +		return; + +	del_timer(&dev->vblank_disable_timer); + +	vblank_disable_fn((unsigned long)dev); + +	drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, +		 DRM_MEM_DRIVER); +	drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs, +		 DRM_MEM_DRIVER); +	drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * +		 dev->num_crtcs, DRM_MEM_DRIVER); +	drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * +		 dev->num_crtcs, DRM_MEM_DRIVER); +	drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * +		 dev->num_crtcs, DRM_MEM_DRIVER); +	drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, +		 DRM_MEM_DRIVER); +	drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) * +		 dev->num_crtcs, DRM_MEM_DRIVER); +	drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs, +		 DRM_MEM_DRIVER); + +	dev->num_crtcs = 0; +} +  int drm_vblank_init(struct drm_device *dev, int num_crtcs)  {  	int i, ret = -ENOMEM; @@ -147,22 +177,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)  	return 0;  err: -	drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * num_crtcs, -		 DRM_MEM_DRIVER); -	drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * num_crtcs, -		 DRM_MEM_DRIVER); -	drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * num_crtcs, -		 DRM_MEM_DRIVER); -	drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * -		 num_crtcs, DRM_MEM_DRIVER); -	drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * num_crtcs, -		 DRM_MEM_DRIVER); -	drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * num_crtcs, -		 DRM_MEM_DRIVER); -	drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) * -		 num_crtcs, DRM_MEM_DRIVER); -	drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * num_crtcs, -		 DRM_MEM_DRIVER); +	drm_vblank_cleanup(dev);  	return ret;  }  EXPORT_SYMBOL(drm_vblank_init); @@ -258,6 +273,8 @@ int drm_irq_uninstall(struct drm_device * dev)  	dev->driver->irq_uninstall(dev); +	drm_vblank_cleanup(dev); +  	free_irq(dev->irq, dev);  	dev->locked_tasklet_func = NULL; diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index f03e5d4e..3372a713 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -38,7 +38,7 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)  	if (drm_minor->type == DRM_MINOR_CONTROL)  		if (drm_dev->driver->suspend) -			return drm_dev->driver->suspend(drm_dev); +			return drm_dev->driver->suspend(drm_dev, state);  	return 0;  } diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 64c805f5..0123d412 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -264,7 +264,7 @@ static void i915_restore_vga(struct drm_device *dev)  } -static int i915_suspend(struct drm_device *dev) +static int i915_suspend(struct drm_device *dev, pm_message_t state)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	int i; @@ -275,6 +275,9 @@ static int i915_suspend(struct drm_device *dev)  		return -ENODEV;  	} +	if (state.event == PM_EVENT_PRETHAW) +		return 0; +  	pci_save_state(dev->pdev);  	pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); @@ -389,9 +392,11 @@ static int i915_suspend(struct drm_device *dev)  	i915_save_vga(dev); -	/* Shut down the device */ -	pci_disable_device(dev->pdev); -	pci_set_power_state(dev->pdev, PCI_D3hot); +	if (state.event == PM_EVENT_SUSPEND) { +		/* Shut down the device */ +		pci_disable_device(dev->pdev); +		pci_set_power_state(dev->pdev, PCI_D3hot); +	}  	return 0;  } | 
