|
@@ -267,7 +267,8 @@ EXPORT_SYMBOL(drm_irq_install);
|
|
*/
|
|
*/
|
|
int drm_irq_uninstall(struct drm_device * dev)
|
|
int drm_irq_uninstall(struct drm_device * dev)
|
|
{
|
|
{
|
|
- int irq_enabled;
|
|
|
|
|
|
+ unsigned long irqflags;
|
|
|
|
+ int irq_enabled, i;
|
|
|
|
|
|
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
|
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
@@ -277,6 +278,16 @@ int drm_irq_uninstall(struct drm_device * dev)
|
|
dev->irq_enabled = 0;
|
|
dev->irq_enabled = 0;
|
|
mutex_unlock(&dev->struct_mutex);
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Wake up any waiters so they don't hang.
|
|
|
|
+ */
|
|
|
|
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
|
|
|
|
+ for (i = 0; i < dev->num_crtcs; i++) {
|
|
|
|
+ DRM_WAKEUP(&dev->vbl_queue[i]);
|
|
|
|
+ dev->vblank_enabled[i] = 0;
|
|
|
|
+ }
|
|
|
|
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
|
|
|
|
+
|
|
if (!irq_enabled)
|
|
if (!irq_enabled)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
@@ -652,8 +663,9 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
|
|
vblwait->request.sequence, crtc);
|
|
vblwait->request.sequence, crtc);
|
|
dev->last_vblank_wait[crtc] = vblwait->request.sequence;
|
|
dev->last_vblank_wait[crtc] = vblwait->request.sequence;
|
|
DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
|
|
DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
|
|
- ((drm_vblank_count(dev, crtc)
|
|
|
|
- - vblwait->request.sequence) <= (1 << 23)));
|
|
|
|
|
|
+ (((drm_vblank_count(dev, crtc) -
|
|
|
|
+ vblwait->request.sequence) <= (1 << 23)) ||
|
|
|
|
+ !dev->irq_enabled));
|
|
|
|
|
|
if (ret != -EINTR) {
|
|
if (ret != -EINTR) {
|
|
struct timeval now;
|
|
struct timeval now;
|