Initialize the vblank structures at load time. Previously we did this

at irq install/uninstall time, but when we vt switch, we uninstall the
irq handler.  When the irq handler is reinstalled, the modeset ioctl
happens first.  The modeset ioctl is supposed to tell us that we can
disable vblank interrupts if there are no active consumers.  This will
fail after a vt switch until another modeset ioctl is called via dpms
or xrandr.  Leading to cases where either interrupts are on and can't
be disabled, or worse, no interrupts at all.

MFC after:	2 weeks
This commit is contained in:
rnoland 2009-02-28 02:37:55 +00:00
parent e9bc5839af
commit ddd5c68e84
16 changed files with 44 additions and 20 deletions

View File

@ -794,6 +794,7 @@ void drm_handle_vblank(struct drm_device *dev, int crtc);
u32 drm_vblank_count(struct drm_device *dev, int crtc);
int drm_vblank_get(struct drm_device *dev, int crtc);
void drm_vblank_put(struct drm_device *dev, int crtc);
void drm_vblank_cleanup(struct drm_device *dev);
int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
int drm_vblank_init(struct drm_device *dev, int num_crtcs);
void drm_vbl_send_signals(struct drm_device *dev, int crtc);

View File

@ -523,6 +523,8 @@ static void drm_unload(struct drm_device *dev)
DRM_DEBUG("mtrr_del = %d", retcode);
}
drm_vblank_cleanup(dev);
DRM_LOCK();
drm_lastclose(dev);
DRM_UNLOCK();

View File

@ -96,7 +96,7 @@ static void vblank_disable_fn(void *arg)
}
}
static void drm_vblank_cleanup(struct drm_device *dev)
void drm_vblank_cleanup(struct drm_device *dev)
{
unsigned long irqflags;
@ -213,8 +213,6 @@ int drm_irq_uninstall(struct drm_device *dev)
bus_teardown_intr(dev->device, dev->irqr, dev->irqh);
DRM_LOCK();
drm_vblank_cleanup(dev);
return 0;
}

View File

@ -902,6 +902,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
#endif
DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
ret = drm_vblank_init(dev, I915_NUM_PIPE);
if (ret) {
(void) i915_driver_unload(dev);
return ret;
}
return ret;
}

View File

@ -49,6 +49,8 @@ enum pipe {
PIPE_B,
};
#define I915_NUM_PIPE 2
/* Interface history:
*
* 1.1: Original.

View File

@ -484,11 +484,6 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
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;
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;

View File

@ -54,6 +54,7 @@ static void mach64_configure(struct drm_device *dev)
DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
dev->driver->buf_priv_size = 1; /* No dev_priv */
dev->driver->load = mach64_driver_load;
dev->driver->lastclose = mach64_driver_lastclose;
dev->driver->get_vblank_counter = mach64_get_vblank_counter;
dev->driver->enable_vblank = mach64_enable_vblank;
@ -94,6 +95,12 @@ mach64_attach(device_t nbdev)
return drm_attach(nbdev, mach64_pciidlist);
}
int
mach64_driver_load(struct drm_device * dev, unsigned long flags)
{
return drm_vblank_init(dev, 1);
}
static int
mach64_detach(device_t nbdev)
{

View File

@ -166,6 +166,7 @@ extern int mach64_dma_blit(struct drm_device *dev, void *data,
extern int mach64_get_param(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int mach64_driver_load(struct drm_device * dev, unsigned long flags);
extern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc);
extern int mach64_enable_vblank(struct drm_device *dev, int crtc);
extern void mach64_disable_vblank(struct drm_device *dev, int crtc);

View File

@ -146,7 +146,7 @@ void mach64_driver_irq_preinstall(struct drm_device * dev)
int mach64_driver_irq_postinstall(struct drm_device * dev)
{
return drm_vblank_init(dev, 1);
return 0;
}
void mach64_driver_irq_uninstall(struct drm_device * dev)

View File

@ -399,6 +399,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
int mga_driver_load(struct drm_device *dev, unsigned long flags)
{
drm_mga_private_t *dev_priv;
int ret;
dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
if (!dev_priv)
@ -418,6 +419,13 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags)
dev->types[7] = _DRM_STAT_PRIMARY;
dev->types[8] = _DRM_STAT_SECONDARY;
ret = drm_vblank_init(dev, 1);
if (ret) {
(void) mga_driver_unload(dev);
return ret;
}
return 0;
}

View File

@ -157,11 +157,6 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
int mga_driver_irq_postinstall(struct drm_device * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
int ret;
ret = drm_vblank_init(dev, 1);
if (ret)
return ret;
DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);

View File

@ -52,6 +52,7 @@ static void r128_configure(struct drm_device *dev)
DRIVER_SG | DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ;
dev->driver->buf_priv_size = sizeof(drm_r128_buf_priv_t);
dev->driver->load = r128_driver_load;
dev->driver->preclose = r128_driver_preclose;
dev->driver->lastclose = r128_driver_lastclose;
dev->driver->get_vblank_counter = r128_get_vblank_counter;
@ -93,6 +94,11 @@ r128_attach(device_t nbdev)
return drm_attach(nbdev, r128_pciidlist);
}
int r128_driver_load(struct drm_device * dev, unsigned long flags)
{
return drm_vblank_init(dev, 1);
}
static int
r128_detach(device_t nbdev)
{

View File

@ -162,6 +162,7 @@ extern void r128_driver_irq_preinstall(struct drm_device * dev);
extern int r128_driver_irq_postinstall(struct drm_device * dev);
extern void r128_driver_irq_uninstall(struct drm_device * dev);
extern void r128_driver_lastclose(struct drm_device * dev);
extern int r128_driver_load(struct drm_device * dev, unsigned long flags);
extern void r128_driver_preclose(struct drm_device * dev,
struct drm_file *file_priv);

View File

@ -105,7 +105,7 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
int r128_driver_irq_postinstall(struct drm_device * dev)
{
return drm_vblank_init(dev, 1);
return 0;
}
void r128_driver_irq_uninstall(struct drm_device * dev)

View File

@ -1751,6 +1751,12 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
else
dev_priv->flags |= RADEON_IS_PCI;
ret = drm_vblank_init(dev, 2);
if (ret) {
radeon_driver_unload(dev);
return ret;
}
DRM_DEBUG("%s card detected\n",
((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
return ret;

View File

@ -372,15 +372,10 @@ int radeon_driver_irq_postinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
int ret;
atomic_set(&dev_priv->swi_emitted, 0);
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
ret = drm_vblank_init(dev, 2);
if (ret)
return ret;
dev->max_vblank_count = 0x001fffff;
radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);