On Fri, May 30, 2014 at 01:12:05PM -0400, Rob Clark wrote: > 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> Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx> > --- > 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 > -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel