diff options
| author | Keith Packard <keithp@keithp.com> | 2008-06-13 10:27:39 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2008-06-13 14:29:46 -0700 | 
| commit | 3762c9ea6754763694b1de4df3acd9dc37247f87 (patch) | |
| tree | b66355348ec7392c9f4e210c79ed0c28680032cd | |
| parent | 5957470ca3be6c0225985f74b1511401e02c014b (diff) | |
[intel] Enable MSI for i915 IRQ
| -rw-r--r-- | linux-core/i915_drv.c | 17 | ||||
| -rw-r--r-- | shared-core/i915_irq.c | 20 | 
2 files changed, 31 insertions, 6 deletions
| diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 8f51cd4d..89f089b0 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -560,6 +560,7 @@ static int i915_resume(struct drm_device *dev)  }  static int probe(struct pci_dev *pdev, const struct pci_device_id *ent); +static void remove(struct pci_dev *pdev);  static struct drm_driver driver = {  	/* don't use mtrr's here, the Xserver or user space app should  	 * deal with them for intel hardware. @@ -604,7 +605,7 @@ static struct drm_driver driver = {  		.name = DRIVER_NAME,  		.id_table = pciidlist,  		.probe = probe, -		.remove = __devexit_p(drm_cleanup_pci), +		.remove = remove,  		},  #ifdef I915_HAVE_FENCE  	.fence_driver = &i915_fence_driver, @@ -622,7 +623,19 @@ static struct drm_driver driver = {  static int probe(struct pci_dev *pdev, const struct pci_device_id *ent)  { -	return drm_get_dev(pdev, ent, &driver); +	int ret; + +	(void) pci_enable_msi(pdev); +	ret = drm_get_dev(pdev, ent, &driver); +	if (ret && pdev->msi_enabled) +		pci_disable_msi(pdev); +	return ret; +} +static void remove(struct pci_dev *pdev) +{ +	if (pdev->msi_enabled) +		pci_disable_msi(pdev); +	drm_cleanup_pci(pdev);  }  static int __init i915_init(void) diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 58781a4a..9ba5b00a 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -33,6 +33,13 @@  #define MAX_NOPID ((u32)~0) +/* + * These are the interrupts used by the driver + */ +#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \ +				    I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ +				    I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) +  /**   * i915_get_pipe - return the the pipe associated with a given plane   * @dev: DRM device @@ -443,6 +450,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)  	u32 pipea_stats = 0, pipeb_stats = 0;  	int vblank = 0; +	if (dev->pdev->msi_enabled) +		I915_WRITE(I915REG_INT_ENABLE_R, 0);  	iir = I915_READ(I915REG_INT_IDENTITY_R);  #if 0  	DRM_DEBUG("flag=%08x\n", iir); @@ -454,6 +463,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)  			   I915_READ(I915REG_INT_ENABLE_R),  			   I915_READ(I915REG_PIPEASTAT),  			   I915_READ(I915REG_PIPEBSTAT)); +		if (dev->pdev->msi_enabled) +			I915_WRITE(I915REG_INT_ENABLE_R, +				   I915_INTERRUPT_ENABLE_MASK);  		return IRQ_NONE;  	} @@ -498,6 +510,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)  			drm_locked_tasklet(dev, i915_vblank_tasklet);  	} +	if (dev->pdev->msi_enabled) +		I915_WRITE(I915REG_INT_ENABLE_R, I915_INTERRUPT_ENABLE_MASK);  	return IRQ_HANDLED;  } @@ -724,11 +738,9 @@ static void i915_enable_interrupt (struct drm_device *dev)  {  	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; -	dev_priv->irq_mask_reg = (I915_USER_INTERRUPT | -				  I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | -				  I915_DISPLAY_PIPE_B_EVENT_INTERRUPT); +	dev_priv->irq_mask_reg = I915_INTERRUPT_ENABLE_MASK;  	I915_WRITE(I915REG_INT_MASK_R, dev_priv->irq_mask_reg); -	I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_mask_reg); +	I915_WRITE(I915REG_INT_ENABLE_R, I915_INTERRUPT_ENABLE_MASK);  	(void) I915_READ (I915REG_INT_ENABLE_R);  	dev_priv->irq_enabled = 1;  } | 
