aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fops.c')
-rw-r--r--drivers/gpu/drm/drm_fops.c77
1 files changed, 71 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 22d14ecbd3ec..c5b929c3f77a 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -113,7 +113,6 @@ int drm_open(struct inode *inode, struct file *filp)
113 retcode = drm_open_helper(inode, filp, dev); 113 retcode = drm_open_helper(inode, filp, dev);
114 if (retcode) 114 if (retcode)
115 goto err_undo; 115 goto err_undo;
116 atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
117 if (need_setup) { 116 if (need_setup) {
118 retcode = drm_setup(dev); 117 retcode = drm_setup(dev);
119 if (retcode) 118 if (retcode)
@@ -235,7 +234,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
235 234
236 priv->ioctl_count = 0; 235 priv->ioctl_count = 0;
237 /* for compatibility root is always authenticated */ 236 /* for compatibility root is always authenticated */
238 priv->authenticated = capable(CAP_SYS_ADMIN); 237 priv->always_authenticated = capable(CAP_SYS_ADMIN);
238 priv->authenticated = priv->always_authenticated;
239 priv->lock_count = 0; 239 priv->lock_count = 0;
240 240
241 INIT_LIST_HEAD(&priv->lhead); 241 INIT_LIST_HEAD(&priv->lhead);
@@ -374,13 +374,80 @@ static void drm_events_release(struct drm_file *file_priv)
374 } 374 }
375 375
376 /* Remove unconsumed events */ 376 /* Remove unconsumed events */
377 list_for_each_entry_safe(e, et, &file_priv->event_list, link) 377 list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
378 list_del(&e->link);
378 e->destroy(e); 379 e->destroy(e);
380 }
379 381
380 spin_unlock_irqrestore(&dev->event_lock, flags); 382 spin_unlock_irqrestore(&dev->event_lock, flags);
381} 383}
382 384
383/** 385/**
386 * drm_legacy_dev_reinit
387 *
388 * Reinitializes a legacy/ums drm device in it's lastclose function.
389 */
390static void drm_legacy_dev_reinit(struct drm_device *dev)
391{
392 if (drm_core_check_feature(dev, DRIVER_MODESET))
393 return;
394
395 atomic_set(&dev->ioctl_count, 0);
396 atomic_set(&dev->vma_count, 0);
397
398 dev->sigdata.lock = NULL;
399
400 dev->context_flag = 0;
401 dev->last_context = 0;
402 dev->if_version = 0;
403}
404
405/**
406 * Take down the DRM device.
407 *
408 * \param dev DRM device structure.
409 *
410 * Frees every resource in \p dev.
411 *
412 * \sa drm_device
413 */
414int drm_lastclose(struct drm_device * dev)
415{
416 struct drm_vma_entry *vma, *vma_temp;
417
418 DRM_DEBUG("\n");
419
420 if (dev->driver->lastclose)
421 dev->driver->lastclose(dev);
422 DRM_DEBUG("driver lastclose completed\n");
423
424 if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
425 drm_irq_uninstall(dev);
426
427 mutex_lock(&dev->struct_mutex);
428
429 drm_agp_clear(dev);
430
431 drm_legacy_sg_cleanup(dev);
432
433 /* Clear vma list (only built for debugging) */
434 list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
435 list_del(&vma->head);
436 kfree(vma);
437 }
438
439 drm_legacy_dma_takedown(dev);
440
441 dev->dev_mapping = NULL;
442 mutex_unlock(&dev->struct_mutex);
443
444 drm_legacy_dev_reinit(dev);
445
446 DRM_DEBUG("lastclose completed\n");
447 return 0;
448}
449
450/**
384 * Release file. 451 * Release file.
385 * 452 *
386 * \param inode device inode 453 * \param inode device inode
@@ -449,7 +516,6 @@ int drm_release(struct inode *inode, struct file *filp)
449 516
450 list_del(&pos->head); 517 list_del(&pos->head);
451 kfree(pos); 518 kfree(pos);
452 --dev->ctx_count;
453 } 519 }
454 } 520 }
455 } 521 }
@@ -463,7 +529,7 @@ int drm_release(struct inode *inode, struct file *filp)
463 list_for_each_entry(temp, &dev->filelist, lhead) { 529 list_for_each_entry(temp, &dev->filelist, lhead) {
464 if ((temp->master == file_priv->master) && 530 if ((temp->master == file_priv->master) &&
465 (temp != file_priv)) 531 (temp != file_priv))
466 temp->authenticated = 0; 532 temp->authenticated = temp->always_authenticated;
467 } 533 }
468 534
469 /** 535 /**
@@ -511,7 +577,6 @@ int drm_release(struct inode *inode, struct file *filp)
511 * End inline drm_release 577 * End inline drm_release
512 */ 578 */
513 579
514 atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
515 if (!--dev->open_count) { 580 if (!--dev->open_count) {
516 if (atomic_read(&dev->ioctl_count)) { 581 if (atomic_read(&dev->ioctl_count)) {
517 DRM_ERROR("Device busy: %d\n", 582 DRM_ERROR("Device busy: %d\n",