drm: Remove the prefix argument of drm_ut_debug_printk()
[cascardo/linux.git] / drivers / gpu / drm / drm_stub.c
1 /**
2  * \file drm_stub.h
3  * Stub support
4  *
5  * \author Rickard E. (Rik) Faith <faith@valinux.com>
6  */
7
8 /*
9  * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
10  *
11  * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
12  * All Rights Reserved.
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining a
15  * copy of this software and associated documentation files (the "Software"),
16  * to deal in the Software without restriction, including without limitation
17  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18  * and/or sell copies of the Software, and to permit persons to whom the
19  * Software is furnished to do so, subject to the following conditions:
20  *
21  * The above copyright notice and this permission notice (including the next
22  * paragraph) shall be included in all copies or substantial portions of the
23  * Software.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
28  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31  * DEALINGS IN THE SOFTWARE.
32  */
33
34 #include <linux/fs.h>
35 #include <linux/module.h>
36 #include <linux/moduleparam.h>
37 #include <linux/mount.h>
38 #include <linux/slab.h>
39 #include <drm/drmP.h>
40 #include <drm/drm_core.h>
41
42 unsigned int drm_debug = 0;     /* 1 to enable debug output */
43 EXPORT_SYMBOL(drm_debug);
44
45 unsigned int drm_rnodes = 0;    /* 1 to enable experimental render nodes API */
46 EXPORT_SYMBOL(drm_rnodes);
47
48 unsigned int drm_vblank_offdelay = 5000;    /* Default to 5000 msecs. */
49 EXPORT_SYMBOL(drm_vblank_offdelay);
50
51 unsigned int drm_timestamp_precision = 20;  /* Default to 20 usecs. */
52 EXPORT_SYMBOL(drm_timestamp_precision);
53
54 /*
55  * Default to use monotonic timestamps for wait-for-vblank and page-flip
56  * complete events.
57  */
58 unsigned int drm_timestamp_monotonic = 1;
59
60 MODULE_AUTHOR(CORE_AUTHOR);
61 MODULE_DESCRIPTION(CORE_DESC);
62 MODULE_LICENSE("GPL and additional rights");
63 MODULE_PARM_DESC(debug, "Enable debug output");
64 MODULE_PARM_DESC(rnodes, "Enable experimental render nodes API");
65 MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]");
66 MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
67 MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
68
69 module_param_named(debug, drm_debug, int, 0600);
70 module_param_named(rnodes, drm_rnodes, int, 0600);
71 module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
72 module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
73 module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
74
75 static DEFINE_SPINLOCK(drm_minor_lock);
76 struct idr drm_minors_idr;
77
78 struct class *drm_class;
79 struct dentry *drm_debugfs_root;
80
81 int drm_err(const char *func, const char *format, ...)
82 {
83         struct va_format vaf;
84         va_list args;
85         int r;
86
87         va_start(args, format);
88
89         vaf.fmt = format;
90         vaf.va = &args;
91
92         r = printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf);
93
94         va_end(args);
95
96         return r;
97 }
98 EXPORT_SYMBOL(drm_err);
99
100 void drm_ut_debug_printk(const char *function_name, const char *format, ...)
101 {
102         struct va_format vaf;
103         va_list args;
104
105         va_start(args, format);
106         vaf.fmt = format;
107         vaf.va = &args;
108
109         printk(KERN_DEBUG "[" DRM_NAME ":%s], %pV", function_name, &vaf);
110
111         va_end(args);
112 }
113 EXPORT_SYMBOL(drm_ut_debug_printk);
114
115 struct drm_master *drm_master_create(struct drm_minor *minor)
116 {
117         struct drm_master *master;
118
119         master = kzalloc(sizeof(*master), GFP_KERNEL);
120         if (!master)
121                 return NULL;
122
123         kref_init(&master->refcount);
124         spin_lock_init(&master->lock.spinlock);
125         init_waitqueue_head(&master->lock.lock_queue);
126         drm_ht_create(&master->magiclist, DRM_MAGIC_HASH_ORDER);
127         INIT_LIST_HEAD(&master->magicfree);
128         master->minor = minor;
129
130         list_add_tail(&master->head, &minor->master_list);
131
132         return master;
133 }
134
135 struct drm_master *drm_master_get(struct drm_master *master)
136 {
137         kref_get(&master->refcount);
138         return master;
139 }
140 EXPORT_SYMBOL(drm_master_get);
141
142 static void drm_master_destroy(struct kref *kref)
143 {
144         struct drm_master *master = container_of(kref, struct drm_master, refcount);
145         struct drm_magic_entry *pt, *next;
146         struct drm_device *dev = master->minor->dev;
147         struct drm_map_list *r_list, *list_temp;
148
149         list_del(&master->head);
150
151         if (dev->driver->master_destroy)
152                 dev->driver->master_destroy(dev, master);
153
154         list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) {
155                 if (r_list->master == master) {
156                         drm_rmmap_locked(dev, r_list->map);
157                         r_list = NULL;
158                 }
159         }
160
161         if (master->unique) {
162                 kfree(master->unique);
163                 master->unique = NULL;
164                 master->unique_len = 0;
165         }
166
167         kfree(dev->devname);
168         dev->devname = NULL;
169
170         list_for_each_entry_safe(pt, next, &master->magicfree, head) {
171                 list_del(&pt->head);
172                 drm_ht_remove_item(&master->magiclist, &pt->hash_item);
173                 kfree(pt);
174         }
175
176         drm_ht_remove(&master->magiclist);
177
178         kfree(master);
179 }
180
181 void drm_master_put(struct drm_master **master)
182 {
183         kref_put(&(*master)->refcount, drm_master_destroy);
184         *master = NULL;
185 }
186 EXPORT_SYMBOL(drm_master_put);
187
188 int drm_setmaster_ioctl(struct drm_device *dev, void *data,
189                         struct drm_file *file_priv)
190 {
191         int ret = 0;
192
193         if (file_priv->is_master)
194                 return 0;
195
196         if (file_priv->minor->master && file_priv->minor->master != file_priv->master)
197                 return -EINVAL;
198
199         if (!file_priv->master)
200                 return -EINVAL;
201
202         if (file_priv->minor->master)
203                 return -EINVAL;
204
205         mutex_lock(&dev->struct_mutex);
206         file_priv->minor->master = drm_master_get(file_priv->master);
207         file_priv->is_master = 1;
208         if (dev->driver->master_set) {
209                 ret = dev->driver->master_set(dev, file_priv, false);
210                 if (unlikely(ret != 0)) {
211                         file_priv->is_master = 0;
212                         drm_master_put(&file_priv->minor->master);
213                 }
214         }
215         mutex_unlock(&dev->struct_mutex);
216
217         return ret;
218 }
219
220 int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
221                          struct drm_file *file_priv)
222 {
223         if (!file_priv->is_master)
224                 return -EINVAL;
225
226         if (!file_priv->minor->master)
227                 return -EINVAL;
228
229         mutex_lock(&dev->struct_mutex);
230         if (dev->driver->master_drop)
231                 dev->driver->master_drop(dev, file_priv, false);
232         drm_master_put(&file_priv->minor->master);
233         file_priv->is_master = 0;
234         mutex_unlock(&dev->struct_mutex);
235         return 0;
236 }
237
238 /*
239  * DRM Minors
240  * A DRM device can provide several char-dev interfaces on the DRM-Major. Each
241  * of them is represented by a drm_minor object. Depending on the capabilities
242  * of the device-driver, different interfaces are registered.
243  *
244  * Minors can be accessed via dev->$minor_name. This pointer is either
245  * NULL or a valid drm_minor pointer and stays valid as long as the device is
246  * valid. This means, DRM minors have the same life-time as the underlying
247  * device. However, this doesn't mean that the minor is active. Minors are
248  * registered and unregistered dynamically according to device-state.
249  */
250
251 static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
252                                              unsigned int type)
253 {
254         switch (type) {
255         case DRM_MINOR_LEGACY:
256                 return &dev->primary;
257         case DRM_MINOR_RENDER:
258                 return &dev->render;
259         case DRM_MINOR_CONTROL:
260                 return &dev->control;
261         default:
262                 return NULL;
263         }
264 }
265
266 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
267 {
268         struct drm_minor *minor;
269
270         minor = kzalloc(sizeof(*minor), GFP_KERNEL);
271         if (!minor)
272                 return -ENOMEM;
273
274         minor->type = type;
275         minor->dev = dev;
276         INIT_LIST_HEAD(&minor->master_list);
277
278         *drm_minor_get_slot(dev, type) = minor;
279         return 0;
280 }
281
282 static void drm_minor_free(struct drm_device *dev, unsigned int type)
283 {
284         struct drm_minor **slot;
285
286         slot = drm_minor_get_slot(dev, type);
287         if (*slot) {
288                 kfree(*slot);
289                 *slot = NULL;
290         }
291 }
292
293 static int drm_minor_register(struct drm_device *dev, unsigned int type)
294 {
295         struct drm_minor *new_minor;
296         unsigned long flags;
297         int ret;
298         int minor_id;
299
300         DRM_DEBUG("\n");
301
302         new_minor = *drm_minor_get_slot(dev, type);
303         if (!new_minor)
304                 return 0;
305
306         idr_preload(GFP_KERNEL);
307         spin_lock_irqsave(&drm_minor_lock, flags);
308         minor_id = idr_alloc(&drm_minors_idr,
309                              NULL,
310                              64 * type,
311                              64 * (type + 1),
312                              GFP_NOWAIT);
313         spin_unlock_irqrestore(&drm_minor_lock, flags);
314         idr_preload_end();
315
316         if (minor_id < 0)
317                 return minor_id;
318
319         new_minor->index = minor_id;
320
321         ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root);
322         if (ret) {
323                 DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n");
324                 goto err_id;
325         }
326
327         ret = drm_sysfs_device_add(new_minor);
328         if (ret) {
329                 DRM_ERROR("DRM: Error sysfs_device_add.\n");
330                 goto err_debugfs;
331         }
332
333         /* replace NULL with @minor so lookups will succeed from now on */
334         spin_lock_irqsave(&drm_minor_lock, flags);
335         idr_replace(&drm_minors_idr, new_minor, new_minor->index);
336         spin_unlock_irqrestore(&drm_minor_lock, flags);
337
338         DRM_DEBUG("new minor assigned %d\n", minor_id);
339         return 0;
340
341 err_debugfs:
342         drm_debugfs_cleanup(new_minor);
343 err_id:
344         spin_lock_irqsave(&drm_minor_lock, flags);
345         idr_remove(&drm_minors_idr, minor_id);
346         spin_unlock_irqrestore(&drm_minor_lock, flags);
347         new_minor->index = 0;
348         return ret;
349 }
350
351 static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
352 {
353         struct drm_minor *minor;
354         unsigned long flags;
355
356         minor = *drm_minor_get_slot(dev, type);
357         if (!minor || !minor->kdev)
358                 return;
359
360         spin_lock_irqsave(&drm_minor_lock, flags);
361         idr_remove(&drm_minors_idr, minor->index);
362         spin_unlock_irqrestore(&drm_minor_lock, flags);
363         minor->index = 0;
364
365         drm_debugfs_cleanup(minor);
366         drm_sysfs_device_remove(minor);
367 }
368
369 /**
370  * drm_minor_acquire - Acquire a DRM minor
371  * @minor_id: Minor ID of the DRM-minor
372  *
373  * Looks up the given minor-ID and returns the respective DRM-minor object. The
374  * refence-count of the underlying device is increased so you must release this
375  * object with drm_minor_release().
376  *
377  * As long as you hold this minor, it is guaranteed that the object and the
378  * minor->dev pointer will stay valid! However, the device may get unplugged and
379  * unregistered while you hold the minor.
380  *
381  * Returns:
382  * Pointer to minor-object with increased device-refcount, or PTR_ERR on
383  * failure.
384  */
385 struct drm_minor *drm_minor_acquire(unsigned int minor_id)
386 {
387         struct drm_minor *minor;
388         unsigned long flags;
389
390         spin_lock_irqsave(&drm_minor_lock, flags);
391         minor = idr_find(&drm_minors_idr, minor_id);
392         if (minor)
393                 drm_dev_ref(minor->dev);
394         spin_unlock_irqrestore(&drm_minor_lock, flags);
395
396         if (!minor) {
397                 return ERR_PTR(-ENODEV);
398         } else if (drm_device_is_unplugged(minor->dev)) {
399                 drm_dev_unref(minor->dev);
400                 return ERR_PTR(-ENODEV);
401         }
402
403         return minor;
404 }
405
406 /**
407  * drm_minor_release - Release DRM minor
408  * @minor: Pointer to DRM minor object
409  *
410  * Release a minor that was previously acquired via drm_minor_acquire().
411  */
412 void drm_minor_release(struct drm_minor *minor)
413 {
414         drm_dev_unref(minor->dev);
415 }
416
417 /**
418  * Called via drm_exit() at module unload time or when pci device is
419  * unplugged.
420  *
421  * Cleans up all DRM device, calling drm_lastclose().
422  *
423  */
424 void drm_put_dev(struct drm_device *dev)
425 {
426         DRM_DEBUG("\n");
427
428         if (!dev) {
429                 DRM_ERROR("cleanup called no dev\n");
430                 return;
431         }
432
433         drm_dev_unregister(dev);
434         drm_dev_unref(dev);
435 }
436 EXPORT_SYMBOL(drm_put_dev);
437
438 void drm_unplug_dev(struct drm_device *dev)
439 {
440         /* for a USB device */
441         drm_minor_unregister(dev, DRM_MINOR_LEGACY);
442         drm_minor_unregister(dev, DRM_MINOR_RENDER);
443         drm_minor_unregister(dev, DRM_MINOR_CONTROL);
444
445         mutex_lock(&drm_global_mutex);
446
447         drm_device_set_unplugged(dev);
448
449         if (dev->open_count == 0) {
450                 drm_put_dev(dev);
451         }
452         mutex_unlock(&drm_global_mutex);
453 }
454 EXPORT_SYMBOL(drm_unplug_dev);
455
456 /*
457  * DRM internal mount
458  * We want to be able to allocate our own "struct address_space" to control
459  * memory-mappings in VRAM (or stolen RAM, ...). However, core MM does not allow
460  * stand-alone address_space objects, so we need an underlying inode. As there
461  * is no way to allocate an independent inode easily, we need a fake internal
462  * VFS mount-point.
463  *
464  * The drm_fs_inode_new() function allocates a new inode, drm_fs_inode_free()
465  * frees it again. You are allowed to use iget() and iput() to get references to
466  * the inode. But each drm_fs_inode_new() call must be paired with exactly one
467  * drm_fs_inode_free() call (which does not have to be the last iput()).
468  * We use drm_fs_inode_*() to manage our internal VFS mount-point and share it
469  * between multiple inode-users. You could, technically, call
470  * iget() + drm_fs_inode_free() directly after alloc and sometime later do an
471  * iput(), but this way you'd end up with a new vfsmount for each inode.
472  */
473
474 static int drm_fs_cnt;
475 static struct vfsmount *drm_fs_mnt;
476
477 static const struct dentry_operations drm_fs_dops = {
478         .d_dname        = simple_dname,
479 };
480
481 static const struct super_operations drm_fs_sops = {
482         .statfs         = simple_statfs,
483 };
484
485 static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags,
486                                    const char *dev_name, void *data)
487 {
488         return mount_pseudo(fs_type,
489                             "drm:",
490                             &drm_fs_sops,
491                             &drm_fs_dops,
492                             0x010203ff);
493 }
494
495 static struct file_system_type drm_fs_type = {
496         .name           = "drm",
497         .owner          = THIS_MODULE,
498         .mount          = drm_fs_mount,
499         .kill_sb        = kill_anon_super,
500 };
501
502 static struct inode *drm_fs_inode_new(void)
503 {
504         struct inode *inode;
505         int r;
506
507         r = simple_pin_fs(&drm_fs_type, &drm_fs_mnt, &drm_fs_cnt);
508         if (r < 0) {
509                 DRM_ERROR("Cannot mount pseudo fs: %d\n", r);
510                 return ERR_PTR(r);
511         }
512
513         inode = alloc_anon_inode(drm_fs_mnt->mnt_sb);
514         if (IS_ERR(inode))
515                 simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
516
517         return inode;
518 }
519
520 static void drm_fs_inode_free(struct inode *inode)
521 {
522         if (inode) {
523                 iput(inode);
524                 simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
525         }
526 }
527
528 /**
529  * drm_dev_alloc - Allocate new drm device
530  * @driver: DRM driver to allocate device for
531  * @parent: Parent device object
532  *
533  * Allocate and initialize a new DRM device. No device registration is done.
534  * Call drm_dev_register() to advertice the device to user space and register it
535  * with other core subsystems.
536  *
537  * The initial ref-count of the object is 1. Use drm_dev_ref() and
538  * drm_dev_unref() to take and drop further ref-counts.
539  *
540  * RETURNS:
541  * Pointer to new DRM device, or NULL if out of memory.
542  */
543 struct drm_device *drm_dev_alloc(struct drm_driver *driver,
544                                  struct device *parent)
545 {
546         struct drm_device *dev;
547         int ret;
548
549         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
550         if (!dev)
551                 return NULL;
552
553         kref_init(&dev->ref);
554         dev->dev = parent;
555         dev->driver = driver;
556
557         INIT_LIST_HEAD(&dev->filelist);
558         INIT_LIST_HEAD(&dev->ctxlist);
559         INIT_LIST_HEAD(&dev->vmalist);
560         INIT_LIST_HEAD(&dev->maplist);
561         INIT_LIST_HEAD(&dev->vblank_event_list);
562
563         spin_lock_init(&dev->count_lock);
564         spin_lock_init(&dev->event_lock);
565         mutex_init(&dev->struct_mutex);
566         mutex_init(&dev->ctxlist_mutex);
567
568         dev->anon_inode = drm_fs_inode_new();
569         if (IS_ERR(dev->anon_inode)) {
570                 ret = PTR_ERR(dev->anon_inode);
571                 DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
572                 goto err_free;
573         }
574
575         if (drm_core_check_feature(dev, DRIVER_MODESET)) {
576                 ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
577                 if (ret)
578                         goto err_minors;
579         }
580
581         if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
582                 ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
583                 if (ret)
584                         goto err_minors;
585         }
586
587         ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
588         if (ret)
589                 goto err_minors;
590
591         if (drm_ht_create(&dev->map_hash, 12))
592                 goto err_minors;
593
594         ret = drm_ctxbitmap_init(dev);
595         if (ret) {
596                 DRM_ERROR("Cannot allocate memory for context bitmap.\n");
597                 goto err_ht;
598         }
599
600         if (driver->driver_features & DRIVER_GEM) {
601                 ret = drm_gem_init(dev);
602                 if (ret) {
603                         DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
604                         goto err_ctxbitmap;
605                 }
606         }
607
608         return dev;
609
610 err_ctxbitmap:
611         drm_ctxbitmap_cleanup(dev);
612 err_ht:
613         drm_ht_remove(&dev->map_hash);
614 err_minors:
615         drm_minor_free(dev, DRM_MINOR_LEGACY);
616         drm_minor_free(dev, DRM_MINOR_RENDER);
617         drm_minor_free(dev, DRM_MINOR_CONTROL);
618         drm_fs_inode_free(dev->anon_inode);
619 err_free:
620         kfree(dev);
621         return NULL;
622 }
623 EXPORT_SYMBOL(drm_dev_alloc);
624
625 static void drm_dev_release(struct kref *ref)
626 {
627         struct drm_device *dev = container_of(ref, struct drm_device, ref);
628
629         if (dev->driver->driver_features & DRIVER_GEM)
630                 drm_gem_destroy(dev);
631
632         drm_ctxbitmap_cleanup(dev);
633         drm_ht_remove(&dev->map_hash);
634         drm_fs_inode_free(dev->anon_inode);
635
636         drm_minor_free(dev, DRM_MINOR_LEGACY);
637         drm_minor_free(dev, DRM_MINOR_RENDER);
638         drm_minor_free(dev, DRM_MINOR_CONTROL);
639
640         kfree(dev->devname);
641         kfree(dev);
642 }
643
644 /**
645  * drm_dev_ref - Take reference of a DRM device
646  * @dev: device to take reference of or NULL
647  *
648  * This increases the ref-count of @dev by one. You *must* already own a
649  * reference when calling this. Use drm_dev_unref() to drop this reference
650  * again.
651  *
652  * This function never fails. However, this function does not provide *any*
653  * guarantee whether the device is alive or running. It only provides a
654  * reference to the object and the memory associated with it.
655  */
656 void drm_dev_ref(struct drm_device *dev)
657 {
658         if (dev)
659                 kref_get(&dev->ref);
660 }
661 EXPORT_SYMBOL(drm_dev_ref);
662
663 /**
664  * drm_dev_unref - Drop reference of a DRM device
665  * @dev: device to drop reference of or NULL
666  *
667  * This decreases the ref-count of @dev by one. The device is destroyed if the
668  * ref-count drops to zero.
669  */
670 void drm_dev_unref(struct drm_device *dev)
671 {
672         if (dev)
673                 kref_put(&dev->ref, drm_dev_release);
674 }
675 EXPORT_SYMBOL(drm_dev_unref);
676
677 /**
678  * drm_dev_register - Register DRM device
679  * @dev: Device to register
680  *
681  * Register the DRM device @dev with the system, advertise device to user-space
682  * and start normal device operation. @dev must be allocated via drm_dev_alloc()
683  * previously.
684  *
685  * Never call this twice on any device!
686  *
687  * RETURNS:
688  * 0 on success, negative error code on failure.
689  */
690 int drm_dev_register(struct drm_device *dev, unsigned long flags)
691 {
692         int ret;
693
694         mutex_lock(&drm_global_mutex);
695
696         ret = drm_minor_register(dev, DRM_MINOR_CONTROL);
697         if (ret)
698                 goto err_minors;
699
700         ret = drm_minor_register(dev, DRM_MINOR_RENDER);
701         if (ret)
702                 goto err_minors;
703
704         ret = drm_minor_register(dev, DRM_MINOR_LEGACY);
705         if (ret)
706                 goto err_minors;
707
708         if (dev->driver->load) {
709                 ret = dev->driver->load(dev, flags);
710                 if (ret)
711                         goto err_minors;
712         }
713
714         /* setup grouping for legacy outputs */
715         if (drm_core_check_feature(dev, DRIVER_MODESET)) {
716                 ret = drm_mode_group_init_legacy_group(dev,
717                                 &dev->primary->mode_group);
718                 if (ret)
719                         goto err_unload;
720         }
721
722         ret = 0;
723         goto out_unlock;
724
725 err_unload:
726         if (dev->driver->unload)
727                 dev->driver->unload(dev);
728 err_minors:
729         drm_minor_unregister(dev, DRM_MINOR_LEGACY);
730         drm_minor_unregister(dev, DRM_MINOR_RENDER);
731         drm_minor_unregister(dev, DRM_MINOR_CONTROL);
732 out_unlock:
733         mutex_unlock(&drm_global_mutex);
734         return ret;
735 }
736 EXPORT_SYMBOL(drm_dev_register);
737
738 /**
739  * drm_dev_unregister - Unregister DRM device
740  * @dev: Device to unregister
741  *
742  * Unregister the DRM device from the system. This does the reverse of
743  * drm_dev_register() but does not deallocate the device. The caller must call
744  * drm_dev_unref() to drop their final reference.
745  */
746 void drm_dev_unregister(struct drm_device *dev)
747 {
748         struct drm_map_list *r_list, *list_temp;
749
750         drm_lastclose(dev);
751
752         if (dev->driver->unload)
753                 dev->driver->unload(dev);
754
755         if (dev->agp)
756                 drm_pci_agp_destroy(dev);
757
758         drm_vblank_cleanup(dev);
759
760         list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
761                 drm_rmmap(dev, r_list->map);
762
763         drm_minor_unregister(dev, DRM_MINOR_LEGACY);
764         drm_minor_unregister(dev, DRM_MINOR_RENDER);
765         drm_minor_unregister(dev, DRM_MINOR_CONTROL);
766 }
767 EXPORT_SYMBOL(drm_dev_unregister);