aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_crtc.c61
-rw-r--r--include/drm/drm_crtc.h5
-rw-r--r--include/uapi/drm/drm_mode.h1
3 files changed, 60 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 73f543af4924..f990d9f180f0 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -370,6 +370,21 @@ void drm_mode_object_put(struct drm_device *dev,
370 mutex_unlock(&dev->mode_config.idr_mutex); 370 mutex_unlock(&dev->mode_config.idr_mutex);
371} 371}
372 372
373static 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 * drm_mode_object_find - look up a drm object with static lifetime 389 * drm_mode_object_find - look up a drm object with static lifetime
375 * @dev: drm device 390 * @dev: drm device
@@ -377,7 +392,9 @@ void drm_mode_object_put(struct drm_device *dev,
377 * @type: type of the mode object 392 * @type: type of the mode object
378 * 393 *
379 * Note that framebuffers cannot be looked up with this functions - since those 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 */
382struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, 399struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
383 uint32_t id, uint32_t type) 400 uint32_t id, uint32_t type)
@@ -387,13 +404,10 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
387 /* Framebuffers are reference counted and need their own lookup 404 /* Framebuffers are reference counted and need their own lookup
388 * function.*/ 405 * function.*/
389 WARN_ON(type == DRM_MODE_OBJECT_FB); 406 WARN_ON(type == DRM_MODE_OBJECT_FB);
390 407 obj = _object_find(dev, id, type);
391 mutex_lock(&dev->mode_config.idr_mutex); 408 /* don't leak out unref'd fb's */
392 obj = idr_find(&dev->mode_config.crtc_idr, id); 409 if (obj && (obj->type == DRM_MODE_OBJECT_FB))
393 if (!obj || (obj->type != type) || (obj->id != id))
394 obj = NULL; 410 obj = NULL;
395 mutex_unlock(&dev->mode_config.idr_mutex);
396
397 return obj; 411 return obj;
398} 412}
399EXPORT_SYMBOL(drm_mode_object_find); 413EXPORT_SYMBOL(drm_mode_object_find);
@@ -3074,6 +3088,8 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
3074 if (!property) 3088 if (!property)
3075 return NULL; 3089 return NULL;
3076 3090
3091 property->dev = dev;
3092
3077 if (num_values) { 3093 if (num_values) {
3078 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL); 3094 property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
3079 if (!property->values) 3095 if (!property->values)
@@ -3234,6 +3250,23 @@ struct drm_property *drm_property_create_range(struct drm_device *dev, int flags
3234} 3250}
3235EXPORT_SYMBOL(drm_property_create_range); 3251EXPORT_SYMBOL(drm_property_create_range);
3236 3252
3253struct 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}
3268EXPORT_SYMBOL(drm_property_create_object);
3269
3237/** 3270/**
3238 * drm_property_add_enum - add a possible value to an enumeration property 3271 * drm_property_add_enum - add a possible value to an enumeration property
3239 * @property: enumeration property to change 3272 * @property: enumeration property to change
@@ -3661,6 +3694,20 @@ static bool drm_property_change_is_valid(struct drm_property *property,
3661 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) { 3694 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
3662 /* Only the driver knows */ 3695 /* Only the driver knows */
3663 return true; 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 } else { 3711 } else {
3665 int i; 3712 int i;
3666 for (i = 0; i < property->num_values; i++) 3713 for (i = 0; i < property->num_values; i++)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 92f6ec2de86a..cb2e599f769f 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -50,6 +50,7 @@ struct drm_clip_rect;
50#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb 50#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
51#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee 51#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
52#define DRM_MODE_OBJECT_BRIDGE 0xbdbdbdbd 52#define DRM_MODE_OBJECT_BRIDGE 0xbdbdbdbd
53#define DRM_MODE_OBJECT_ANY 0
53 54
54struct drm_mode_object { 55struct drm_mode_object {
55 uint32_t id; 56 uint32_t id;
@@ -190,6 +191,7 @@ struct drm_property {
190 char name[DRM_PROP_NAME_LEN]; 191 char name[DRM_PROP_NAME_LEN];
191 uint32_t num_values; 192 uint32_t num_values;
192 uint64_t *values; 193 uint64_t *values;
194 struct drm_device *dev;
193 195
194 struct list_head enum_blob_list; 196 struct list_head enum_blob_list;
195}; 197};
@@ -980,6 +982,8 @@ struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
980struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, 982struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
981 const char *name, 983 const char *name,
982 uint64_t min, uint64_t max); 984 uint64_t min, uint64_t max);
985struct drm_property *drm_property_create_object(struct drm_device *dev,
986 int flags, const char *name, uint32_t type);
983extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); 987extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
984extern int drm_property_add_enum(struct drm_property *property, int index, 988extern int drm_property_add_enum(struct drm_property *property, int index,
985 uint64_t value, const char *name); 989 uint64_t value, const char *name);
@@ -995,6 +999,7 @@ extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
995 int gamma_size); 999 int gamma_size);
996extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, 1000extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
997 uint32_t id, uint32_t type); 1001 uint32_t id, uint32_t type);
1002
998/* IOCTLs */ 1003/* IOCTLs */
999extern int drm_mode_getresources(struct drm_device *dev, 1004extern int drm_mode_getresources(struct drm_device *dev,
1000 void *data, struct drm_file *file_priv); 1005 void *data, struct drm_file *file_priv);
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index caeaa6f7ebde..57f46348befe 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -264,6 +264,7 @@ struct drm_mode_get_connector {
264 */ 264 */
265#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0 265#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0
266#define DRM_MODE_PROP_TYPE(n) ((n) << 6) 266#define DRM_MODE_PROP_TYPE(n) ((n) << 6)
267#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1)
267 268
268struct drm_mode_property_enum { 269struct drm_mode_property_enum {
269 __u64 value; 270 __u64 value;