diff options
Diffstat (limited to 'drivers/gpu/drm/drm_fops.c')
-rw-r--r-- | drivers/gpu/drm/drm_fops.c | 77 |
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 | */ | ||
390 | static 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 | */ | ||
414 | int 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", |