Index: drm_bufs.c =================================================================== --- drm_bufs.c (revision 190607) +++ drm_bufs.c (working copy) @@ -306,7 +306,7 @@ case _DRM_FRAME_BUFFER: if (map->mtrr) { int __unused retcode; - + retcode = drm_mtrr_del(0, map->offset, map->size, DRM_MTRR_WC); DRM_DEBUG("mtrr_del = %d\n", retcode); Index: radeon_cp.c =================================================================== --- radeon_cp.c (revision 190607) +++ radeon_cp.c (working copy) @@ -2071,6 +2071,8 @@ return ret; } + dev->max_vblank_count = 0x001fffff; + DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); return ret; Index: drm_irq.c =================================================================== --- drm_irq.c (revision 190607) +++ drm_irq.c (working copy) @@ -55,7 +55,7 @@ return 0; } -static irqreturn_t +irqreturn_t drm_irq_handler_wrap(DRM_IRQ_ARGS) { struct drm_device *dev = arg; @@ -70,6 +70,9 @@ struct drm_device *dev = (struct drm_device *)arg; int i; + /* Make sure that we are called with the lock held */ + mtx_assert(&dev->vbl_lock, MA_OWNED); + if (callout_pending(&dev->vblank_disable_timer)) { /* callout was reset */ return; @@ -86,8 +89,8 @@ return; for (i = 0; i < dev->num_crtcs; i++) { - if (atomic_read(&dev->vblank[i].refcount) == 0 && - dev->vblank[i].enabled && !dev->vblank[i].inmodeset) { + if (dev->vblank[i].refcount == 0 && + dev->vblank[i].enabled) { DRM_DEBUG("disabling vblank on crtc %d\n", i); dev->vblank[i].last = dev->driver->get_vblank_counter(dev, i); @@ -109,7 +112,9 @@ callout_drain(&dev->vblank_disable_timer); + DRM_SPINLOCK(&dev->vbl_lock); vblank_disable_fn((void *)dev); + DRM_SPINUNLOCK(&dev->vbl_lock); free(dev->vblank, DRM_MEM_DRIVER); @@ -132,14 +137,15 @@ DRM_DEBUG("\n"); /* Zero per-crtc vblank stuff */ + DRM_SPINLOCK(&dev->vbl_lock); for (i = 0; i < num_crtcs; i++) { DRM_INIT_WAITQUEUE(&dev->vblank[i].queue); TAILQ_INIT(&dev->vblank[i].sigs); - atomic_set(&dev->vblank[i].count, 0); - atomic_set(&dev->vblank[i].refcount, 0); + dev->vblank[i].refcount = 0; + atomic_set_acq_32(&dev->vblank[i].count, 0); } - dev->vblank_disable_allowed = 0; + DRM_SPINUNLOCK(&dev->vbl_lock); return 0; @@ -150,14 +156,11 @@ int drm_irq_install(struct drm_device *dev) { - int crtc, retcode; - if (dev->irq == 0 || dev->dev_private == NULL) return EINVAL; - DRM_DEBUG("irq=%d\n", dev->irq); - DRM_LOCK(); + if (dev->irq_enabled) { DRM_UNLOCK(); return EBUSY; @@ -166,78 +169,30 @@ dev->context_flag = 0; - /* Before installing handler */ - dev->driver->irq_preinstall(dev); - DRM_UNLOCK(); - - /* Install handler */ -#if __FreeBSD_version >= 700031 - retcode = bus_setup_intr(dev->device, dev->irqr, - INTR_TYPE_TTY | INTR_MPSAFE, - NULL, drm_irq_handler_wrap, dev, &dev->irqh); -#else - retcode = bus_setup_intr(dev->device, dev->irqr, - INTR_TYPE_TTY | INTR_MPSAFE, - drm_irq_handler_wrap, dev, &dev->irqh); -#endif - if (retcode != 0) - goto err; - /* After installing handler */ - DRM_LOCK(); dev->driver->irq_postinstall(dev); - DRM_UNLOCK(); - if (dev->driver->enable_vblank) { - DRM_SPINLOCK(&dev->vbl_lock); - for( crtc = 0 ; crtc < dev->num_crtcs ; crtc++) { - if (dev->driver->enable_vblank(dev, crtc) == 0) { - dev->vblank[crtc].enabled = 1; - } - } - callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ, - (timeout_t *)vblank_disable_fn, (void *)dev); - DRM_SPINUNLOCK(&dev->vbl_lock); - } - return 0; -err: - DRM_LOCK(); - dev->irq_enabled = 0; + DRM_DEBUG("irq %d enabled\n", dev->irq); + DRM_UNLOCK(); - return retcode; + return 0; } int drm_irq_uninstall(struct drm_device *dev) { - int crtc; + DRM_SPINLOCK_ASSERT(&dev->dev_lock); if (!dev->irq_enabled) return EINVAL; dev->irq_enabled = 0; - /* - * Wake up any waiters so they don't hang. - */ - DRM_SPINLOCK(&dev->vbl_lock); - for (crtc = 0; crtc < dev->num_crtcs; crtc++) { - if (dev->vblank[crtc].enabled) { - DRM_WAKEUP(&dev->vblank[crtc].queue); - dev->vblank[crtc].last = - dev->driver->get_vblank_counter(dev, crtc); - dev->vblank[crtc].enabled = 0; - } - } - DRM_SPINUNLOCK(&dev->vbl_lock); - - DRM_DEBUG("irq=%d\n", dev->irq); - + DRM_SPINLOCK(&dev->irq_lock); dev->driver->irq_uninstall(dev); + DRM_SPINUNLOCK(&dev->irq_lock); - DRM_UNLOCK(); - bus_teardown_intr(dev->device, dev->irqr, dev->irqh); - DRM_LOCK(); + DRM_DEBUG("irq %d disabled\n", dev->irq); return 0; } @@ -272,7 +227,7 @@ u32 drm_vblank_count(struct drm_device *dev, int crtc) { - return atomic_read(&dev->vblank[crtc].count); + return atomic_load_acq_32(&dev->vblank[crtc].count); } static void drm_update_vblank_count(struct drm_device *dev, int crtc) @@ -298,45 +253,49 @@ DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", crtc, diff); - atomic_add(diff, &dev->vblank[crtc].count); + atomic_add_rel_32(&dev->vblank[crtc].count, diff); } int drm_vblank_get(struct drm_device *dev, int crtc) { int ret = 0; - DRM_SPINLOCK(&dev->vbl_lock); + /* Make sure that we are called with the lock held */ + mtx_assert(&dev->vbl_lock, MA_OWNED); + /* Going from 0->1 means we have to enable interrupts again */ - atomic_add_acq_int(&dev->vblank[crtc].refcount, 1); - if (dev->vblank[crtc].refcount == 1 && + if (++dev->vblank[crtc].refcount == 1 && !dev->vblank[crtc].enabled) { ret = dev->driver->enable_vblank(dev, crtc); DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); if (ret) - atomic_dec(&dev->vblank[crtc].refcount); + --dev->vblank[crtc].refcount; else { dev->vblank[crtc].enabled = 1; drm_update_vblank_count(dev, crtc); } } - DRM_SPINUNLOCK(&dev->vbl_lock); + if (dev->vblank[crtc].enabled) { + dev->vblank[crtc].last = + dev->driver->get_vblank_counter(dev, crtc); + } + return ret; } void drm_vblank_put(struct drm_device *dev, int crtc) { - KASSERT(atomic_read(&dev->vblank[crtc].refcount) > 0, + /* Make sure that we are called with the lock held */ + mtx_assert(&dev->vbl_lock, MA_OWNED); + + KASSERT(dev->vblank[crtc].refcount > 0, ("invalid refcount")); /* Last user schedules interrupt disable */ - atomic_subtract_acq_int(&dev->vblank[crtc].refcount, 1); - - DRM_SPINLOCK(&dev->vbl_lock); - if (dev->vblank[crtc].refcount == 0) + if (--dev->vblank[crtc].refcount == 0) callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ, (timeout_t *)vblank_disable_fn, (void *)dev); - DRM_SPINUNLOCK(&dev->vbl_lock); } int drm_modeset_ctl(struct drm_device *dev, void *data, @@ -345,13 +304,11 @@ struct drm_modeset_ctl *modeset = data; int crtc, ret = 0; - DRM_DEBUG("num_crtcs=%d\n", dev->num_crtcs); /* If drm_vblank_init() hasn't been called yet, just no-op */ if (!dev->num_crtcs) goto out; crtc = modeset->crtc; - DRM_DEBUG("crtc=%d\n", crtc); if (crtc >= dev->num_crtcs) { ret = EINVAL; goto out; @@ -366,25 +323,25 @@ */ switch (modeset->cmd) { case _DRM_PRE_MODESET: - DRM_DEBUG("pre-modeset\n"); + DRM_DEBUG("pre-modeset, crtc %d\n", crtc); + DRM_SPINLOCK(&dev->vbl_lock); if (!dev->vblank[crtc].inmodeset) { dev->vblank[crtc].inmodeset = 0x1; if (drm_vblank_get(dev, crtc) == 0) dev->vblank[crtc].inmodeset |= 0x2; } + DRM_SPINUNLOCK(&dev->vbl_lock); break; case _DRM_POST_MODESET: - DRM_DEBUG("post-modeset\n"); + DRM_DEBUG("post-modeset, crtc %d\n", crtc); + DRM_SPINLOCK(&dev->vbl_lock); if (dev->vblank[crtc].inmodeset) { - DRM_SPINLOCK(&dev->vbl_lock); - dev->vblank_disable_allowed = 1; - DRM_SPINUNLOCK(&dev->vbl_lock); - if (dev->vblank[crtc].inmodeset & 0x2) drm_vblank_put(dev, crtc); - dev->vblank[crtc].inmodeset = 0; } + dev->vblank_disable_allowed = 1; + DRM_SPINUNLOCK(&dev->vbl_lock); break; default: ret = EINVAL; @@ -401,8 +358,9 @@ unsigned int flags, seq, crtc; int ret = 0; - if (!dev->irq_enabled) + if (!dev->irq_enabled) { return EINVAL; + } if (vblwait->request.type & ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) { @@ -415,10 +373,13 @@ flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK; crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0; - if (crtc >= dev->num_crtcs) + if (crtc >= dev->num_crtcs) { return EINVAL; + } + DRM_SPINLOCK(&dev->vbl_lock); ret = drm_vblank_get(dev, crtc); + DRM_SPINUNLOCK(&dev->vbl_lock); if (ret) { DRM_ERROR("failed to acquire vblank counter, %d\n", ret); return ret; @@ -463,20 +424,21 @@ } else { DRM_DEBUG("waiting on vblank count %d, crtc %d\n", vblwait->request.sequence, crtc); - dev->vblank[crtc].last = vblwait->request.sequence; - for ( ret = 0 ; !ret && !(((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23)) || - !dev->irq_enabled) ; ) { + for ( ret = 0 ; !ret && !((drm_vblank_count(dev, crtc) - + vblwait->request.sequence) <= (1 << 23)) ; ) { mtx_lock(&dev->irq_lock); - if (!(((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23)) || - !dev->irq_enabled)) + if (!((drm_vblank_count(dev, crtc) - + vblwait->request.sequence) <= (1 << 23))) ret = mtx_sleep(&dev->vblank[crtc].queue, &dev->irq_lock, PCATCH, "vblwtq", - 3 * DRM_HZ); + DRM_HZ); mtx_unlock(&dev->irq_lock); } + if (ret == EWOULDBLOCK) { + DRM_DEBUG("timed out waiting on vblank\n"); + ret = EBUSY; + } if (ret != EINTR && ret != ERESTART) { struct timeval now; @@ -492,7 +454,10 @@ } done: + DRM_SPINLOCK(&dev->vbl_lock); drm_vblank_put(dev, crtc); + DRM_SPINUNLOCK(&dev->vbl_lock); + return ret; } @@ -526,7 +491,7 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) { - atomic_inc(&dev->vblank[crtc].count); + atomic_add_rel_32(&dev->vblank[crtc].count, 1); DRM_WAKEUP(&dev->vblank[crtc].queue); drm_vbl_send_signals(dev, crtc); } Index: i915_irq.c =================================================================== --- i915_irq.c (revision 190607) +++ i915_irq.c (working copy) @@ -154,7 +154,7 @@ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL; if (!i915_pipe_enabled(dev, pipe)) { - DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); + DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); return 0; } @@ -183,7 +183,7 @@ int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; if (!i915_pipe_enabled(dev, pipe)) { - DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); + DRM_DEBUG("trying to get vblank count for disabled pipe %d\n", pipe); return 0; } @@ -200,12 +200,10 @@ u32 vblank_enable; int irq_received; - atomic_inc(&dev_priv->irq_received); - iir = I915_READ(IIR); if (IS_I965G(dev)) { - vblank_status = I915_START_VBLANK_INTERRUPT_STATUS; + vblank_status = PIPE_START_VBLANK_INTERRUPT_STATUS; vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE; } else { vblank_status = I915_VBLANK_INTERRUPT_STATUS; @@ -352,7 +350,8 @@ if (ret == -ERESTART) DRM_DEBUG("restarting syscall\n"); - if (ret == -EBUSY) { + if (ret == -EWOULDBLOCK) { + /* ret = -EBUSY; */ DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", READ_BREADCRUMB(dev_priv), (int)dev_priv->counter); } @@ -408,11 +407,8 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - u32 pipeconf; - pipeconf = I915_READ(pipeconf_reg); - if (!(pipeconf & PIPEACONF_ENABLE)) + if (!i915_pipe_enabled(dev, pipe)) return -EINVAL; DRM_SPINLOCK(&dev_priv->user_irq_lock); @@ -500,8 +496,6 @@ { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - atomic_set_int(&dev_priv->irq_received, 0); - I915_WRITE(HWSTAM, 0xeffe); I915_WRITE(PIPEASTAT, 0); I915_WRITE(PIPEBSTAT, 0); @@ -521,10 +515,12 @@ /* Unmask the interrupts that we always want on. */ dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX; - dev_priv->pipestat[0] = 0; - dev_priv->pipestat[1] = 0; - /* Disable pipe interrupt enables, clear pending pipe status */ + /* + * If you driver is going to be brain-damaged and setup + * vblank interrupts before you install the handler, then + * you can't nuke it here. + */ I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); @@ -533,6 +529,10 @@ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); I915_WRITE(IMR, dev_priv->irq_mask_reg); + I915_WRITE(PIPEASTAT, dev_priv->pipestat[0] | + (dev_priv->pipestat[0] >> 16)); + I915_WRITE(PIPEBSTAT, dev_priv->pipestat[1] | + (dev_priv->pipestat[1] >> 16)); (void) I915_READ(IER); return 0; Index: i915_dma.c =================================================================== --- i915_dma.c (revision 190607) +++ i915_dma.c (working copy) @@ -444,6 +444,8 @@ if (dev_priv->sarea_priv) dev_priv->sarea_priv->last_enqueue = dev_priv->counter; + DRM_DEBUG("emitting: %d\n", dev_priv->counter); + BEGIN_LP_RING(4); OUT_RING(MI_STORE_DWORD_INDEX); OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); @@ -481,6 +483,7 @@ } i915_emit_breadcrumb(dev); + return 0; } @@ -871,6 +874,8 @@ ret = drm_addmap(dev, base, size, _DRM_REGISTERS, _DRM_KERNEL | _DRM_DRIVER, &dev_priv->mmio_map); + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + if (IS_GM45(dev)) dev->driver->get_vblank_counter = gm45_get_vblank_counter; else Index: radeon_drv.h =================================================================== --- radeon_drv.h (revision 190607) +++ radeon_drv.h (working copy) @@ -309,7 +309,6 @@ atomic_t swi_emitted; int vblank_crtc; uint32_t irq_enable_reg; - int irq_enabled; uint32_t r500_disp_irq_reg; struct radeon_surface surfaces[RADEON_MAX_SURFACES]; Index: drmP.h =================================================================== --- drmP.h (revision 190607) +++ drmP.h (working copy) @@ -791,10 +791,7 @@ /* IRQ support (drm_irq.c) */ int drm_irq_install(struct drm_device *dev); int drm_irq_uninstall(struct drm_device *dev); -irqreturn_t drm_irq_handler(DRM_IRQ_ARGS); -void drm_driver_irq_preinstall(struct drm_device *dev); -void drm_driver_irq_postinstall(struct drm_device *dev); -void drm_driver_irq_uninstall(struct drm_device *dev); +irqreturn_t drm_irq_handler_wrap(DRM_IRQ_ARGS); 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); Index: drm_drv.c =================================================================== --- drm_drv.c (revision 190607) +++ drm_drv.c (working copy) @@ -201,14 +201,8 @@ unit = device_get_unit(kdev); dev = device_get_softc(kdev); -#if __FreeBSD_version < 700010 - if (!strcmp(device_get_name(kdev), "drmsub")) - dev->device = device_get_parent(kdev); - else - dev->device = kdev; -#else dev->device = kdev; -#endif + dev->devnode = make_dev(&drm_cdevsw, unit, DRM_DEV_UID, @@ -216,49 +210,45 @@ DRM_DEV_MODE, "dri/card%d", unit); -#if __FreeBSD_version >= 700053 - dev->pci_domain = pci_get_domain(dev->device); -#else - dev->pci_domain = 0; -#endif - dev->pci_bus = pci_get_bus(dev->device); - dev->pci_slot = pci_get_slot(dev->device); - dev->pci_func = pci_get_function(dev->device); + dev->pci_domain = pci_get_domain(kdev); + dev->pci_bus = pci_get_bus(kdev); + dev->pci_slot = pci_get_slot(kdev); + dev->pci_func = pci_get_function(kdev); - dev->pci_vendor = pci_get_vendor(dev->device); - dev->pci_device = pci_get_device(dev->device); + dev->pci_vendor = pci_get_vendor(kdev); + dev->pci_device = pci_get_device(kdev); if (drm_msi && !drm_msi_is_blacklisted(dev->pci_vendor, dev->pci_device)) { - msicount = pci_msi_count(dev->device); + msicount = pci_msi_count(kdev); DRM_DEBUG("MSI count = %d\n", msicount); if (msicount > 1) msicount = 1; - if (pci_alloc_msi(dev->device, &msicount) == 0) { + if (pci_alloc_msi(kdev, &msicount) == 0) { DRM_INFO("MSI enabled %d message(s)\n", msicount); dev->msi_enabled = 1; dev->irqrid = 1; } } - dev->irqr = bus_alloc_resource_any(dev->device, SYS_RES_IRQ, - &dev->irqrid, RF_SHAREABLE); + dev->irqr = bus_alloc_resource_any(kdev, SYS_RES_IRQ, + &dev->irqrid, RF_ACTIVE | RF_SHAREABLE); if (!dev->irqr) { return ENOENT; } dev->irq = (int) rman_get_start(dev->irqr); + id_entry = drm_find_description(dev->pci_vendor, + dev->pci_device, idlist); + dev->id_entry = id_entry; + mtx_init(&dev->dev_lock, "drmdev", NULL, MTX_DEF); mtx_init(&dev->irq_lock, "drmirq", NULL, MTX_DEF); mtx_init(&dev->vbl_lock, "drmvbl", NULL, MTX_DEF); mtx_init(&dev->drw_lock, "drmdrw", NULL, MTX_DEF); - id_entry = drm_find_description(dev->pci_vendor, - dev->pci_device, idlist); - dev->id_entry = id_entry; - return drm_load(dev); } @@ -422,7 +412,7 @@ static int drm_load(struct drm_device *dev) { - int i, retcode; + int i, intr_flags, retcode; DRM_DEBUG("\n"); @@ -448,13 +438,29 @@ /* Shared code returns -errno. */ retcode = -dev->driver->load(dev, dev->id_entry->driver_private); - if (pci_enable_busmaster(dev->device)) - DRM_ERROR("Request to enable bus-master failed.\n"); DRM_UNLOCK(); if (retcode != 0) goto error; } + /* Enable busmastering */ + if (pci_enable_busmaster(dev->device)) + DRM_ERROR("Request to enable bus-master failed.\n"); + + /* Install the interrupt handler */ + if(dev->driver->irq_preinstall) { + DRM_LOCK(); + dev->driver->irq_preinstall(dev); + DRM_UNLOCK(); + } + intr_flags = INTR_TYPE_TTY | INTR_MPSAFE; + if (dev->msi_enabled) + intr_flags |= INTR_EXCL; + retcode = bus_setup_intr(dev->device, dev->irqr, intr_flags, NULL, + drm_irq_handler_wrap, dev, &dev->irqh); + if (retcode != 0) + goto error; + if (drm_core_has_AGP(dev)) { if (drm_device_is_agp(dev)) dev->agp = drm_agp_init(); @@ -527,12 +533,18 @@ DRM_DEBUG("mtrr_del = %d", retcode); } - drm_vblank_cleanup(dev); - DRM_LOCK(); drm_lastclose(dev); DRM_UNLOCK(); + if (bus_teardown_intr(dev->device, dev->irqr, dev->irqh)) + DRM_ERROR("bus_teardown_intr failed!\n"); + + drm_vblank_cleanup(dev); + + if (pci_disable_busmaster(dev->device)) + DRM_ERROR("pci_disable_busmaster failed!\n"); + /* Clean up PCI resources allocated by drm_bufs.c. We're not really * worried about resource consumption while the DRM is inactive (between * lastclose and firstopen or unload) because these aren't actually @@ -561,9 +573,6 @@ drm_mem_uninit(); - if (pci_disable_busmaster(dev->device)) - DRM_ERROR("Request to disable bus-master failed.\n"); - mtx_destroy(&dev->drw_lock); mtx_destroy(&dev->vbl_lock); mtx_destroy(&dev->irq_lock); Index: i915_drv.c =================================================================== --- i915_drv.c (revision 190607) +++ i915_drv.c (working copy) @@ -52,7 +52,10 @@ return -ENODEV; } + DRM_LOCK(); + DRM_DEBUG("starting suspend\n"); i915_save_state(dev); + DRM_UNLOCK(); return (bus_generic_suspend(kdev)); } @@ -61,7 +64,10 @@ { struct drm_device *dev = device_get_softc(kdev); + DRM_LOCK(); + DRM_DEBUG("starting resume\n"); i915_restore_state(dev); + DRM_UNLOCK(); return (bus_generic_resume(kdev)); } Index: i915_drv.h =================================================================== --- i915_drv.h (revision 190607) +++ i915_drv.h (working copy) @@ -129,12 +129,11 @@ int page_flipping; wait_queue_head_t irq_queue; - atomic_t irq_received; /** Protects user_irq_refcount and irq_mask_reg */ DRM_SPINTYPE user_irq_lock; /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ int user_irq_refcount; - /** Cached value of IER to avoid reads in updating the bitfield */ + /** Cached value of IMR to avoid reads in updating the bitfield */ u32 irq_mask_reg; u32 pipestat[2]; Index: mga_irq.c =================================================================== --- mga_irq.c (revision 190607) +++ mga_irq.c (working copy) @@ -178,6 +178,4 @@ /* Disable *all* interrupts */ MGA_WRITE(MGA_IEN, 0); - - dev->irq_enabled = 0; } Index: radeon_irq.c =================================================================== --- radeon_irq.c (revision 190607) +++ radeon_irq.c (working copy) @@ -380,8 +380,6 @@ atomic_set(&dev_priv->swi_emitted, 0); DRM_INIT_WAITQUEUE(&dev_priv->swi_queue); - dev->max_vblank_count = 0x001fffff; - radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1); return 0; @@ -394,8 +392,6 @@ if (!dev_priv) return; - dev_priv->irq_enabled = 0; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) RADEON_WRITE(R500_DxMODE_INT_MASK, 0); /* Disable *all* interrupts */ Index: drm_sysctl.c =================================================================== --- drm_sysctl.c (revision 190607) +++ drm_sysctl.c (working copy) @@ -38,6 +38,7 @@ static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS; static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS; static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS; +static int drm_vblank_info DRM_SYSCTL_HANDLER_ARGS; struct drm_sysctl_list { const char *name; @@ -47,6 +48,7 @@ {"vm", drm_vm_info}, {"clients", drm_clients_info}, {"bufs", drm_bufs_info}, + {"vblank", drm_vblank_info}, }; #define DRM_SYSCTL_ENTRIES (sizeof(drm_sysctl_list)/sizeof(drm_sysctl_list[0])) @@ -313,3 +315,25 @@ free(tempprivs, DRM_MEM_DRIVER); return retcode; } + +static int drm_vblank_info DRM_SYSCTL_HANDLER_ARGS +{ + struct drm_device *dev = arg1; + char buf[128]; + int retcode; + int i; + + DRM_SYSCTL_PRINT("\ncrtc ref count last enabled inmodeset\n"); + for(i = 0 ; i < dev->num_crtcs ; i++) { + DRM_SYSCTL_PRINT(" %02d %02d %08d %08d %02d %02d\n", + i, atomic_load_acq_32(&dev->vblank[i].refcount), + atomic_load_acq_32(&dev->vblank[i].count), + atomic_load_acq_32(&dev->vblank[i].last), + atomic_load_acq_int(&dev->vblank[i].enabled), + atomic_load_acq_int(&dev->vblank[i].inmodeset)); + } + + SYSCTL_OUT(req, "", -1); +done: + return retcode; +}