3535#include <linux/slab.h>
3636#include <linux/srcu.h>
3737
38+ #include <drm/drm_accel.h>
3839#include <drm/drm_cache.h>
3940#include <drm/drm_client.h>
4041#include <drm/drm_color_mgmt.h>
@@ -90,6 +91,8 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
9091 return & dev -> primary ;
9192 case DRM_MINOR_RENDER :
9293 return & dev -> render ;
94+ case DRM_MINOR_ACCEL :
95+ return & dev -> accel ;
9396 default :
9497 BUG ();
9598 }
@@ -104,9 +107,13 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data)
104107
105108 put_device (minor -> kdev );
106109
107- spin_lock_irqsave (& drm_minor_lock , flags );
108- idr_remove (& drm_minors_idr , minor -> index );
109- spin_unlock_irqrestore (& drm_minor_lock , flags );
110+ if (minor -> type == DRM_MINOR_ACCEL ) {
111+ accel_minor_remove (minor -> index );
112+ } else {
113+ spin_lock_irqsave (& drm_minor_lock , flags );
114+ idr_remove (& drm_minors_idr , minor -> index );
115+ spin_unlock_irqrestore (& drm_minor_lock , flags );
116+ }
110117}
111118
112119static int drm_minor_alloc (struct drm_device * dev , unsigned int type )
@@ -123,13 +130,17 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
123130 minor -> dev = dev ;
124131
125132 idr_preload (GFP_KERNEL );
126- spin_lock_irqsave (& drm_minor_lock , flags );
127- r = idr_alloc (& drm_minors_idr ,
128- NULL ,
129- 64 * type ,
130- 64 * (type + 1 ),
131- GFP_NOWAIT );
132- spin_unlock_irqrestore (& drm_minor_lock , flags );
133+ if (type == DRM_MINOR_ACCEL ) {
134+ r = accel_minor_alloc ();
135+ } else {
136+ spin_lock_irqsave (& drm_minor_lock , flags );
137+ r = idr_alloc (& drm_minors_idr ,
138+ NULL ,
139+ 64 * type ,
140+ 64 * (type + 1 ),
141+ GFP_NOWAIT );
142+ spin_unlock_irqrestore (& drm_minor_lock , flags );
143+ }
133144 idr_preload_end ();
134145
135146 if (r < 0 )
@@ -161,20 +172,28 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type)
161172 if (!minor )
162173 return 0 ;
163174
164- ret = drm_debugfs_init (minor , minor -> index , drm_debugfs_root );
165- if (ret ) {
166- DRM_ERROR ("DRM: Failed to initialize /sys/kernel/debug/dri.\n" );
167- goto err_debugfs ;
175+ if (minor -> type == DRM_MINOR_ACCEL ) {
176+ accel_debugfs_init (minor , minor -> index );
177+ } else {
178+ ret = drm_debugfs_init (minor , minor -> index , drm_debugfs_root );
179+ if (ret ) {
180+ DRM_ERROR ("DRM: Failed to initialize /sys/kernel/debug/dri.\n" );
181+ goto err_debugfs ;
182+ }
168183 }
169184
170185 ret = device_add (minor -> kdev );
171186 if (ret )
172187 goto err_debugfs ;
173188
174189 /* replace NULL with @minor so lookups will succeed from now on */
175- spin_lock_irqsave (& drm_minor_lock , flags );
176- idr_replace (& drm_minors_idr , minor , minor -> index );
177- spin_unlock_irqrestore (& drm_minor_lock , flags );
190+ if (minor -> type == DRM_MINOR_ACCEL ) {
191+ accel_minor_replace (minor , minor -> index );
192+ } else {
193+ spin_lock_irqsave (& drm_minor_lock , flags );
194+ idr_replace (& drm_minors_idr , minor , minor -> index );
195+ spin_unlock_irqrestore (& drm_minor_lock , flags );
196+ }
178197
179198 DRM_DEBUG ("new minor registered %d\n" , minor -> index );
180199 return 0 ;
@@ -194,9 +213,13 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type)
194213 return ;
195214
196215 /* replace @minor with NULL so lookups will fail from now on */
197- spin_lock_irqsave (& drm_minor_lock , flags );
198- idr_replace (& drm_minors_idr , NULL , minor -> index );
199- spin_unlock_irqrestore (& drm_minor_lock , flags );
216+ if (minor -> type == DRM_MINOR_ACCEL ) {
217+ accel_minor_replace (NULL , minor -> index );
218+ } else {
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+ }
200223
201224 device_del (minor -> kdev );
202225 dev_set_drvdata (minor -> kdev , NULL ); /* safety belt */
@@ -603,6 +626,13 @@ static int drm_dev_init(struct drm_device *dev,
603626 /* no per-device feature limits by default */
604627 dev -> driver_features = ~0u ;
605628
629+ if (drm_core_check_feature (dev , DRIVER_COMPUTE_ACCEL ) &&
630+ (drm_core_check_feature (dev , DRIVER_RENDER ) ||
631+ drm_core_check_feature (dev , DRIVER_MODESET ))) {
632+ DRM_ERROR ("DRM driver can't be both a compute acceleration and graphics driver\n" );
633+ return - EINVAL ;
634+ }
635+
606636 drm_legacy_init_members (dev );
607637 INIT_LIST_HEAD (& dev -> filelist );
608638 INIT_LIST_HEAD (& dev -> filelist_internal );
@@ -628,15 +658,21 @@ static int drm_dev_init(struct drm_device *dev,
628658
629659 dev -> anon_inode = inode ;
630660
631- if (drm_core_check_feature (dev , DRIVER_RENDER )) {
632- ret = drm_minor_alloc (dev , DRM_MINOR_RENDER );
661+ if (drm_core_check_feature (dev , DRIVER_COMPUTE_ACCEL )) {
662+ ret = drm_minor_alloc (dev , DRM_MINOR_ACCEL );
633663 if (ret )
634664 goto err ;
635- }
665+ } else {
666+ if (drm_core_check_feature (dev , DRIVER_RENDER )) {
667+ ret = drm_minor_alloc (dev , DRM_MINOR_RENDER );
668+ if (ret )
669+ goto err ;
670+ }
636671
637- ret = drm_minor_alloc (dev , DRM_MINOR_PRIMARY );
638- if (ret )
639- goto err ;
672+ ret = drm_minor_alloc (dev , DRM_MINOR_PRIMARY );
673+ if (ret )
674+ goto err ;
675+ }
640676
641677 ret = drm_legacy_create_map_hash (dev );
642678 if (ret )
@@ -883,6 +919,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
883919 if (ret )
884920 goto err_minors ;
885921
922+ ret = drm_minor_register (dev , DRM_MINOR_ACCEL );
923+ if (ret )
924+ goto err_minors ;
925+
886926 ret = create_compat_control_link (dev );
887927 if (ret )
888928 goto err_minors ;
@@ -902,12 +942,13 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
902942 driver -> name , driver -> major , driver -> minor ,
903943 driver -> patchlevel , driver -> date ,
904944 dev -> dev ? dev_name (dev -> dev ) : "virtual device" ,
905- dev -> primary -> index );
945+ dev -> primary ? dev -> primary -> index : dev -> accel -> index );
906946
907947 goto out_unlock ;
908948
909949err_minors :
910950 remove_compat_control_link (dev );
951+ drm_minor_unregister (dev , DRM_MINOR_ACCEL );
911952 drm_minor_unregister (dev , DRM_MINOR_PRIMARY );
912953 drm_minor_unregister (dev , DRM_MINOR_RENDER );
913954out_unlock :
@@ -950,6 +991,7 @@ void drm_dev_unregister(struct drm_device *dev)
950991 drm_legacy_rmmaps (dev );
951992
952993 remove_compat_control_link (dev );
994+ drm_minor_unregister (dev , DRM_MINOR_ACCEL );
953995 drm_minor_unregister (dev , DRM_MINOR_PRIMARY );
954996 drm_minor_unregister (dev , DRM_MINOR_RENDER );
955997}
@@ -1034,6 +1076,7 @@ static const struct file_operations drm_stub_fops = {
10341076static void drm_core_exit (void )
10351077{
10361078 drm_privacy_screen_lookup_exit ();
1079+ accel_core_exit ();
10371080 unregister_chrdev (DRM_MAJOR , "drm" );
10381081 debugfs_remove (drm_debugfs_root );
10391082 drm_sysfs_destroy ();
@@ -1061,6 +1104,10 @@ static int __init drm_core_init(void)
10611104 if (ret < 0 )
10621105 goto error ;
10631106
1107+ ret = accel_core_init ();
1108+ if (ret < 0 )
1109+ goto error ;
1110+
10641111 drm_privacy_screen_lookup_init ();
10651112
10661113 drm_core_init_complete = true;
0 commit comments