diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 59 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_fops.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 117 |
3 files changed, 115 insertions, 100 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 7aa8121d1323..190df83be695 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -171,65 +171,6 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||
171 | 171 | ||
172 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) | 172 | #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) |
173 | 173 | ||
174 | /** File operations structure */ | ||
175 | static const struct file_operations drm_stub_fops = { | ||
176 | .owner = THIS_MODULE, | ||
177 | .open = drm_stub_open, | ||
178 | .llseek = noop_llseek, | ||
179 | }; | ||
180 | |||
181 | static int __init drm_core_init(void) | ||
182 | { | ||
183 | int ret = -ENOMEM; | ||
184 | |||
185 | drm_global_init(); | ||
186 | drm_connector_ida_init(); | ||
187 | idr_init(&drm_minors_idr); | ||
188 | |||
189 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) | ||
190 | goto err_p1; | ||
191 | |||
192 | drm_class = drm_sysfs_create(THIS_MODULE, "drm"); | ||
193 | if (IS_ERR(drm_class)) { | ||
194 | printk(KERN_ERR "DRM: Error creating drm class.\n"); | ||
195 | ret = PTR_ERR(drm_class); | ||
196 | goto err_p2; | ||
197 | } | ||
198 | |||
199 | drm_debugfs_root = debugfs_create_dir("dri", NULL); | ||
200 | if (!drm_debugfs_root) { | ||
201 | DRM_ERROR("Cannot create /sys/kernel/debug/dri\n"); | ||
202 | ret = -1; | ||
203 | goto err_p3; | ||
204 | } | ||
205 | |||
206 | DRM_INFO("Initialized %s %d.%d.%d %s\n", | ||
207 | CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); | ||
208 | return 0; | ||
209 | err_p3: | ||
210 | drm_sysfs_destroy(); | ||
211 | err_p2: | ||
212 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
213 | |||
214 | idr_destroy(&drm_minors_idr); | ||
215 | err_p1: | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static void __exit drm_core_exit(void) | ||
220 | { | ||
221 | debugfs_remove(drm_debugfs_root); | ||
222 | drm_sysfs_destroy(); | ||
223 | |||
224 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
225 | |||
226 | drm_connector_ida_destroy(); | ||
227 | idr_destroy(&drm_minors_idr); | ||
228 | } | ||
229 | |||
230 | module_init(drm_core_init); | ||
231 | module_exit(drm_core_exit); | ||
232 | |||
233 | /** | 174 | /** |
234 | * Copy and IOCTL return string to user space | 175 | * Copy and IOCTL return string to user space |
235 | */ | 176 | */ |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 3299175da6ac..955f32cbce53 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -112,45 +112,6 @@ err_undo: | |||
112 | EXPORT_SYMBOL(drm_open); | 112 | EXPORT_SYMBOL(drm_open); |
113 | 113 | ||
114 | /** | 114 | /** |
115 | * File \c open operation. | ||
116 | * | ||
117 | * \param inode device inode. | ||
118 | * \param filp file pointer. | ||
119 | * | ||
120 | * Puts the dev->fops corresponding to the device minor number into | ||
121 | * \p filp, call the \c open method, and restore the file operations. | ||
122 | */ | ||
123 | int drm_stub_open(struct inode *inode, struct file *filp) | ||
124 | { | ||
125 | struct drm_device *dev; | ||
126 | struct drm_minor *minor; | ||
127 | int err = -ENODEV; | ||
128 | const struct file_operations *new_fops; | ||
129 | |||
130 | DRM_DEBUG("\n"); | ||
131 | |||
132 | mutex_lock(&drm_global_mutex); | ||
133 | minor = drm_minor_acquire(iminor(inode)); | ||
134 | if (IS_ERR(minor)) | ||
135 | goto out_unlock; | ||
136 | |||
137 | dev = minor->dev; | ||
138 | new_fops = fops_get(dev->driver->fops); | ||
139 | if (!new_fops) | ||
140 | goto out_release; | ||
141 | |||
142 | replace_fops(filp, new_fops); | ||
143 | if (filp->f_op->open) | ||
144 | err = filp->f_op->open(inode, filp); | ||
145 | |||
146 | out_release: | ||
147 | drm_minor_release(minor); | ||
148 | out_unlock: | ||
149 | mutex_unlock(&drm_global_mutex); | ||
150 | return err; | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * Check whether DRI will run on this CPU. | 115 | * Check whether DRI will run on this CPU. |
155 | * | 116 | * |
156 | * \return non-zero if the DRI will run on this CPU, or zero otherwise. | 117 | * \return non-zero if the DRI will run on this CPU, or zero otherwise. |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 18c9b3d8201e..b249f14f66a9 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * DEALINGS IN THE SOFTWARE. | 26 | * DEALINGS IN THE SOFTWARE. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/debugfs.h> | ||
29 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
@@ -61,10 +62,10 @@ module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600) | |||
61 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); | 62 | module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); |
62 | 63 | ||
63 | static DEFINE_SPINLOCK(drm_minor_lock); | 64 | static DEFINE_SPINLOCK(drm_minor_lock); |
64 | struct idr drm_minors_idr; | 65 | static struct idr drm_minors_idr; |
65 | 66 | ||
66 | struct class *drm_class; | 67 | struct class *drm_class; |
67 | struct dentry *drm_debugfs_root; | 68 | static struct dentry *drm_debugfs_root; |
68 | 69 | ||
69 | int drm_err(const char *func, const char *format, ...) | 70 | int drm_err(const char *func, const char *format, ...) |
70 | { | 71 | { |
@@ -787,3 +788,115 @@ int drm_dev_set_unique(struct drm_device *dev, const char *fmt, ...) | |||
787 | return dev->unique ? 0 : -ENOMEM; | 788 | return dev->unique ? 0 : -ENOMEM; |
788 | } | 789 | } |
789 | EXPORT_SYMBOL(drm_dev_set_unique); | 790 | EXPORT_SYMBOL(drm_dev_set_unique); |
791 | |||
792 | /* | ||
793 | * DRM Core | ||
794 | * The DRM core module initializes all global DRM objects and makes them | ||
795 | * available to drivers. Once setup, drivers can probe their respective | ||
796 | * devices. | ||
797 | * Currently, core management includes: | ||
798 | * - The "DRM-Global" key/value database | ||
799 | * - Global ID management for connectors | ||
800 | * - DRM major number allocation | ||
801 | * - DRM minor management | ||
802 | * - DRM sysfs class | ||
803 | * - DRM debugfs root | ||
804 | * | ||
805 | * Furthermore, the DRM core provides dynamic char-dev lookups. For each | ||
806 | * interface registered on a DRM device, you can request minor numbers from DRM | ||
807 | * core. DRM core takes care of major-number management and char-dev | ||
808 | * registration. A stub ->open() callback forwards any open() requests to the | ||
809 | * registered minor. | ||
810 | */ | ||
811 | |||
812 | static int drm_stub_open(struct inode *inode, struct file *filp) | ||
813 | { | ||
814 | const struct file_operations *new_fops; | ||
815 | struct drm_minor *minor; | ||
816 | int err; | ||
817 | |||
818 | DRM_DEBUG("\n"); | ||
819 | |||
820 | mutex_lock(&drm_global_mutex); | ||
821 | minor = drm_minor_acquire(iminor(inode)); | ||
822 | if (IS_ERR(minor)) { | ||
823 | err = PTR_ERR(minor); | ||
824 | goto out_unlock; | ||
825 | } | ||
826 | |||
827 | new_fops = fops_get(minor->dev->driver->fops); | ||
828 | if (!new_fops) { | ||
829 | err = -ENODEV; | ||
830 | goto out_release; | ||
831 | } | ||
832 | |||
833 | replace_fops(filp, new_fops); | ||
834 | if (filp->f_op->open) | ||
835 | err = filp->f_op->open(inode, filp); | ||
836 | else | ||
837 | err = 0; | ||
838 | |||
839 | out_release: | ||
840 | drm_minor_release(minor); | ||
841 | out_unlock: | ||
842 | mutex_unlock(&drm_global_mutex); | ||
843 | return err; | ||
844 | } | ||
845 | |||
846 | static const struct file_operations drm_stub_fops = { | ||
847 | .owner = THIS_MODULE, | ||
848 | .open = drm_stub_open, | ||
849 | .llseek = noop_llseek, | ||
850 | }; | ||
851 | |||
852 | static int __init drm_core_init(void) | ||
853 | { | ||
854 | int ret = -ENOMEM; | ||
855 | |||
856 | drm_global_init(); | ||
857 | drm_connector_ida_init(); | ||
858 | idr_init(&drm_minors_idr); | ||
859 | |||
860 | if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)) | ||
861 | goto err_p1; | ||
862 | |||
863 | drm_class = drm_sysfs_create(THIS_MODULE, "drm"); | ||
864 | if (IS_ERR(drm_class)) { | ||
865 | printk(KERN_ERR "DRM: Error creating drm class.\n"); | ||
866 | ret = PTR_ERR(drm_class); | ||
867 | goto err_p2; | ||
868 | } | ||
869 | |||
870 | drm_debugfs_root = debugfs_create_dir("dri", NULL); | ||
871 | if (!drm_debugfs_root) { | ||
872 | DRM_ERROR("Cannot create /sys/kernel/debug/dri\n"); | ||
873 | ret = -1; | ||
874 | goto err_p3; | ||
875 | } | ||
876 | |||
877 | DRM_INFO("Initialized %s %d.%d.%d %s\n", | ||
878 | CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); | ||
879 | return 0; | ||
880 | err_p3: | ||
881 | drm_sysfs_destroy(); | ||
882 | err_p2: | ||
883 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
884 | |||
885 | idr_destroy(&drm_minors_idr); | ||
886 | err_p1: | ||
887 | return ret; | ||
888 | } | ||
889 | |||
890 | static void __exit drm_core_exit(void) | ||
891 | { | ||
892 | debugfs_remove(drm_debugfs_root); | ||
893 | drm_sysfs_destroy(); | ||
894 | |||
895 | unregister_chrdev(DRM_MAJOR, "drm"); | ||
896 | |||
897 | drm_connector_ida_destroy(); | ||
898 | idr_destroy(&drm_minors_idr); | ||
899 | } | ||
900 | |||
901 | module_init(drm_core_init); | ||
902 | module_exit(drm_core_exit); | ||