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@xxxxxxxxx> --- drivers/gpu/drm/drm_crtc.c | 61 +++++++++++++++++++++++++++++++++++++++------ include/drm/drm_crtc.h | 5 ++++ include/uapi/drm/drm_mode.h | 1 + 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 0dbd6e0..8fdd5b3 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -389,6 +389,21 @@ void drm_mode_object_put(struct drm_device *dev, mutex_unlock(&dev->mode_config.idr_mutex); } +static struct drm_mode_object *_object_find(struct drm_device *dev, + uint32_t id, uint32_t type) +{ + struct drm_mode_object *obj = NULL; + + mutex_lock(&dev->mode_config.idr_mutex); + obj = idr_find(&dev->mode_config.crtc_idr, id); + if (!obj || (type != DRM_MODE_OBJECT_ANY && obj->type != type) || + (obj->id != id)) + obj = NULL; + mutex_unlock(&dev->mode_config.idr_mutex); + + return obj; +} + /** * drm_mode_object_find - look up a drm object with static lifetime * @dev: drm device @@ -396,7 +411,9 @@ void drm_mode_object_put(struct drm_device *dev, * @type: type of the mode object * * Note that framebuffers cannot be looked up with this functions - since those - * are reference counted, they need special treatment. + * are reference counted, they need special treatment. Even with + * DRM_MODE_OBJECT_ANY (although that will simply return NULL + * rather than WARN_ON()). */ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type) @@ -406,13 +423,10 @@ struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, /* Framebuffers are reference counted and need their own lookup * function.*/ WARN_ON(type == DRM_MODE_OBJECT_FB); - - mutex_lock(&dev->mode_config.idr_mutex); - obj = idr_find(&dev->mode_config.crtc_idr, id); - if (!obj || (obj->type != type) || (obj->id != id)) + obj = _object_find(dev, id, type); + /* don't leak out unref'd fb's */ + if (obj && (obj->type == DRM_MODE_OBJECT_FB)) obj = NULL; - mutex_unlock(&dev->mode_config.idr_mutex); - return obj; } EXPORT_SYMBOL(drm_mode_object_find); @@ -3093,6 +3107,8 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, if (!property) return NULL; + property->dev = dev; + if (num_values) { property->values = kzalloc(sizeof(uint64_t)*num_values, GFP_KERNEL); if (!property->values) @@ -3253,6 +3269,23 @@ struct drm_property *drm_property_create_range(struct drm_device *dev, int flags } EXPORT_SYMBOL(drm_property_create_range); +struct drm_property *drm_property_create_object(struct drm_device *dev, + int flags, const char *name, uint32_t type) +{ + struct drm_property *property; + + flags |= DRM_MODE_PROP_OBJECT; + + property = drm_property_create(dev, flags, name, 1); + if (!property) + return NULL; + + property->values[0] = type; + + return property; +} +EXPORT_SYMBOL(drm_property_create_object); + /** * drm_property_add_enum - add a possible value to an enumeration property * @property: enumeration property to change @@ -3680,6 +3713,20 @@ static bool drm_property_change_is_valid(struct drm_property *property, } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) { /* Only the driver knows */ return true; + } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { + struct drm_mode_object *obj; + /* a zero value for an object property translates to null: */ + if (value == 0) + return true; + /* + * NOTE: use _object_find() directly to bypass restriction on + * looking up refcnt'd objects (ie. fb's). For a refcnt'd + * object this could race against object finalization, so it + * simply tells us that the object *was* valid. Which is good + * enough. + */ + obj = _object_find(property->dev, value, property->values[0]); + return obj != NULL; } else { int i; for (i = 0; i < property->num_values; i++) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 0ff9558..c63df87 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -50,6 +50,7 @@ struct drm_clip_rect; #define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb #define DRM_MODE_OBJECT_PLANE 0xeeeeeeee #define DRM_MODE_OBJECT_BRIDGE 0xbdbdbdbd +#define DRM_MODE_OBJECT_ANY 0 struct drm_mode_object { uint32_t id; @@ -190,6 +191,7 @@ struct drm_property { char name[DRM_PROP_NAME_LEN]; uint32_t num_values; uint64_t *values; + struct drm_device *dev; struct list_head enum_blob_list; }; @@ -981,6 +983,8 @@ struct drm_property *drm_property_create_bitmask(struct drm_device *dev, struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max); +struct drm_property *drm_property_create_object(struct drm_device *dev, + int flags, const char *name, uint32_t type); extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); extern int drm_property_add_enum(struct drm_property *property, int index, uint64_t value, const char *name); @@ -997,6 +1001,7 @@ extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size); extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); + /* IOCTLs */ extern int drm_mode_getresources(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index a7f546e..5b530c7 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -263,6 +263,7 @@ struct drm_mode_get_connector { */ #define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0 #define DRM_MODE_PROP_TYPE(n) ((n) << 6) +#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1) struct drm_mode_property_enum { __u64 value; -- 1.9.3 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel