@@ -370,14 +370,31 @@ void drm_mode_object_put(struct drm_device *dev,
370
370
mutex_unlock (& dev -> mode_config .idr_mutex );
371
371
}
372
372
373
+ static struct drm_mode_object * _object_find (struct drm_device * dev ,
374
+ uint32_t id , uint32_t type )
375
+ {
376
+ struct drm_mode_object * obj = NULL ;
377
+
378
+ mutex_lock (& dev -> mode_config .idr_mutex );
379
+ obj = idr_find (& dev -> mode_config .crtc_idr , id );
380
+ if (!obj || (type != DRM_MODE_OBJECT_ANY && obj -> type != type ) ||
381
+ (obj -> id != id ))
382
+ obj = NULL ;
383
+ mutex_unlock (& dev -> mode_config .idr_mutex );
384
+
385
+ return obj ;
386
+ }
387
+
373
388
/**
374
389
* drm_mode_object_find - look up a drm object with static lifetime
375
390
* @dev: drm device
376
391
* @id: id of the mode object
377
392
* @type: type of the mode object
378
393
*
379
394
* Note that framebuffers cannot be looked up with this functions - since those
380
- * are reference counted, they need special treatment.
395
+ * are reference counted, they need special treatment. Even with
396
+ * DRM_MODE_OBJECT_ANY (although that will simply return NULL
397
+ * rather than WARN_ON()).
381
398
*/
382
399
struct drm_mode_object * drm_mode_object_find (struct drm_device * dev ,
383
400
uint32_t id , uint32_t type )
@@ -387,13 +404,10 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
387
404
/* Framebuffers are reference counted and need their own lookup
388
405
* function.*/
389
406
WARN_ON (type == DRM_MODE_OBJECT_FB );
390
-
391
- mutex_lock (& dev -> mode_config .idr_mutex );
392
- obj = idr_find (& dev -> mode_config .crtc_idr , id );
393
- if (!obj || (obj -> type != type ) || (obj -> id != id ))
407
+ obj = _object_find (dev , id , type );
408
+ /* don't leak out unref'd fb's */
409
+ if (obj && (obj -> type == DRM_MODE_OBJECT_FB ))
394
410
obj = NULL ;
395
- mutex_unlock (& dev -> mode_config .idr_mutex );
396
-
397
411
return obj ;
398
412
}
399
413
EXPORT_SYMBOL (drm_mode_object_find );
@@ -3074,6 +3088,8 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
3074
3088
if (!property )
3075
3089
return NULL ;
3076
3090
3091
+ property -> dev = dev ;
3092
+
3077
3093
if (num_values ) {
3078
3094
property -> values = kzalloc (sizeof (uint64_t )* num_values , GFP_KERNEL );
3079
3095
if (!property -> values )
@@ -3234,6 +3250,23 @@ struct drm_property *drm_property_create_range(struct drm_device *dev, int flags
3234
3250
}
3235
3251
EXPORT_SYMBOL (drm_property_create_range );
3236
3252
3253
+ struct drm_property * drm_property_create_object (struct drm_device * dev ,
3254
+ int flags , const char * name , uint32_t type )
3255
+ {
3256
+ struct drm_property * property ;
3257
+
3258
+ flags |= DRM_MODE_PROP_OBJECT ;
3259
+
3260
+ property = drm_property_create (dev , flags , name , 1 );
3261
+ if (!property )
3262
+ return NULL ;
3263
+
3264
+ property -> values [0 ] = type ;
3265
+
3266
+ return property ;
3267
+ }
3268
+ EXPORT_SYMBOL (drm_property_create_object );
3269
+
3237
3270
/**
3238
3271
* drm_property_add_enum - add a possible value to an enumeration property
3239
3272
* @property: enumeration property to change
@@ -3661,6 +3694,20 @@ static bool drm_property_change_is_valid(struct drm_property *property,
3661
3694
} else if (drm_property_type_is (property , DRM_MODE_PROP_BLOB )) {
3662
3695
/* Only the driver knows */
3663
3696
return true;
3697
+ } else if (drm_property_type_is (property , DRM_MODE_PROP_OBJECT )) {
3698
+ struct drm_mode_object * obj ;
3699
+ /* a zero value for an object property translates to null: */
3700
+ if (value == 0 )
3701
+ return true;
3702
+ /*
3703
+ * NOTE: use _object_find() directly to bypass restriction on
3704
+ * looking up refcnt'd objects (ie. fb's). For a refcnt'd
3705
+ * object this could race against object finalization, so it
3706
+ * simply tells us that the object *was* valid. Which is good
3707
+ * enough.
3708
+ */
3709
+ obj = _object_find (property -> dev , value , property -> values [0 ]);
3710
+ return obj != NULL ;
3664
3711
} else {
3665
3712
int i ;
3666
3713
for (i = 0 ; i < property -> num_values ; i ++ )
0 commit comments