diff options
Diffstat (limited to 'drivers/char/drm/drm_fops.c')
-rw-r--r-- | drivers/char/drm/drm_fops.c | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 314abd9d6510..3b159cab3bc8 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -356,58 +356,56 @@ int drm_release(struct inode *inode, struct file *filp) | |||
356 | current->pid, (long)old_encode_dev(priv->head->device), | 356 | current->pid, (long)old_encode_dev(priv->head->device), |
357 | dev->open_count); | 357 | dev->open_count); |
358 | 358 | ||
359 | if (priv->lock_count && dev->lock.hw_lock && | 359 | if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { |
360 | _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && | 360 | if (drm_i_have_hw_lock(filp)) { |
361 | dev->lock.filp == filp) { | ||
362 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | ||
363 | filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | ||
364 | |||
365 | if (dev->driver->reclaim_buffers_locked) | ||
366 | dev->driver->reclaim_buffers_locked(dev, filp); | 361 | dev->driver->reclaim_buffers_locked(dev, filp); |
367 | 362 | } else { | |
368 | drm_lock_free(dev, &dev->lock.hw_lock->lock, | 363 | unsigned long _end=jiffies + 3*DRM_HZ; |
369 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | 364 | int locked = 0; |
370 | 365 | ||
371 | /* FIXME: may require heavy-handed reset of | 366 | drm_idlelock_take(&dev->lock); |
372 | hardware at this point, possibly | 367 | |
373 | processed via a callback to the X | 368 | /* |
374 | server. */ | 369 | * Wait for a while. |
375 | } else if (dev->driver->reclaim_buffers_locked && priv->lock_count | 370 | */ |
376 | && dev->lock.hw_lock) { | 371 | |
377 | /* The lock is required to reclaim buffers */ | 372 | do{ |
378 | DECLARE_WAITQUEUE(entry, current); | 373 | spin_lock(&dev->lock.spinlock); |
379 | 374 | locked = dev->lock.idle_has_lock; | |
380 | add_wait_queue(&dev->lock.lock_queue, &entry); | 375 | spin_unlock(&dev->lock.spinlock); |
381 | for (;;) { | 376 | if (locked) |
382 | __set_current_state(TASK_INTERRUPTIBLE); | 377 | break; |
383 | if (!dev->lock.hw_lock) { | 378 | schedule(); |
384 | /* Device has been unregistered */ | 379 | } while (!time_after_eq(jiffies, _end)); |
385 | retcode = -EINTR; | 380 | |
386 | break; | 381 | if (!locked) { |
382 | DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" | ||
383 | "\tdriver to use reclaim_buffers_idlelocked() instead.\n" | ||
384 | "\tI will go on reclaiming the buffers anyway.\n"); | ||
387 | } | 385 | } |
388 | if (drm_lock_take(&dev->lock.hw_lock->lock, | 386 | |
389 | DRM_KERNEL_CONTEXT)) { | ||
390 | dev->lock.filp = filp; | ||
391 | dev->lock.lock_time = jiffies; | ||
392 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | ||
393 | break; /* Got lock */ | ||
394 | } | ||
395 | /* Contention */ | ||
396 | schedule(); | ||
397 | if (signal_pending(current)) { | ||
398 | retcode = -ERESTARTSYS; | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | __set_current_state(TASK_RUNNING); | ||
403 | remove_wait_queue(&dev->lock.lock_queue, &entry); | ||
404 | if (!retcode) { | ||
405 | dev->driver->reclaim_buffers_locked(dev, filp); | 387 | dev->driver->reclaim_buffers_locked(dev, filp); |
406 | drm_lock_free(dev, &dev->lock.hw_lock->lock, | 388 | drm_idlelock_release(&dev->lock); |
407 | DRM_KERNEL_CONTEXT); | ||
408 | } | 389 | } |
409 | } | 390 | } |
410 | 391 | ||
392 | if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) { | ||
393 | |||
394 | drm_idlelock_take(&dev->lock); | ||
395 | dev->driver->reclaim_buffers_idlelocked(dev, filp); | ||
396 | drm_idlelock_release(&dev->lock); | ||
397 | |||
398 | } | ||
399 | |||
400 | if (drm_i_have_hw_lock(filp)) { | ||
401 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | ||
402 | filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | ||
403 | |||
404 | drm_lock_free(&dev->lock, | ||
405 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | ||
406 | } | ||
407 | |||
408 | |||
411 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && | 409 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && |
412 | !dev->driver->reclaim_buffers_locked) { | 410 | !dev->driver->reclaim_buffers_locked) { |
413 | dev->driver->reclaim_buffers(dev, filp); | 411 | dev->driver->reclaim_buffers(dev, filp); |