1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <linux/debugfs.h>
30#include <linux/fs.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
33#include <linux/mount.h>
34#include <linux/slab.h>
35#include <linux/srcu.h>
36
37#include <drm/drm_client.h>
38#include <drm/drm_drv.h>
39#include <drm/drmP.h>
40
41#include "drm_crtc_internal.h"
42#include "drm_legacy.h"
43#include "drm_internal.h"
44
45
46
47
48
49unsigned int drm_debug = 0;
50EXPORT_SYMBOL(drm_debug);
51
52MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl");
53MODULE_DESCRIPTION("DRM shared core routines");
54MODULE_LICENSE("GPL and additional rights");
55MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug category.\n"
56"\t\tBit 0 (0x01) will enable CORE messages (drm core code)\n"
57"\t\tBit 1 (0x02) will enable DRIVER messages (drm controller code)\n"
58"\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
59"\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
60"\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
61"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
62"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)\n"
63"\t\tBit 8 (0x100) will enable DP messages (displayport code)");
64module_param_named(debug, drm_debug, int, 0600);
65
66static DEFINE_SPINLOCK(drm_minor_lock);
67static struct idr drm_minors_idr;
68
69
70
71
72
73
74
75
76static bool drm_core_init_complete = false;
77
78static struct dentry *drm_debugfs_root;
79
80DEFINE_STATIC_SRCU(drm_unplug_srcu);
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
96 unsigned int type)
97{
98 switch (type) {
99 case DRM_MINOR_PRIMARY:
100 return &dev->primary;
101 case DRM_MINOR_RENDER:
102 return &dev->render;
103 default:
104 BUG();
105 }
106}
107
108static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
109{
110 struct drm_minor *minor;
111 unsigned long flags;
112 int r;
113
114 minor = kzalloc(sizeof(*minor), GFP_KERNEL);
115 if (!minor)
116 return -ENOMEM;
117
118 minor->type = type;
119 minor->dev = dev;
120
121 idr_preload(GFP_KERNEL);
122 spin_lock_irqsave(&drm_minor_lock, flags);
123 r = idr_alloc(&drm_minors_idr,
124 NULL,
125 64 * type,
126 64 * (type + 1),
127 GFP_NOWAIT);
128 spin_unlock_irqrestore(&drm_minor_lock, flags);
129 idr_preload_end();
130
131 if (r < 0)
132 goto err_free;
133
134 minor->index = r;
135
136 minor->kdev = drm_sysfs_minor_alloc(minor);
137 if (IS_ERR(minor->kdev)) {
138 r = PTR_ERR(minor->kdev);
139 goto err_index;
140 }
141
142 *drm_minor_get_slot(dev, type) = minor;
143 return 0;
144
145err_index:
146 spin_lock_irqsave(&drm_minor_lock, flags);
147 idr_remove(&drm_minors_idr, minor->index);
148 spin_unlock_irqrestore(&drm_minor_lock, flags);
149err_free:
150 kfree(minor);
151 return r;
152}
153
154static void drm_minor_free(struct drm_device *dev, unsigned int type)
155{
156 struct drm_minor **slot, *minor;
157 unsigned long flags;
158
159 slot = drm_minor_get_slot(dev, type);
160 minor = *slot;
161 if (!minor)
162 return;
163
164 put_device(minor->kdev);
165
166 spin_lock_irqsave(&drm_minor_lock, flags);
167 idr_remove(&drm_minors_idr, minor->index);
168 spin_unlock_irqrestore(&drm_minor_lock, flags);
169
170 kfree(minor);
171 *slot = NULL;
172}
173
174static int drm_minor_register(struct drm_device *dev, unsigned int type)
175{
176 struct drm_minor *minor;
177 unsigned long flags;
178 int ret;
179
180 DRM_DEBUG("\n");
181
182 minor = *drm_minor_get_slot(dev, type);
183 if (!minor)
184 return 0;
185
186 ret = drm_debugfs_init(minor, minor->index, drm_debugfs_root);
187 if (ret) {
188 DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n");
189 goto err_debugfs;
190 }
191
192 ret = device_add(minor->kdev);
193 if (ret)
194 goto err_debugfs;
195
196
197 spin_lock_irqsave(&drm_minor_lock, flags);
198 idr_replace(&drm_minors_idr, minor, minor->index);
199 spin_unlock_irqrestore(&drm_minor_lock, flags);
200
201 DRM_DEBUG("new minor registered %d\n", minor->index);
202 return 0;
203
204err_debugfs:
205 drm_debugfs_cleanup(minor);
206 return ret;
207}
208
209static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
210{
211 struct drm_minor *minor;
212 unsigned long flags;
213
214 minor = *drm_minor_get_slot(dev, type);
215 if (!minor || !device_is_registered(minor->kdev))
216 return;
217
218
219 spin_lock_irqsave(&drm_minor_lock, flags);
220 idr_replace(&drm_minors_idr, NULL, minor->index);
221 spin_unlock_irqrestore(&drm_minor_lock, flags);
222
223 device_del(minor->kdev);
224 dev_set_drvdata(minor->kdev, NULL);
225 drm_debugfs_cleanup(minor);
226}
227
228
229
230
231
232
233
234
235
236
237struct drm_minor *drm_minor_acquire(unsigned int minor_id)
238{
239 struct drm_minor *minor;
240 unsigned long flags;
241
242 spin_lock_irqsave(&drm_minor_lock, flags);
243 minor = idr_find(&drm_minors_idr, minor_id);
244 if (minor)
245 drm_dev_get(minor->dev);
246 spin_unlock_irqrestore(&drm_minor_lock, flags);
247
248 if (!minor) {
249 return ERR_PTR(-ENODEV);
250 } else if (drm_dev_is_unplugged(minor->dev)) {
251 drm_dev_put(minor->dev);
252 return ERR_PTR(-ENODEV);
253 }
254
255 return minor;
256}
257
258void drm_minor_release(struct drm_minor *minor)
259{
260 drm_dev_put(minor->dev);
261}
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305void drm_put_dev(struct drm_device *dev)
306{
307 DRM_DEBUG("\n");
308
309 if (!dev) {
310 DRM_ERROR("cleanup called no dev\n");
311 return;
312 }
313
314 drm_dev_unregister(dev);
315 drm_dev_put(dev);
316}
317EXPORT_SYMBOL(drm_put_dev);
318
319
320
321
322
323
324
325
326
327
328
329
330
331bool drm_dev_enter(struct drm_device *dev, int *idx)
332{
333 *idx = srcu_read_lock(&drm_unplug_srcu);
334
335 if (dev->unplugged) {
336 srcu_read_unlock(&drm_unplug_srcu, *idx);
337 return false;
338 }
339
340 return true;
341}
342EXPORT_SYMBOL(drm_dev_enter);
343
344
345
346
347
348
349
350
351void drm_dev_exit(int idx)
352{
353 srcu_read_unlock(&drm_unplug_srcu, idx);
354}
355EXPORT_SYMBOL(drm_dev_exit);
356
357
358
359
360
361
362
363
364
365
366
367void drm_dev_unplug(struct drm_device *dev)
368{
369
370
371
372
373
374
375 dev->unplugged = true;
376 synchronize_srcu(&drm_unplug_srcu);
377
378 drm_dev_unregister(dev);
379 drm_dev_put(dev);
380}
381EXPORT_SYMBOL(drm_dev_unplug);
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401static int drm_fs_cnt;
402static struct vfsmount *drm_fs_mnt;
403
404static const struct dentry_operations drm_fs_dops = {
405 .d_dname = simple_dname,
406};
407
408static const struct super_operations drm_fs_sops = {
409 .statfs = simple_statfs,
410};
411
412static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags,
413 const char *dev_name, void *data)
414{
415 return mount_pseudo(fs_type,
416 "drm:",
417 &drm_fs_sops,
418 &drm_fs_dops,
419 0x010203ff);
420}
421
422static struct file_system_type drm_fs_type = {
423 .name = "drm",
424 .owner = THIS_MODULE,
425 .mount = drm_fs_mount,
426 .kill_sb = kill_anon_super,
427};
428
429static struct inode *drm_fs_inode_new(void)
430{
431 struct inode *inode;
432 int r;
433
434 r = simple_pin_fs(&drm_fs_type, &drm_fs_mnt, &drm_fs_cnt);
435 if (r < 0) {
436 DRM_ERROR("Cannot mount pseudo fs: %d\n", r);
437 return ERR_PTR(r);
438 }
439
440 inode = alloc_anon_inode(drm_fs_mnt->mnt_sb);
441 if (IS_ERR(inode))
442 simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
443
444 return inode;
445}
446
447static void drm_fs_inode_free(struct inode *inode)
448{
449 if (inode) {
450 iput(inode);
451 simple_release_fs(&drm_fs_mnt, &drm_fs_cnt);
452 }
453}
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486int drm_dev_init(struct drm_device *dev,
487 struct drm_driver *driver,
488 struct device *parent)
489{
490 int ret;
491
492 if (!drm_core_init_complete) {
493 DRM_ERROR("DRM core is not initialized\n");
494 return -ENODEV;
495 }
496
497 BUG_ON(!parent);
498
499 kref_init(&dev->ref);
500 dev->dev = parent;
501 dev->driver = driver;
502
503
504 dev->driver_features = ~0u;
505
506 INIT_LIST_HEAD(&dev->filelist);
507 INIT_LIST_HEAD(&dev->filelist_internal);
508 INIT_LIST_HEAD(&dev->clientlist);
509 INIT_LIST_HEAD(&dev->ctxlist);
510 INIT_LIST_HEAD(&dev->vmalist);
511 INIT_LIST_HEAD(&dev->maplist);
512 INIT_LIST_HEAD(&dev->vblank_event_list);
513
514 spin_lock_init(&dev->buf_lock);
515 spin_lock_init(&dev->event_lock);
516 mutex_init(&dev->struct_mutex);
517 mutex_init(&dev->filelist_mutex);
518 mutex_init(&dev->clientlist_mutex);
519 mutex_init(&dev->ctxlist_mutex);
520 mutex_init(&dev->master_mutex);
521
522 dev->anon_inode = drm_fs_inode_new();
523 if (IS_ERR(dev->anon_inode)) {
524 ret = PTR_ERR(dev->anon_inode);
525 DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
526 goto err_free;
527 }
528
529 if (drm_core_check_feature(dev, DRIVER_RENDER)) {
530 ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
531 if (ret)
532 goto err_minors;
533 }
534
535 ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
536 if (ret)
537 goto err_minors;
538
539 ret = drm_ht_create(&dev->map_hash, 12);
540 if (ret)
541 goto err_minors;
542
543 drm_legacy_ctxbitmap_init(dev);
544
545 if (drm_core_check_feature(dev, DRIVER_GEM)) {
546 ret = drm_gem_init(dev);
547 if (ret) {
548 DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
549 goto err_ctxbitmap;
550 }
551 }
552
553 ret = drm_dev_set_unique(dev, dev_name(parent));
554 if (ret)
555 goto err_setunique;
556
557 return 0;
558
559err_setunique:
560 if (drm_core_check_feature(dev, DRIVER_GEM))
561 drm_gem_destroy(dev);
562err_ctxbitmap:
563 drm_legacy_ctxbitmap_cleanup(dev);
564 drm_ht_remove(&dev->map_hash);
565err_minors:
566 drm_minor_free(dev, DRM_MINOR_PRIMARY);
567 drm_minor_free(dev, DRM_MINOR_RENDER);
568 drm_fs_inode_free(dev->anon_inode);
569err_free:
570 mutex_destroy(&dev->master_mutex);
571 mutex_destroy(&dev->ctxlist_mutex);
572 mutex_destroy(&dev->clientlist_mutex);
573 mutex_destroy(&dev->filelist_mutex);
574 mutex_destroy(&dev->struct_mutex);
575 return ret;
576}
577EXPORT_SYMBOL(drm_dev_init);
578
579
580
581
582
583
584
585
586
587
588
589
590
591void drm_dev_fini(struct drm_device *dev)
592{
593 drm_vblank_cleanup(dev);
594
595 if (drm_core_check_feature(dev, DRIVER_GEM))
596 drm_gem_destroy(dev);
597
598 drm_legacy_ctxbitmap_cleanup(dev);
599 drm_ht_remove(&dev->map_hash);
600 drm_fs_inode_free(dev->anon_inode);
601
602 drm_minor_free(dev, DRM_MINOR_PRIMARY);
603 drm_minor_free(dev, DRM_MINOR_RENDER);
604
605 mutex_destroy(&dev->master_mutex);
606 mutex_destroy(&dev->ctxlist_mutex);
607 mutex_destroy(&dev->clientlist_mutex);
608 mutex_destroy(&dev->filelist_mutex);
609 mutex_destroy(&dev->struct_mutex);
610 kfree(dev->unique);
611}
612EXPORT_SYMBOL(drm_dev_fini);
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636struct drm_device *drm_dev_alloc(struct drm_driver *driver,
637 struct device *parent)
638{
639 struct drm_device *dev;
640 int ret;
641
642 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
643 if (!dev)
644 return ERR_PTR(-ENOMEM);
645
646 ret = drm_dev_init(dev, driver, parent);
647 if (ret) {
648 kfree(dev);
649 return ERR_PTR(ret);
650 }
651
652 return dev;
653}
654EXPORT_SYMBOL(drm_dev_alloc);
655
656static void drm_dev_release(struct kref *ref)
657{
658 struct drm_device *dev = container_of(ref, struct drm_device, ref);
659
660 if (dev->driver->release) {
661 dev->driver->release(dev);
662 } else {
663 drm_dev_fini(dev);
664 kfree(dev);
665 }
666}
667
668
669
670
671
672
673
674
675
676
677
678
679
680void drm_dev_get(struct drm_device *dev)
681{
682 if (dev)
683 kref_get(&dev->ref);
684}
685EXPORT_SYMBOL(drm_dev_get);
686
687
688
689
690
691
692
693
694void drm_dev_put(struct drm_device *dev)
695{
696 if (dev)
697 kref_put(&dev->ref, drm_dev_release);
698}
699EXPORT_SYMBOL(drm_dev_put);
700
701static int create_compat_control_link(struct drm_device *dev)
702{
703 struct drm_minor *minor;
704 char *name;
705 int ret;
706
707 if (!drm_core_check_feature(dev, DRIVER_MODESET))
708 return 0;
709
710 minor = *drm_minor_get_slot(dev, DRM_MINOR_PRIMARY);
711 if (!minor)
712 return 0;
713
714
715
716
717
718
719
720
721
722
723 name = kasprintf(GFP_KERNEL, "controlD%d", minor->index + 64);
724 if (!name)
725 return -ENOMEM;
726
727 ret = sysfs_create_link(minor->kdev->kobj.parent,
728 &minor->kdev->kobj,
729 name);
730
731 kfree(name);
732
733 return ret;
734}
735
736static void remove_compat_control_link(struct drm_device *dev)
737{
738 struct drm_minor *minor;
739 char *name;
740
741 if (!drm_core_check_feature(dev, DRIVER_MODESET))
742 return;
743
744 minor = *drm_minor_get_slot(dev, DRM_MINOR_PRIMARY);
745 if (!minor)
746 return;
747
748 name = kasprintf(GFP_KERNEL, "controlD%d", minor->index + 64);
749 if (!name)
750 return;
751
752 sysfs_remove_link(minor->kdev->kobj.parent, name);
753
754 kfree(name);
755}
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777int drm_dev_register(struct drm_device *dev, unsigned long flags)
778{
779 struct drm_driver *driver = dev->driver;
780 int ret;
781
782 mutex_lock(&drm_global_mutex);
783
784 ret = drm_minor_register(dev, DRM_MINOR_RENDER);
785 if (ret)
786 goto err_minors;
787
788 ret = drm_minor_register(dev, DRM_MINOR_PRIMARY);
789 if (ret)
790 goto err_minors;
791
792 ret = create_compat_control_link(dev);
793 if (ret)
794 goto err_minors;
795
796 dev->registered = true;
797
798 if (dev->driver->load) {
799 ret = dev->driver->load(dev, flags);
800 if (ret)
801 goto err_minors;
802 }
803
804 if (drm_core_check_feature(dev, DRIVER_MODESET))
805 drm_modeset_register_all(dev);
806
807 ret = 0;
808
809 DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
810 driver->name, driver->major, driver->minor,
811 driver->patchlevel, driver->date,
812 dev->dev ? dev_name(dev->dev) : "virtual device",
813 dev->primary->index);
814
815 goto out_unlock;
816
817err_minors:
818 remove_compat_control_link(dev);
819 drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
820 drm_minor_unregister(dev, DRM_MINOR_RENDER);
821out_unlock:
822 mutex_unlock(&drm_global_mutex);
823 return ret;
824}
825EXPORT_SYMBOL(drm_dev_register);
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841void drm_dev_unregister(struct drm_device *dev)
842{
843 struct drm_map_list *r_list, *list_temp;
844
845 if (drm_core_check_feature(dev, DRIVER_LEGACY))
846 drm_lastclose(dev);
847
848 dev->registered = false;
849
850 drm_client_dev_unregister(dev);
851
852 if (drm_core_check_feature(dev, DRIVER_MODESET))
853 drm_modeset_unregister_all(dev);
854
855 if (dev->driver->unload)
856 dev->driver->unload(dev);
857
858 if (dev->agp)
859 drm_pci_agp_destroy(dev);
860
861 list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
862 drm_legacy_rmmap(dev, r_list->map);
863
864 remove_compat_control_link(dev);
865 drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
866 drm_minor_unregister(dev, DRM_MINOR_RENDER);
867}
868EXPORT_SYMBOL(drm_dev_unregister);
869
870
871
872
873
874
875
876
877
878
879
880
881int drm_dev_set_unique(struct drm_device *dev, const char *name)
882{
883 kfree(dev->unique);
884 dev->unique = kstrdup(name, GFP_KERNEL);
885
886 return dev->unique ? 0 : -ENOMEM;
887}
888EXPORT_SYMBOL(drm_dev_set_unique);
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910static int drm_stub_open(struct inode *inode, struct file *filp)
911{
912 const struct file_operations *new_fops;
913 struct drm_minor *minor;
914 int err;
915
916 DRM_DEBUG("\n");
917
918 mutex_lock(&drm_global_mutex);
919 minor = drm_minor_acquire(iminor(inode));
920 if (IS_ERR(minor)) {
921 err = PTR_ERR(minor);
922 goto out_unlock;
923 }
924
925 new_fops = fops_get(minor->dev->driver->fops);
926 if (!new_fops) {
927 err = -ENODEV;
928 goto out_release;
929 }
930
931 replace_fops(filp, new_fops);
932 if (filp->f_op->open)
933 err = filp->f_op->open(inode, filp);
934 else
935 err = 0;
936
937out_release:
938 drm_minor_release(minor);
939out_unlock:
940 mutex_unlock(&drm_global_mutex);
941 return err;
942}
943
944static const struct file_operations drm_stub_fops = {
945 .owner = THIS_MODULE,
946 .open = drm_stub_open,
947 .llseek = noop_llseek,
948};
949
950static void drm_core_exit(void)
951{
952 unregister_chrdev(DRM_MAJOR, "drm");
953 debugfs_remove(drm_debugfs_root);
954 drm_sysfs_destroy();
955 idr_destroy(&drm_minors_idr);
956 drm_connector_ida_destroy();
957}
958
959static int __init drm_core_init(void)
960{
961 int ret;
962
963 drm_connector_ida_init();
964 idr_init(&drm_minors_idr);
965
966 ret = drm_sysfs_init();
967 if (ret < 0) {
968 DRM_ERROR("Cannot create DRM class: %d\n", ret);
969 goto error;
970 }
971
972 drm_debugfs_root = debugfs_create_dir("dri", NULL);
973 if (!drm_debugfs_root) {
974 ret = -ENOMEM;
975 DRM_ERROR("Cannot create debugfs-root: %d\n", ret);
976 goto error;
977 }
978
979 ret = register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops);
980 if (ret < 0)
981 goto error;
982
983 drm_core_init_complete = true;
984
985 DRM_DEBUG("Initialized\n");
986 return 0;
987
988error:
989 drm_core_exit();
990 return ret;
991}
992
993module_init(drm_core_init);
994module_exit(drm_core_exit);
995