Skip to content

Commit 98f75de

Browse files
robclarkairlied
authored andcommitted
drm: add object property type
An object property is an id (idr) for a drm mode object. This will allow a property to be used set/get a framebuffer, CRTC, etc. Signed-off-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1 parent 5ea22f2 commit 98f75de

File tree

3 files changed

+60
-7
lines changed

3 files changed

+60
-7
lines changed

drivers/gpu/drm/drm_crtc.c

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,31 @@ void drm_mode_object_put(struct drm_device *dev,
370370
mutex_unlock(&dev->mode_config.idr_mutex);
371371
}
372372

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+
373388
/**
374389
* drm_mode_object_find - look up a drm object with static lifetime
375390
* @dev: drm device
376391
* @id: id of the mode object
377392
* @type: type of the mode object
378393
*
379394
* 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()).
381398
*/
382399
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
383400
uint32_t id, uint32_t type)
@@ -387,13 +404,10 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
387404
/* Framebuffers are reference counted and need their own lookup
388405
* function.*/
389406
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))
394410
obj = NULL;
395-
mutex_unlock(&dev->mode_config.idr_mutex);
396-
397411
return obj;
398412
}
399413
EXPORT_SYMBOL(drm_mode_object_find);
@@ -3074,6 +3088,8 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
30743088
if (!property)
30753089
return NULL;
30763090

3091+
property->dev = dev;
3092+
30773093
if (num_values) {
30783094
property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL);
30793095
if (!property->values)
@@ -3234,6 +3250,23 @@ struct drm_property *drm_property_create_range(struct drm_device *dev, int flags
32343250
}
32353251
EXPORT_SYMBOL(drm_property_create_range);
32363252

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+
32373270
/**
32383271
* drm_property_add_enum - add a possible value to an enumeration property
32393272
* @property: enumeration property to change
@@ -3661,6 +3694,20 @@ static bool drm_property_change_is_valid(struct drm_property *property,
36613694
} else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
36623695
/* Only the driver knows */
36633696
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;
36643711
} else {
36653712
int i;
36663713
for (i = 0; i < property->num_values; i++)

include/drm/drm_crtc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct drm_clip_rect;
5050
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
5151
#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
5252
#define DRM_MODE_OBJECT_BRIDGE 0xbdbdbdbd
53+
#define DRM_MODE_OBJECT_ANY 0
5354

5455
struct drm_mode_object {
5556
uint32_t id;
@@ -190,6 +191,7 @@ struct drm_property {
190191
char name[DRM_PROP_NAME_LEN];
191192
uint32_t num_values;
192193
uint64_t *values;
194+
struct drm_device *dev;
193195

194196
struct list_head enum_blob_list;
195197
};
@@ -980,6 +982,8 @@ struct drm_property *drm_property_create_bitmask(struct drm_device *dev,
980982
struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
981983
const char *name,
982984
uint64_t min, uint64_t max);
985+
struct drm_property *drm_property_create_object(struct drm_device *dev,
986+
int flags, const char *name, uint32_t type);
983987
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
984988
extern int drm_property_add_enum(struct drm_property *property, int index,
985989
uint64_t value, const char *name);
@@ -995,6 +999,7 @@ extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
995999
int gamma_size);
9961000
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
9971001
uint32_t id, uint32_t type);
1002+
9981003
/* IOCTLs */
9991004
extern int drm_mode_getresources(struct drm_device *dev,
10001005
void *data, struct drm_file *file_priv);

include/uapi/drm/drm_mode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ struct drm_mode_get_connector {
264264
*/
265265
#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0
266266
#define DRM_MODE_PROP_TYPE(n) ((n) << 6)
267+
#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1)
267268

268269
struct drm_mode_property_enum {
269270
__u64 value;

0 commit comments

Comments
 (0)