2012/5/16 Rob Clark <rob.clark@xxxxxxxxxx>: > From: Rob Clark <rob@xxxxxx> > > A bitmask property is similar to an enum. The enum value is a bit > position (0-63), and valid property values consist of a mask of > zero or more of (1 << enum_val[n]). > > Signed-off-by: Rob Clark <rob@xxxxxx> <Bikeshedding> "int num_values" appears after column 80 in 2 places </Bikeshedding> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx> > --- > drivers/gpu/drm/drm_crtc.c | 46 +++++++++++++++++++++++++++++++++++++++++--- > include/drm/drm_crtc.h | 3 +++ > include/drm/drm_mode.h | 1 + > 3 files changed, 47 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 75661c8..022873e 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -2707,6 +2707,33 @@ struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, > } > EXPORT_SYMBOL(drm_property_create_enum); > > +struct drm_property *drm_property_create_bitmask(struct drm_device *dev, > + int flags, const char *name, > + const struct drm_prop_enum_list *props, int num_values) > +{ > + struct drm_property *property; > + int i, ret; > + > + flags |= DRM_MODE_PROP_BITMASK; > + > + property = drm_property_create(dev, flags, name, num_values); > + if (!property) > + return NULL; > + > + for (i = 0; i < num_values; i++) { > + ret = drm_property_add_enum(property, i, > + props[i].type, > + props[i].name); > + if (ret) { > + drm_property_destroy(dev, property); > + return NULL; > + } > + } > + > + return property; > +} > +EXPORT_SYMBOL(drm_property_create_bitmask); > + > struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, > const char *name, > uint64_t min, uint64_t max) > @@ -2731,7 +2758,14 @@ int drm_property_add_enum(struct drm_property *property, int index, > { > struct drm_property_enum *prop_enum; > > - if (!(property->flags & DRM_MODE_PROP_ENUM)) > + if (!(property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) > + return -EINVAL; > + > + /* > + * Bitmask enum properties have the additional constraint of values > + * from 0 to 63 > + */ > + if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) > return -EINVAL; > > if (!list_empty(&property->enum_blob_list)) { > @@ -2875,7 +2909,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, > } > property = obj_to_property(obj); > > - if (property->flags & DRM_MODE_PROP_ENUM) { > + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { > list_for_each_entry(prop_enum, &property->enum_blob_list, head) > enum_count++; > } else if (property->flags & DRM_MODE_PROP_BLOB) { > @@ -2900,7 +2934,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, > } > out_resp->count_values = value_count; > > - if (property->flags & DRM_MODE_PROP_ENUM) { > + if (property->flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { > if ((out_resp->count_enum_blobs >= enum_count) && enum_count) { > copied = 0; > enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr; > @@ -3055,6 +3089,12 @@ static bool drm_property_change_is_valid(struct drm_property *property, > if (value < property->values[0] || value > property->values[1]) > return false; > return true; > + } else if (property->flags & DRM_MODE_PROP_BITMASK) { > + int i; > + __u64 valid_mask = 0; > + for (i = 0; i < property->num_values; i++) > + valid_mask |= (1LL << property->values[i]); > + return !(value & ~valid_mask); > } 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 e194c78..39e3e1c 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -940,6 +940,9 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int > const char *name, > const struct drm_prop_enum_list *props, > int num_values); > +struct drm_property *drm_property_create_bitmask(struct drm_device *dev, > + int flags, const char *name, > + const struct drm_prop_enum_list *props, int num_values); > struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, > const char *name, > uint64_t min, uint64_t max); > diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h > index 326f2be..5581980 100644 > --- a/include/drm/drm_mode.h > +++ b/include/drm/drm_mode.h > @@ -230,6 +230,7 @@ struct drm_mode_get_connector { > #define DRM_MODE_PROP_IMMUTABLE (1<<2) > #define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ > #define DRM_MODE_PROP_BLOB (1<<4) > +#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */ > > struct drm_mode_property_enum { > __u64 value; > -- > 1.7.9.5 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel -- Paulo Zanoni _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel