diff options
author | Robert Noland <rnoland@2hip.net> | 2008-07-23 19:55:06 -0400 |
---|---|---|
committer | Robert Noland <rnoland@2hip.net> | 2008-07-23 19:55:06 -0400 |
commit | 965a72202b439068e62ac341990f51953457b202 (patch) | |
tree | fbd49467efd5f388db6d847c92d7c751e1c2b01c /shared-core | |
parent | 589f9681734770dce966bcded7d3d4bd78f4bea5 (diff) |
i915: Move all of the irq install/uninstall to load time.
This resolves a panic on FreeBSD which was caused by trying
to re-initialize the swap lock. It's just much easier to
initialize all of the locks at load time. It should also
ensure that the vblank structures are available earlier.
Diffstat (limited to 'shared-core')
-rw-r--r-- | shared-core/i915_dma.c | 47 | ||||
-rw-r--r-- | shared-core/i915_drv.h | 1 | ||||
-rw-r--r-- | shared-core/i915_irq.c | 54 |
3 files changed, 50 insertions, 52 deletions
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index ad6e1293..e57580fe 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -1010,7 +1010,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; unsigned long base, size; - int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; + int ret = 0, num_pipes = 2, mmio_bar = IS_I9XX(dev) ? 0 : 1; /* i915 has 4 more counters */ dev->counters += 4; @@ -1041,12 +1041,57 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_opregion_init(dev); #endif + I915_WRITE16(HWSTAM, 0xeffe); + I915_WRITE16(IMR, 0x0); + I915_WRITE16(IER, 0x0); + + DRM_SPININIT(&dev_priv->swaps_lock, "swap"); + INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); + dev_priv->swaps_pending = 0; + + DRM_SPININIT(&dev_priv->user_irq_lock, "userirq"); + dev_priv->user_irq_refcount = 0; + dev_priv->irq_enable_reg = 0; + + ret = drm_vblank_init(dev, num_pipes); + if (ret) + return ret; + + dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + + i915_enable_interrupt(dev); + DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); + + /* + * Initialize the hardware status page IRQ location. + */ + + I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); + return ret; } int i915_driver_unload(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + u32 temp; + + if (dev_priv) { + dev_priv->vblank_pipe = 0; + + dev_priv->irq_enabled = 0; + I915_WRITE(HWSTAM, 0xffffffff); + I915_WRITE(IMR, 0xffffffff); + I915_WRITE(IER, 0x0); + + temp = I915_READ(PIPEASTAT); + I915_WRITE(PIPEASTAT, temp); + temp = I915_READ(PIPEBSTAT); + I915_WRITE(PIPEBSTAT, temp); + temp = I915_READ(IIR); + I915_WRITE(IIR, temp); + } if (dev_priv->mmio_map) drm_rmmap(dev, dev_priv->mmio_map); diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 421572cd..a77fcf04 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -307,6 +307,7 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); extern void i915_driver_irq_preinstall(struct drm_device * dev); extern int i915_driver_irq_postinstall(struct drm_device * dev); extern void i915_driver_irq_uninstall(struct drm_device * dev); +extern void i915_enable_interrupt(struct drm_device *dev); extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index b95d0f1e..135d6159 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -668,7 +668,7 @@ void i915_disable_vblank(struct drm_device *dev, int plane) } } -static void i915_enable_interrupt (struct drm_device *dev) +void i915_enable_interrupt (struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -876,63 +876,15 @@ int i915_vblank_swap(struct drm_device *dev, void *data, */ void i915_driver_irq_preinstall(struct drm_device * dev) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - - I915_WRITE16(HWSTAM, 0xeffe); - I915_WRITE16(IMR, 0x0); - I915_WRITE16(IER, 0x0); + return; } int i915_driver_irq_postinstall(struct drm_device * dev) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int ret, num_pipes = 2; - - DRM_SPININIT(&dev_priv->swaps_lock, "swap"); - INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); - dev_priv->swaps_pending = 0; - - DRM_SPININIT(&dev_priv->user_irq_lock, "userirq"); - dev_priv->user_irq_refcount = 0; - dev_priv->irq_enable_reg = 0; - - ret = drm_vblank_init(dev, num_pipes); - if (ret) - return ret; - - dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; - dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ - - i915_enable_interrupt(dev); - DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); - - /* - * Initialize the hardware status page IRQ location. - */ - - I915_WRITE(INSTPM, (1 << 5) | (1 << 21)); return 0; } void i915_driver_irq_uninstall(struct drm_device * dev) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 temp; - - if (!dev_priv) - return; - - dev_priv->vblank_pipe = 0; - - dev_priv->irq_enabled = 0; - I915_WRITE(HWSTAM, 0xffffffff); - I915_WRITE(IMR, 0xffffffff); - I915_WRITE(IER, 0x0); - - temp = I915_READ(PIPEASTAT); - I915_WRITE(PIPEASTAT, temp); - temp = I915_READ(PIPEBSTAT); - I915_WRITE(PIPEBSTAT, temp); - temp = I915_READ(IIR); - I915_WRITE(IIR, temp); + return; } |